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;
}
}