Bea.AI coding blog
  • Tree
    • Tree Traverse
    • Iteration based traverse
    • Typical problems and solutions
      • Max width of binary tree
      • Binary Tree & BST Serialize & Deserialize
      • Lowest common ancestor (LCA) for Binary Tree and BST
      • Subproblem-based Approach for Resolving Max Value on Trees
      • Path sum III
  • Graph
  • Data structure
    • Java data structure
  • Algorithm general templates
    • Tree
    • Trie
    • Graph
  • Java Algorithm Tips and Tricks
    • Java concurrent list
  • Coding patterns & Strategies
  • Coding patterns & template
    • 1. Binary Search
    • 2. Two Pointer
    • 3. Sliding Window
    • 4. Backtracking
    • 5. DFS
    • 6. BFS
    • 7. Stack
    • 8. Heap
    • 9. Prefix Sum
    • 10. Linked List
    • 11. BST
    • 12. Line sweep
    • 14. Tree
    • 15. Graph
    • 16. Bit manipulation
    • 17. Matrix
    • 18. Monotonic Stack
    • 19. Sorting
    • 20. Union Find
    • 21. Trie
    • 22. Dynamic programming
    • 23. Customized Data Structure
  • Code interview steps
  • Leetcode
    • Tree
      • Traversal
      • Construction and Conversion
      • Search and Validation
      • Manipulation and Modification
      • Special Trees
      • Miscellaneous
    • Dynamic programing
      • Classic DP Problems
      • Sequence/Array DP
      • Matrix DP
      • Knapsack Problems
      • String DP
      • Tree/Graph DP
      • Optimization Problems
      • Combinatorial DP
    • DFS
      • Graph Traversal
      • Path Finding
      • Tree Traversal
      • Backtracking
      • Topological Sorting
      • Traversal Order
      • Dynamic Programming with DFS
      • Connected Components
    • BFS
      • Graph
      • Tree
      • Matrix
      • String
      • Others
    • Two points
      • Array
      • String
      • Linked List
      • Sorting
      • Others
    • LinkedList
      • Basic Operations
      • Cycle Detection and Handling
      • Intersection and Union
      • Partitioning and Merging
      • Palindrome
      • Miscellaneous
    • Backtracking
    • Binary Search
    • Union Find
    • Trie
    • Sort
    • Heap
    • Randomness
    • Topological sort
    • Stack
    • HashTable
    • Sliding Window
  • Blind 75
    • Array
    • Binary
    • Dynamic Programming
    • Graph
    • Interval
    • LinkedList
    • Matrix
    • String
    • Tree
    • Heap
  • Companies
    • Apple
Powered by GitBook
On this page
  • Template
  • Typical problems
  1. Coding patterns & template

1. Binary Search

Template

  • Basic template

// This template is to find the target from a sorted array, not consider duplicates
int binarySearch(int[] nums, int target) {
    int left = 0, right = nums.length - 1;
    while (left <= right) {
        int mid = left + (right - left)/2;
        if (nums[mid] == target) {
            return mid;
        } else if (nums[mid] > target) {
            right = mid - 1;
        } else if (nums[mid] < target) {
            left = mid + 1;
        }
    }
    return -1;
}
// The termination condition is nums[mid] == target or left > right
  • Left bound

// This template is to find the left bound
// It's used to find the target from a sorted array with the smallest index
int findLeftBound(int[] nums, int target) {
    int left = 0, right = nums.length - 1;
    while (left <= right) {
        int mid = left + (right - left) / 2;
        if (nums[mid] == target) {
            right = mid - 1; // Push the right pointer even when find the target
        } else if (nums[mid] > target) {
            right = mid - 1;
        } else if (nums[mid] < target) {
            left = mid + 1;
        }
    }
    if (left >= nums.length || nums[left] != target) {
        return -1;
    }
    return left;
}

// As left < right case, the termination case is left == right
int findLeftBound(int[] nums, int target) {
    if (nums.length == 0) return -1;
    int left = 0;
    int right = nums.length; // 注意
    
    while (left < right) { // 注意
        int mid = (left + right) / 2;
        if (nums[mid] == target) {
            right = mid;
        } else if (nums[mid] < target) {
            left = mid + 1;
        } else if (nums[mid] > target) {
            right = mid; // 注意
        }
    }
    return left;
}
  • Right bound

// This template is to find the right bound
// It's used to find the target from a sorted array with the largest index
int findRightBound(int[] nums, int target) {
    int left = 0, right = nums.length - 1;
    while (left <= right) {
        int mid = left + (right - left) / 2;
        if (nums[mid] == target) {
            left = mid + 1; // Push the left pointer even after finding the target
        } else if (nums[mid] < target) {
            left = mid + 1;
        } else if (nums[mid] > target) {
            right = mid - 1;
        }
    }
    if (right <= 0 || nums[right] != target) {
        return -1;
    }
    return right;
}

int findRightBound(int[] nums, int target) {
    if (nums.length == 0) return -1;
    int left = 0, right = nums.length;
    
    while (left < right) {
        int mid = (left + right) / 2;
        if (nums[mid] == target) {
            left = mid + 1; // 注意
        } else if (nums[mid] < target) {
            left = mid + 1;
        } else if (nums[mid] > target) {
            right = mid;
        }
    }
    return left - 1; // 注意
}

// As the termination condition is left == right, it can be right - 1

总结:如果只是找到target,用left <= right, 但找左边界(最近的少于target的值),或者右边界,用left < right 更加灵活

Typical problems

  • Find peak element from the array, left < right is useful for comparing index and index + 1, which is used for find local max/min

public int findPeakElement(int[] nums) {
        int left = 0;
        int right = nums.length - 1;

        while (left < right) {
            int mid = left + (right - left) / 2;

            // If the mid element is greater than its neighbors, it's a potential peak
            if (nums[mid] > nums[mid + 1])
                right = mid;
            else
                left = mid + 1;
        }

        // At the end of the loop, 'left' and 'right' will be equal and point to a peak element
        return left;
    }
  • Search in a rotated sorted array, notice either the left half is ordered or right half is ordered, and the target either in this side or in the other side


public int searchInRotatedSortedArray(int[] nums, int target) {
        int left = 0, right = nums.length - 1;
        while (left <= right) {
            int mid  = left + (right - left) / 2;
            if (nums[mid] == target) {
                return mid;
            }
             // 左半段是有序的
            if (nums[left] <= nums[mid]) {
                // target 在这段里
                if (nums[left] <= target && target < nums[mid]) {
                    right = mid - 1;
                } else {
                    left = mid + 1;
                }
                //后半段有序
            } else {
                if (nums[mid] < target && target <= nums[right]) {
                    left = mid + 1;
                } else {
                    right = mid - 1;
                }
            }
        }
        return -1;
    }
  • Eat balance - capacity find problems

public int minEatingSpeed(int[] piles, int h) {
        int maxEatingSpeed = 0;
        for (int i = 0; i < piles.length; i++) {
          maxEatingSpeed = Math.max(maxEatingSpeed, piles[i]);
        }

        int left = 1, right = maxEatingSpeed;

        while (left < right) {
          int mid = left + (right - left) / 2;
          if (eatingHoursWithSpeed(piles, mid) > h) {
            left = mid + 1;
          } else {
            right = mid;
          }
        }
        return left;
    }

    private int eatingHoursWithSpeed(int[] piles, int itemsPerHour) {
      int hours = 0;
      for (int i = 0; i < piles.length; i++) {
        hours += piles[i] / itemsPerHour;
        if (piles[i] % itemsPerHour > 0) {
            hours++;
        }
      }
      return hours;
    }
PreviousCoding patterns & templateNext2. Two Pointer

Last updated 1 year ago