Leetcode solution to a problem - the idea of binary search algorithm

1. prescribing requirements

Achieve normal

Input : [1,2,3,4,5]
key : 3
return the index : 2
public int binarySearch(int[] nums, int key) {
    int l = 0, h = nums.length - 1; while (l <= h) { int m = l + (h - l) / 2; if (nums[m] == key) { return m; } else if (nums[m] > key) { h = m - 1; } else { l = m + 1; } } return -1; }

time complexity

Also known as binary search binary search every time it looks interval halved, this binary characteristic algorithm time complexity is O (logN).

calculated m

There are two ways of calculating the value of m:

  • m = (l + h) / 2
  • m = l + (h - l) / 2

l + h add overflow may occur, i.e. the integer result of the addition is larger than the range that can be represented. But l and h are positive, so the h - l will not add overflow problem. Therefore, it is preferable to use the second method of calculation.

Unsuccessful search for Return Value

When the loop exits If you still have not found key, then expressed lookup fails. There are two return values:

  • -1: with an error code indicates that the key is not found
  • l: the key is inserted in the correct position nums

variant

Binary search can have many variants, variants achieve pay attention to determine the boundary values. For example, in an array of repeating elements to achieve find key leftmost position is as follows:

public int binarySearch(int[] nums, int key) {
    int l = 0, h = nums.length - 1; while (l < h) { int m = l + (h - l) / 2; if (nums[m] >= key) { h = m; } else { l = m + 1; } } return l; }

The implementation and proper realization of the following ways:

  • h is an assignment expression h = m
  • The cycling conditions were l <h
  • Finally returned instead l -1

In the case of nums [m]> = key, the key can be deduced located leftmost [l, m] interval, which is a closed interval. h is an assignment expression h = m, m positions as may be solutions.

In the assignment expression h is h = m the case, if the loop condition is l <= h, then the situation will not withdraw from circulation appears, therefore circulation only under conditions l <h. The following case demonstrates cycling conditions l <cycle can not quit when = h:

nums = {0, 1, 2}, key = 1
l   m   h
0   1   2  nums[m] >= key
0   0   1  nums[m] < key
1   1   1  nums[m] >= key
1   1   1  nums[m] >= key
...

When the loop exits, does not mean not find the key, so the final result should not return -1. In order to verify that there is not found, you need to determine what the value of a call to end the return position and key equality.

1. prescribing requirements

69. Sqrt(x) (Easy)

Input: 4
Output: 2

Input: 8
Output: 2
Explanation: The square root of 8 is 2.82842..., and since we want to return an integer, the decimal part will be truncated.

Sqrt prescribing a certain number x between 0 ~ x, and satisfies sqrt == x / sqrt. Binary search can be used to find sqrt between 0 ~ x.

For x = 8, its evolution is 2.82842 ..., it should return the last 2 instead of 3. When the cycling conditions were l <= h and the loop exits, h l is always smaller than 1, that is h = 2, l = 3, so the return value of the last should not h l.

public int mySqrt(int x) {
    if (x <= 1) { return x; } int l = 1, h = x; while (l <= h) { int mid = l + (h - l) / 2; int sqrt = x / mid; if (sqrt == mid) { return mid; } else if (mid > sqrt) { h = mid - 1; } else { l = mid + 1; } } return h; }

2. given element is greater than the smallest element

744. Find Smallest Letter Greater Than Target (Easy)

Input:
letters = ["c", "f", "j"]
target = "d"
Output: "f"

Input:
letters = ["c", "f", "j"]
target = "k"
Output: "c"

Topic Description: Given an ordered array of characters and a character target letters, asked to identify letters minimum character greater than target, and if you can not find the return of a character.

public char nextGreatestLetter(char[] letters, char target) {
    int n = letters.length; int l = 0, h = n - 1; while (l <= h) { int m = l + (h - l) / 2; if (letters[m] <= target) { l = m + 1; } else { h = m - 1; } } return l < n ? letters[l] : letters[0]; }

3. ordered array of Single Element

540. Single Element in a Sorted Array (Medium)

Input: [1, 1, 2, 3, 3, 4, 4, 8, 8]
Output: 2

Subject description: an ordered array has only one number does not appear twice, to find this number.

In claim (logN) time complexity O solved, and therefore can not traverse the array to solve the XOR operation, do the time complexity is O (N).

Single Element position to make the index in the array. After the index, the pair state originally present in the array is changed. If m is an even number, and m + 1 <index, then nums [m] == nums [m + 1]; m + 1> = index, then nums [m] = nums [m + 1]!.

From the law above may know if nums [m] == nums [m + 1], then the location of the array index is [m + 2, h], so this case l = m + 2; if nums [m]! = nums [m + 1], then the location of the array where the index is [l, m], this time so that h = m.

Since assignment expression h is h = m, then you can only use the loop condition l <h This form.

public int singleNonDuplicate ( int [] the nums) {
     int L = 0, H = the nums .length - . 1; the while (L <H) { int m = L + (H - L) / 2; IF (m % 2 == . 1) {m -; // ensure l / h / m are even bit, so that the interval size is always odd look} IF (the nums [m] == the nums [m + . 1]) {L = m + 2 ;} the else {H = m;}} return the nums [L];}

4. The first wrong version

278. First Bad Version (Easy)

Description Title: Given n represents an element with a [1, 2, ..., n] version, began to appear at the wrong version of x position, resulting in errors are later versions. Can call isBadVersion (int x) to know whether a version of the error, the first error to find the required version.

If the version of the m-th error indicates the first version of the error between the [L, m], so that h = m; otherwise a wrong version of the [m + 1, h] between, so that l = m + 1.

Since assignment expression h is h = m, so the loop condition is l <h.

public int firstBadVersion(int n) {
    int l = 1, h = n; while (l < h) { int mid = l + (h - l) / 2; if (isBadVersion(mid)) { h = mid; } else { l = mid + 1; } } return l; }

The minimum number of rotation of the array

153. Find Minimum in Rotated Sorted Array (Medium)

Input: [3,4,5,1,2],
Output: 1
public int findMin(int[] nums) {
    int l = 0, h = nums.length - 1; while (l < h) { int m = l + (h - l) / 2; if (nums[m] <= nums[h]) { h = m; } else { l = m + 1; } } return nums[l]; }

6. Find the interval

34. Find First and Last Position of Element in Sorted Array

Input: nums = [5,7,7,8,8,10], target = 8
Output: [3,4]

Input: nums = [5,7,7,8,8,10], target = 6
Output: [-1,-1]
public int[] searchRange(int[] nums, int target) {
    int first = binarySearch(nums, target); int last = binarySearch(nums, target + 1) - 1; if (first == nums.length || nums[first] != target) { return new int[]{-1, -1}; } else { return new int[]{first, Math.max(first, last)}; } } private int binarySearch(int[] nums, int target) { int l = 0, h = nums.length; // 注意 h 的初始值 while (l < h) { int m = l + (h - l) / 2; if (nums[m] >= target) { h = m; } else { l = m + 1; } } return l; }

Guess you like

Origin www.cnblogs.com/daimasanjiaomao/p/11009078.html