Binary Search 總結

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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章