Binary Search是对于sorted或者部分sorted,能找到大小关系可以使搜索朝着“正确”方向前进的,省掉了不正确方向的搜索。所以是每次搜索都是logn的复杂度。如果需要遍历n个元素,则是O(nlogn)的复杂度。
4. Median of Two Sorted Arrays
33. Search in Rotated Sorted Array
34. Search for a Range
4. Median of Two Sorted Arrays
There are two sorted arrays nums1 and nums2 of size m and n respectively.
Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).
Example 1:
nums1 = [1, 3]
nums2 = [2]
The median is 2.0
Example 2:
nums1 = [1, 2]
nums2 = [3, 4]
The median is (2 + 3)/2 = 2.5
1)规定nums1的长度一定要小于nums2. 因为比较条件是nums1[m] > nums[n - 1]. 防止数据越界
2)右边界用长度是为了偶数的时候取右边。同时,长度相加再加1是为了第k个值取右边部分。
3) 注意采用MIN、MAX VALUE处理边界情况。
class Solution { public double findMedianSortedArrays(int[] nums1, int[] nums2) { if (nums1.length > nums2.length) { return findMedianSortedArrays(nums2, nums1); } // 指的右边部分第一个 int k = (nums1.length + nums2.length + 1) / 2; boolean isEven = ((nums1.length + nums2.length) & 1) == 0 ? true : false; int s = 0; int e = nums1.length; int m = -1; int n = -1; while (s < e) { m = (s + (e - s) / 2) ; n = k - m; if (nums1[m] < nums2[n - 1]) { s = m + 1; } else { e = m; } } m = s; n = k - s; int c1 = Math.max(m <= 0 ? Integer.MIN_VALUE : nums1[m - 1], n <= 0 ? Integer.MIN_VALUE : nums2[n - 1]) ; int c2 = Math.min(m >= nums1.length ? Integer.MAX_VALUE : nums1[m], n >= nums2.length ? Integer.MAX_VALUE : nums2[n]); if (isEven) { return (c1 + c2) * 0.5; } return c1; } }
class Solution { private int bSearch(int[] nums, int s, int e, int target) { while (s < e) { int mid = s + (e - s) / 2; if (target == nums[mid]) { return mid; } if (target < nums[mid]) { e = mid; } else { s = mid + 1; } } if (nums[s] != target) { return -1; } return s; } public int search(int[] nums, int target) { if (nums == null || nums.length == 0) { return -1; } int s = 0; int e = nums.length - 1; while (s + 1 < e) { int mid = s + (e - s) / 2; if (nums[s] < nums[mid]) { if (target <= nums[mid] && target >= nums[s]) { return bSearch(nums, s, mid, target); } else { s = mid; continue; } } else { if (target <= nums[e] && target >= nums[mid]) { return bSearch(nums, mid, e, target); } else { e = mid; continue; } } } if (nums[s] == target) { return s; } if (nums[e] == target) { return e; } return -1; } }
81. Search in Rotated Sorted Array II
public class Solution { private boolean binaryS(int[] nums, int target, int s, int e) { while (s < e) { int mid = s + (e - s) / 2; if (target == nums[mid]) { return true; } if (target < nums[mid]) { e = mid; } else { s = mid + 1; } } if (nums[s] == target) { return true; } return false; } public boolean search(int[] nums, int target) { if (nums == null || nums.length == 0) { return false; } int low = 0; int high = nums.length - 1; int mid = 0; while (low + 1 < high) { mid = low + (high - low) / 2; //prevent overflow int midVal = nums[mid]; if (nums[low] == midVal) { ++low; continue; } if (midVal == nums[high]) { --high; continue; } if (nums[mid] == target) {//directly return if we are lucky return true; } if (nums[low] < nums[mid]) {// left part is sorted if (target >= nums[low] && target <= nums[mid]) { //only when it is sorted, this can be used as criteria return binaryS(nums, target, low, mid); } else { // low = mid; } } else { // right part is sorted if (target >= nums[mid] && target <= nums[high]) { return binaryS(nums, target, mid, high); } else { high = mid; } } } if (target == nums[low]) { return true; } if (target == nums[high]) { return true; } return false; } }
34. Search for a Range
class Solution { public int[] searchRange(int[] nums, int target) { int x = -1; int y = -1; if (nums == null || nums.length == 0) { return new int[]{x, y}; } int s = 0; int e = nums.length - 1; while (s < e) { int mid = s + (e - s) / 2; if (target > nums[mid]) { s = mid + 1; } else { e = mid; } } if (nums[s] != target) { return new int[]{x, y}; } x = s; s = 0; e = nums.length - 1; while (s < e) { int mid = (s + (e - s) / 2) + 1; if (target < nums[mid]) { e = mid - 1; } else { s = mid; } } y = s; return new int[]{x, y}; } }35. Search Insert Position
class Solution { public int searchInsert(int[] nums, int target) { if (nums == null || nums.length == 0) { return 0; } int i = 0; int j = nums.length - 1; while (i < j) { int mid = i + (j - i) / 2; if (nums[mid] == target) { return mid; } if (target < nums[mid]) { j = mid; } else { i = mid + 1; } } if (target <= nums[i]) {// 这里的等号是,只有一个数且这个数与target相等是不会进入循环的。 return i; } return i + 1; } }
50. Pow(x, n)
class Solution { private double pow(double x, int n) { if (n == 0) { return 1; } if (n == 1) { return x; } boolean ood = false; if ((n & 1) == 1) { ood = true; } n = (n >>> 1); if (ood) { return pow(x * x, n) * x; } return pow(x * x, n); } public double myPow(double x, int n) { if (n < 0) { x = 1/x; if (n == Integer.MIN_VALUE) { n = Integer.MAX_VALUE; x = x * x; } else { n = -n; } } return pow(x, n); } }
69. Sqrt(x)
class Solution { public int mySqrt(int x) { if (x == 0 || x == 1) { return x; } long start = 1; long end = x; long mid = 0; while (start + 1 < end) { mid = start + (end - start) / 2; if (mid * mid < x) { start = mid; } else if (mid * mid > x){ end = mid; } else { return (int)mid; } } if (end * end < x) { return (int)end; } return (int)start; } }
74. Search a 2D Matrix
public class Solution { public boolean searchMatrix(int[][] matrix, int target) { if (matrix == null || matrix.length == 0 || matrix[0] == null || matrix[0].length == 0) { return false; } int row = matrix.length;//3 int col = matrix[0].length;//4 if (target < matrix[0][0] || target > matrix[row - 1][col - 1]) { return false; } int s = 0; int e = col * row - 1; while (s < e) { int mid = s + (e - s) / 2; int val = matrix[mid / col][mid % col]; if (target > val) { s = mid + 1; } else if (target < val) { e = mid; } else { return true; } } if (matrix[s / col][s % col] == target) { return true; } return false; } }