Find K Closest Elements
Given target
, a non-negative integer k
and an integer array A
sorted in ascending order, find the k
closest numbers to target
in A
, sorted in ascending order by the difference between the number and target. Otherwise, sorted in ascending order by number if the difference is same.
Example
Example 1:
Input: A = [1, 2, 3], target = 2, k = 3
Output: [2, 1, 3]
Example 2:
Input: A = [1, 4, 6, 8], target = 3, k = 3
Output: [4, 1, 6]
Challenge
O(logn + k) time
思路:先找到起始start point,然後用打擂臺的方法O(K)的去取得最近的值;
class Solution {
public List<Integer> findClosestElements(int[] arr, int k, int x) {
List<Integer> list = new ArrayList<Integer>();
if(arr == null || arr.length == 0) {
return list;
}
int index = findCloset(arr, x);
list.add(arr[index]);
int i = index-1; int j = index+1;
int count = 1;
while(count < k) {
if(0 <= i && j < arr.length) {
if(x - arr[i] <= arr[j] - x) {
list.add(0,arr[i--]);
} else {
list.add(arr[j++]);
}
} else if(i < 0 && j < arr.length) {
list.add(arr[j++]);
} else if(i >= 0 && j >= arr.length) {
list.add(0,arr[i--]);
}
count++;
}
return list;
}
private int findCloset(int[] A, int target) {
int start = 0; int end = A.length - 1;
while(start + 1 < end) {
int mid = start + (end - start) / 2;
if(A[mid] == target) {
return mid;
} else if(A[mid] < target) {
start = mid;
} else {
end = mid;
}
}
if(target - A[start] < A[end] - target) {
return start;
}
return end;
}
}
Median of Two Sorted Array
思路:每次跟A和B中的 第 k/2值進行比較;然後扔掉最小的那一部分,因爲是保證沒有用的,這樣總體思路是縮小搜索範圍;
class Solution {
public double findMedianSortedArrays(int[] nums1, int[] nums2) {
if(nums1 == null && nums2 == null) {
return 0.0;
}
int n = nums1.length;
int m = nums2.length;
if((n + m) % 2 == 0) {
return (findKth(nums1, 0, nums2, 0, (n+m) / 2)
+ findKth(nums1, 0, nums2, 0, (n+m) / 2 + 1) )* 0.5;
} else{
return findKth(nums1, 0, nums2, 0, (n+m) / 2 + 1);
}
}
private double findKth(int[] A, int astart,
int[] B, int bstart, int k) {
if(astart >= A.length) {
return B[bstart + k - 1];
}
if(bstart >= B.length) {
return A[astart + k - 1];
}
if(k == 1) {
return Math.min(A[astart], B[bstart]);
}
int halfA = astart + k/2 - 1 >= A.length ? Integer.MAX_VALUE : A[astart + k/2 - 1];
int halfB = bstart + k/2 - 1 >= B.length ? Integer.MAX_VALUE : B[bstart + k/2 - 1];
if(halfA < halfB) {
return findKth(A, astart + k/2, B, bstart, k - k / 2);
} else {
return findKth(A, astart, B, bstart + k / 2, k - k/2);
}
}
}