Template
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| private int binarySearch(int[] nums, int target) { if (nums == null || nums.length == 0) { return -1; } int start = 0, end = nums.length - 1; while (start + 1 < end) { int mid = start + (end - start) / 2; if (nums[mid] < target) { start = mid; } else if (nums[mid] == target) { end = mid; } else { end = mid; } } if (nums[start] == target) { return start; } if (nums[end] == target) { return end; } return -1; }
|
Type
- Random position of the target
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| public class Solution { public int findPosition(int[] nums, int target) { if (nums == null || nums.length == 0) { return -1; } int start = 0, end = nums.length - 1; while (start + 1 < end) { int mid = start + (end - start) / 2; if (nums[mid] == target) { return mid; } else if (nums[mid] < target) { start = mid; } else { end = mid; } } if (nums[start] == target) { return start; } if (nums[end] == target) { return end; } return -1; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| class Solution { public int binarySearch(int[] nums, int target) { if (nums == null || nums.length == 0) { return -1; } int start = 0, end = nums.length - 1; while (start + 1 < end) { int mid = start + (end - start) / 2; if (nums[mid] == target) { end = mid; } else if (nums[mid] < target) { start = mid; } else { end = mid; } } if (nums[start] == target) { return start; } if (nums[end] == target) { return end; } return -1; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| public class Solution { public int lastPosition(int[] nums, int target) { if (nums == null || nums.length == 0) { return -1; } int start = 0; int end = nums.length - 1; while (start + 1 < end) { int mid = start + (end - start) / 2; if (nums[mid] == target) { start = mid; } else if (nums[mid] < target) { start = mid; } else { end = mid; } } if (nums[end] == target) { return end; } else if (nums[start] == target) { return start; } else { return -1; } } }
|
Example
- Search In a Big Sorted Array (Can not find the upper bound)
Exponential Backoff
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| Public int searchBigSortedArray(ArrayReader reader, int target) { int kth = 1; while (reader.get(kth - 1) < target) { kth = kth * 2; } int start = 0, end = kth - 1; while (start + 1 < end) { int mid = start + (end - start) / 2; if (reader.get(mid) < targrt) { start = mid; } else { end = mid; } if (reader.get(start) == target) { return start; } if (reader.get(end) == target) { return end; } return -1; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| public int[] kClosestNumbers(int[] A, int[] target, int k) { int right = findUpperCloest(A, target); int left = right - 1; int[] results = new int[k]; for (int i = 0; i < k; i++) { if (isLeftCloser(A, target, left, right)) { results[i] = A[left]; left--; } else { results[i] = A[right]; right++; } } return results; } private int findUpperCloest(int[] A, int target) { int start = 0, end = A.length - 1; while (start + 1 < end) { int mid = start + (end - start) / 2; if (A[mid] >= target) { end = mid; } else { start = mid; } } if (A[start] >= target) { return start; } if (A[end] >= target) { return end; } return A.length; } private boolean isLeftCloser(int[] A, int target, int left, int right) { if (left < 0) { return false; } if (right >= A.length) { return true; } return (target - A[left] <= (A[right] - target)); }
|
- Maximum Number in Mountain Sequence
12345654321
if have repeated number cannot use this method
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| public class Solution { public int mountainSequence(int[] nums) { if (nums == null || nums.length == 0) { return -1; } int start = 0, end = nums.length - 1; while (start + 1 < end) { int mid = start + (end - start) / 2; if (nums[mid] > nums[mid + 1]) { end = mid; } else { start = mid; } } return Math.max(nums[start], nums[end]); } }
|
- Find Minimum in Rotated Sorted Array
0 1 2 4 5 6 7 -> 4 5 6 7 0 1 2
-> 右边第一个位置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public class Solution { public int findMin(int[] nums) { if (nums == null || nums.length == 0) { return -1; } int start = 0, end = nums.length - 1; while (start + 1 < end) { int mid = start + (end - start) / 2; if (nums[mid] > nums[end]) { start = mid; } else { end = mid; } } return Math.min(nums[start], nums[end]); } }
|
follow up: [111111110111], repeated number O(n), can not be logn
- Search in Rotated Sorted Array
Solution 1 : find minimum first(two binary search)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
| public int search(int[] A, int target) { if (A == null || A.length == 0) { return -1; } int index = findMinIndex(A); if (A[index] <= target && target <= A[A.length - 1]) { return binarySearch(A, index, A.length - 1, target); } return binarySearch(A, 0, index - 1, target); } private int findMinIndex(int[] A) { int start = 0, end = A.length - 1; while (start + 1 < end) { int mid = start + (end - start) / 2; if (A[mid] < A[end]) { end = mid; } else { start = mid; } } if (A[start] < A[end]) { return start; } return end; } private int binarySearch(int[] A, int start, int end, int target) { if (end < 0) { end += A.length; } while (start + 1 < end) { int mid = start + (end - start) / 2; if (A[mid] < target) { start = mid; } else { end - mid; } if (A[start] == target) { return start; } if (A[end] == target) { return end; } return -1; } }
|
Solution 2, directly cut
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| public int search(int[] A, int target) { if (A == null || A.length == 0) { return -1; } int start = 0, end = A.lenghth - 1; while (start + 1 < end) { int mid = start + (end - start) / 2; if (A[mid] >= A[start]) { if (A[start] <= target && target <= A[mid]) { end = mid; } else { start = mid; } } else { if (A[mid] <= target && target <= A[end]) { start = mid; } else { end = mid; } } } if (A[start] == target) { return start; } if (A[end] == target) { return end; } return -1; }
|
Find peak element(any peak)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public int findPeak(int[] A) { int start = 1, end = A.length - 2; while (start + 1 < end) { int mid = start + (end - start) / 2; if (A[mid] < A[mid - 1]) { end = mid; } else if (A[mid] < A[mid + 1]) { start = mid; } else { return mid; } } if (A[start] < A[end]) { return end; } else { return start; } }
|
有一些原木,现在想把这些木头切割成一些长度相同的小段木头,需要得到的小段的数目至少为 k
。给定L和k,你需要计算能够得到的小段木头的最大长度。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
| public int woodCut(int[] L, int k) { if (L == null || L.length == 0) { return 0; } long maxValue = 0, sumValue = 0; for (int i = 0; i < L.length; i++) { sumValue += L[i]; maxValue = Math.max(maxValue, L[i]); } int start = 1, end = (int)Math.min(maxValue, sumValue / k); if (start > end) { return 0; } while (start + 1 < end) { int mid = start + (end - start) / 2; if (getPieces(L, mid) >= k) { start = mid; } else { end = mid; } } if (getPieces(L, end) >= k) { return end; } if (getPieces(L, start) >= k) { return start; } return 0; }
private long getPieces(int[] L, int length) { long result = 0; for (int i = 0; i < L.length; i++) { result += L[i] / length; } return result; }
|