顯示具有 Binary Search 標籤的文章。 顯示所有文章
顯示具有 Binary Search 標籤的文章。 顯示所有文章

2019年11月13日 星期三

Last Position of Target


Last Position of Target

  • Lintcode : 458 / Leetcode : 34
  • Level : Easy

Problem

Find the last position of a target number in a sorted array. Return -1 if target does not exist.

Example
Example 1:

Input: nums = [1,2,2,4,5,5], target = 2
Output: 2
Example 2:

Input: nums = [1,2,2,4,5,5], target = 6
Output: -1

Concept & Algorithm

Time Complexity & Space Complexity

time : O(logn)
space: O(1)

Answer

class Solution {
public:
    int lastPosition(vector<int> &nums, int target) {
        if (nums.size() == 0) return -1;
        int l = 0, r = nums.size() - 1;
        while (l + 1 < r) {
            int mid = l + (r - l) / 2;
            if (nums[mid] <= target) {
                l = mid;
            }else {
                r = mid;
            }
        }
        if (nums[r] == target) return r;
        if (nums[l] == target) return l;
        return -1;
    }
};
tags: Binary Search
​

Maximum Number in Mountain Sequence


Maximum Number in Mountain Sequence

  • Lintcode : 585 / Leetcode :
  • Level : Medium

Problem

Given a mountain sequence of n integers which increase firstly and then decrease, find the mountain top.

Example
Example 1:

Input: nums = [1, 2, 4, 8, 6, 3] 
Output: 8
Example 2:

Input: nums = [10, 9, 8, 7], 
Output: 10
Notice
Arrays are strictly incremented, strictly decreasing

Concept & Algorithm

Time Complexity & Space Complexity

time : O(logn)
space: O(1)

Answer

class Solution {
public:
    int mountainSequence(vector<int> &nums) {
        // corner case : if nums.size() == 0
        int l = 0, r = nums.size() - 1;
        while (l + 1 < r) {
            int mid = l + (r - l) / 2;
            if (nums[mid] > nums[mid + 1]) {
                r = mid;
            }else {
                l = mid;
            }
        }
        if (nums[l] > nums[r]) return nums[l];
        return nums[r];
    }
};
tags: Binary Search
​

Find K Closest Elements


Find K Closest Elements

  • Lintcode : 460 / Leetcode : 658
  • Level : Medium

Problem

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

Notice
The value k is a non-negative integer and will always be smaller than the length of the sorted array.
Length of the given array is positive and will not exceed 10^410
​4
​​ 
Absolute value of elements in the array will not exceed 10^410
​4
​​

Concept & Algorithm

Time Complexity & Space Complexity

time : O(logn + k)
space: O(k)

Answer

class Solution {
public:
    vector<int> kClosestNumbers(vector<int> &A, int target, int k) {
        // corner case
        if (A.size() < k) return A;

        int index = findLastLessAndEqual(A, target);
        vector<int> ans;
        countK(A, target, k, ans, index);
        return ans;
    }
    int findLastLessAndEqual (vector<int> &A, int target) {
        int l = 0, r = A.size() - 1;
        while (l + 1 < r) {
            int mid = l + (r - l) / 2;
            if (A[mid] <= target) {
                l = mid;
            }else {
                r = mid;
            }
        }
        if (A[r] <= target) return r;
        if (A[l] <= target) return l;
        return -1;
    }
    void countK(vector<int> &A, int target, int k, vector<int> &ans, int index) {
        int left = index, right = index + 1;
        while (k && left >= 0 && right < A.size()) {
            while (k && left >= 0 && right < A.size() && abs(A[left] - target) <= abs(A[right] - target)) {
                ans.push_back(A[left--]);
                k--;
            }
            while (k && left >= 0 && right < A.size() && abs(A[left] - target) > abs(A[right] - target)) {
                ans.push_back(A[right++]);
                k--;
            }
        }
        while (k && left >= 0) {
            ans.push_back(A[left--]);
            k--;
        }
        while (k && right < A.size()) {
            ans.push_back(A[right++]);
            k--;
        }
    }
};
tags: Binary Search
​

Search in a Big Sorted Array


Search in a Big Sorted Array

  • Lintcode : 447 / Leetcode :
  • Level : Medium

Problem

Given a big sorted array with non-negative integers sorted by non-decreasing order. The array is so big so that you can not get the length of the whole array directly, and you can only access the kth number by ArrayReader.get(k) (or ArrayReader->get(k) for C++).

Find the first index of a target number. Your algorithm should be in O(log k), where k is the first index of the target number.

Return -1, if the number doesn't exist in the array.

Example
Example 1:

Input: [1, 3, 6, 9, 21, ...], target = 3
Output: 1
Example 2:

Input: [1, 3, 6, 9, 21, ...], target = 4
Output: -1
Challenge
O(logn) time, n is the first index of the given target number.

Notice
If you accessed an inaccessible index (outside of the array), ArrayReader.get will return 2,147,483,647.

Concept & Algorithm

Time Complexity & Space Complexity

time : O(logn)
space: O(1)

Answer

/**
 * Definition of ArrayReader:
 * 
 * class ArrayReader {
 * public:
 *     int get(int index) {
 *          // return the number on given index, 
 *          // return 2147483647 if the index is invalid.
 *     }
 * };
 */
class Solution {
public:
    int searchBigSortedArray(ArrayReader * reader, int target) {
        int l = 0, r = 1;
        while (reader -> get(r) < target) {
            r *= 2;
        }
        while (l + 1 < r) {
            int mid = l + (r - l) / 2;
            if (reader -> get(mid) >= target) {
                r = mid;
            }
            else {
                l = mid;
            }
        }
        if (reader -> get(l) == target) return l;
        if (reader -> get(r) == target) return r;
        return -1;
    }
};
tags: Binary Search
​

2019年11月9日 星期六

Median of K Sorted Arrays


Median of K Sorted Arrays

  • Lintcode : 931
  • Level : Hard

Problem

There are k sorted arrays nums. Find the median of the given k sorted arrays.

Example
Example 1:

Input:
[[1],[2],[3]]
Output:
2.00
Example 2:

Input:
[[1,1,2],[2,4,8],[3,7,10,20]]
Output:
3.50
Notice
The length of the given arrays may not equal to each other.
The elements of the given arrays are all positive number.
Return 0 if there are no elements in the array.
In order to ensure time complexity, the program will be executed repeatedly.

Concept & Algorithm

Time Complexity & Space Complexity

time : O(log(maximum - minimum) n logm)
(n = elements in nums, m = avg elements in n)
space: O(1)

Answer

class Solution {
public:
    double findMedian(vector<vector<int>> &nums) {
        if (nums.size() == 0) return 0;
        int n = 0;
        for (auto i : nums) {
            if (i.empty()) continue;
            n += i.size();
        }
        if (n == 0) return 0;
        if (n & 1) {   
            return findKth(nums, n / 2 + 1);    
        }else {
            return (findKth(nums, n / 2) + findKth(nums, n / 2 + 1)) / 2.0;
        }
    }

private:
    double findKth (vector<vector<int>> &nums, int k) {
        int lb = INT_MAX, ub = INT_MIN;
        for (auto i : nums){
            if (i.empty()) continue;
            lb = min(lb, i[0]);
            ub = max(ub, i.back());
        }
        int start = lb, end = ub;
        while (start + 1 < end) {
            int mid = start + (end - start) / 2;
            if (count(nums, mid) >= k) {
                end = mid;
            }else if (count(nums, mid) < k) {
                start = mid; ;
            }
        }
        if (count(nums, start) == k) return start;
        return end;
    }
    int count(vector<vector<int>> &nums, int key) {
        int count = 0;
        for (auto i : nums) {
            if (i.empty()) continue;
            count += countLessAndEqual(i, key);
        }
        return count;
    }
    int countLessAndEqual(vector<int> &n, int key) {
        int l = 0, r = n.size() - 1; 
        while (l + 1 < r) {
            int mid = l + (r - l) / 2;
            if (n[mid] <= key) {
                l = mid;
            }else {
                r = mid;
            }
        }
        if (n[l] > key) return l;
        if (n[r] > key) return r;
        return n.size();
    }
};
tags: Binary Search
​

2019年11月3日 星期日

Intersection of Two Arrays

Intersection of Two Arrays

  • Lintcode : 547
  • Level : Easy

Problem

Given two arrays, write a function to compute their intersection.

Example
Example 1:

Input: nums1 = [1, 2, 2, 1], nums2 = [2, 2], 
Output: [2].
Example 2:

Input: nums1 = [1, 2], nums2 = [2], 
Output: [2].
Challenge
Can you implement it in three different algorithms?

Notice
Each element in the result must be unique.
The order of the results needs to be ascending

Concept & Algorithm

Time Complexity & Space Complexity

sol 1:
time : O(n)
space: O(n)
sol 2:
time : O(n)
space: O(1)

Answer


// sol 1:
class Solution {
public:
    vector<int> intersection(vector<int> &nums1, vector<int> &nums2) {
        set<int> map(nums1.begin(), nums1.end());
        vector<int> ans;
        for (auto i : nums2) {
            if(map.find(i) != map.end()) {
                ans.push_back(i);
                map.erase(i);
            }
        }
        return ans;
    }
};

// sol 2:
class Solution {
public:
    vector<int> intersection(vector<int> &nums1, vector<int> &nums2) {
        if (nums1.size() == 0 || nums2.size() == 0) return {};
        sort(nums1.begin(), nums1.end());
        sort(nums2.begin(), nums2.end());
        vector<int> ans;
        for (int i = 0; i < nums1.size(); i++) {
            if (i > 0 && nums1[i] == nums1[i - 1]) continue;
            if (binarySearch(nums2, nums1[i])) {
                ans.push_back(nums1[i]);
            }
        }
        return ans;
    }
    bool binarySearch(vector<int> &nums2, int target) {
        int l = 0, r = nums2.size() - 1;
        while (l + 1 < r) {
            int mid = l + (r - l) / 2;
            if (nums2[mid] == target) return true;
            else if (nums2[mid] < target) {
                l = mid;
            }
            else r = mid;
        }
        if (nums2[l] == target) return true;
        if (nums2[r] == target) return true;
        return false;
    }
};
tags: Binary Search
​

Last Position of Target

Last Position of Target Lintcode : 458 / Leetcode : 34 Level : Easy Problem Find the last position of a target number in a sorted ...