First, we use k/2 as our step length to pick two numbers from arrayA and arrayB starting from index 0. Then we keep the larger number, and move the left boundary of the array which has the smaller number. In this case, we could remove k/2 numbers, and we just need to find (k - k / 2)th smallest in the remaining numbers. Then, we use k/4 as our step, and do the same step as above, and then k/8, k/16... Until k == 1, then just return the smaller of the current two numbers.
publicdoublefindMedianSortedArrays(int[] nums1,int[] nums2){intaLength=nums1.length;intbLength=nums2.length;intlength= aLength + bLength;if(length %2==0){inta=findKthSmallest(nums1,0, nums2,0, length /2);intb=findKthSmallest(nums1,0, nums2,0, length /2+1);return(a + b)/2.0;}else{return1.0*findKthSmallest(nums1,0, nums2,0, length /2+1);}}privateintfindKthSmallest(int[] a,int aLeft,int[] b,int bLeft,int k){if(aLeft >=a.length){return b[bLeft + k -1];}elseif(bLeft >=b.length){return a[aLeft + k -1];}elseif(k ==1){returnMath.min(a[aLeft], b[bLeft]);}intaKthLeft= aLeft + k /2-1<a.length? a[aLeft + k /2-1]:Integer.MAX_VALUE;intbKthLeft= bLeft + k /2-1<b.length? b[bLeft + k /2-1]:Integer.MAX_VALUE;if(aKthLeft < bKthLeft){returnfindKthSmallest(a, aLeft + k /2, b, bLeft, k - k /2);}else{returnfindKthSmallest(a, aLeft, b, bLeft + k /2, k - k /2);}}
public int search(int[] nums, int target) {
if (nums == null || nums.length == 0) return -1;
int left = 0, right = nums.length - 1;
while(left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid] == target) {
return mid;
}
if (nums[mid] > target) {
if (nums[left] <= target || nums[mid] < nums[right]) {
right = mid - 1;
} else {
left = mid + 1;
}
} else {
if (target <= nums[right] || nums[left] < nums[mid]) {
left = mid + 1;
} else {
right = mid - 1;
}
}
}
return -1;
}
public int findPeakElement(int[] nums) {
int left = 0, right = nums.length - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if ((mid == 0 || nums[mid] > nums[mid - 1]) && (mid == nums.length - 1 || nums[mid] > nums[mid + 1])) {
return mid;
}
if (mid == 0 || nums[mid] > nums[mid - 1]) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return -1;
}
public int kthSmallest(int[][] matrix, int k) {
int n = matrix.length, m = matrix[0].length;
int lo = matrix[0][0], hi = matrix[n - 1][m - 1];
while (lo < hi) {
int mid = lo + (hi - lo) / 2;
int j = m - 1;
int count = 0;
for (int i = 0; i < n; i++) {
while (j >= 0 && matrix[i][j] > mid) {
j -= 1;
}
count += (j + 1);
}
if (count < k) {
lo = mid + 1;
} else {
hi = mid;
}
}
return hi;
}
class Solution {
/*
Method 1: Random & Binary Search.
Time Complexity: O(log n)
Get the total number, get a random number from [1, sum], find where it's located
*/
int[] array;
Random rd = new Random();
public Solution(int[] w) {
array = new int[w.length];
for (int i = 0; i < w.length; i++) {
array[i] = (i == 0 ? w[i] : w[i] + array[i - 1]);
}
}
public int pickIndex() {
int num = rd.nextInt(array[array.length - 1]) + 1;
int left = 0, right = array.length - 1;
while (left < right) {
int mid = left + (right - left) / 2;
if (array[mid] < num) {
left = mid + 1;
} else {
right = mid;
}
}
return left;
}
}