二分查找总结

Suppose a sorted array is rotated at some pivot unknown to you beforehand.

(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).

You are given a target value to search. If found in the array return its index, otherwise return -1.

You may assume no duplicate exists in the array.

Example

For [4, 5, 1, 2, 3] and target=1, return 2.

For [4, 5, 1, 2, 3] and target=0, return -1.


class Solution {
public:
    /*
     * @param A: an integer rotated sorted array
     * @param target: an integer to be searched
     * @return: an integer
     */
    int search(vector<int> &A, int target) {
        // write your code here
        if (A.size() == 0) {
            return -1;
        }
        int i = 0;
        int j = A.size() - 1;
        while (i + 1 < j) {
            int mid = (j - i) / 2 + i;
            if (A[mid] == target) {
                return mid;
            } 
            if (A[mid] > A[i]) {
                if (target >= A[i] && A[mid] > target) {
                    j = mid - 1;
                } else {
                    i = mid + 1;
                }
            } else if (A[mid] < A[j]) {
                if (target <= A[j] && A[mid] < target) {
                    i = mid + 1;
                } else {
                    j = mid - 1;
                }
            }
        }
        if (A[i] == target) {
            return i;
        } else if (A[j] == target) {
            return j;
        } else {
            return -1;
        }
    }
};

Follow up for Search in Rotated Sorted Array:

What if duplicates are allowed?

Would this affect the run-time complexity? How and why?

Write a function to determine if a given target is in the array.

Example

Given [1, 1, 0, 1, 1, 1] and target = 0, return true.
Given [1, 1, 1, 1, 1, 1] and target = 0, return false.


class Solution {
public:
    /*
     * @param A: an integer ratated sorted array and duplicates are allowed
     * @param target: An integer
     * @return: a boolean 
     */
    bool search(vector<int> &A, int target) {
        // write your code here
        if (A.size() == 0) {
            return false;
        }
        int i = 0;
        int j = A.size() - 1;
        while (i + 1 < j) {
            int mid = (j - i) / 2 + i;
            if (A[mid] == target) {
                return true;
            } else if (A[mid] > A[i]) {
                if (A[i] <= target && target < A[mid]) {
                    j = mid - 1;
                } else {
                    i = mid + 1;
                }
            } else if (A[mid] < A[i]) {
                if (target <= A[j] && target > A[mid]) {
                    i = mid + 1;
                } else {
                    j = mid - 1;
                }
            } else {
                i++;
            }
        }
        if (A[i] == target || A[j] == target) {
            return true;
        } else {
            return false;
        }
    }
};

Given a sorted array and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order.

You may assume NO duplicates in the array.

Example

[1,3,5,6], 5 → 2

[1,3,5,6], 2 → 1

[1,3,5,6], 7 → 4

[1,3,5,6], 0 → 0


class Solution {
public:
    /*
     * @param A: an integer sorted array
     * @param target: an integer to be inserted
     * @return: An integer
     */
    int searchInsert(vector<int> &A, int target) {
        // write your code here
        int i = 0;
        int j = A.size();
        while (i < j) {
            int mid = (j - i) / 2 + i;
            if (A[mid] == target) {
                return mid;
            } else if (A[mid] < target) {
                i = mid + 1;
            } else {
                j = mid;
            }
        }
        return i;
    }
};

Given n pieces of wood with length L[i] (integer array). Cut them into small pieces to guarantee you could have equal or more than k pieces with the same length. What is the longest length you can get from the n pieces of wood? Given L & k, return the maximum length of the small pieces.

Notice

You couldn't cut wood into float length.

If you couldn't get >= k pieces, return 0.

Example

For L=[232, 124, 456], k=7, return 114.

class Solution {
public:
    /*
     * @param L: Given n pieces of wood with length L[i]
     * @param k: An integer
     * @return: The maximum length of the small pieces
     */
    int woodCut(vector<int> &L, int k) {
        // write your code here
        int max_value = 0;
        for (int i = 0; i < L.size(); i++) {
            max_value = max(max_value, L[i]);
        }


        int i = 1;
        int j = max_value;
        while (i <= j) {
            int mid = (j - i) / 2 + i;
            int count = 0;
            for (int i = 0; i < L.size(); i++) {
                count += L[i]/mid;
            }
            if (count >= k) {
                i = mid + 1;
            } else {
                j = mid - 1;
            }
        }
        return i - 1;
    }
};

Given a rotated sorted array, recover it to sorted array in-place.

Clarification

What is rotated array?

  • For example, the orginal array is [1,2,3,4], The rotated array of it can be [1,2,3,4], [2,3,4,1], [3,4,1,2], [4,1,2,3]
Example

[4, 5, 1, 2, 3] -> [1, 2, 3, 4, 5]


class Solution {
public:
    /*
     * @param nums: An integer array
     * @return: nothing
     */
    void recoverRotatedSortedArray(vector<int> &nums) {
        // write your code here
        int i = 0;
        int j = nums.size() - 1;
        while (i < j) {
            int mid = (j - i) / 2 + i;
            if (nums[mid] < nums[j]) {
                j = mid;
            } else if (nums[mid] > nums[j]){
                i = mid + 1;
            } else {
                j--;
            }
        }
        reverse(nums, 0 , i - 1);
        reverse(nums, i, nums.size() - 1);
        reverse(nums, 0, nums.size() - 1);
    }
    void reverse(vector<int> &nums, int start, int end) {
        while (start < end) {
            swap(nums[start++], nums[end--]);
        }
    }
};

There is an integer array which has the following features:

  • The numbers in adjacent positions are different.
  • A[0] < A[1] && A[A.length - 2] > A[A.length - 1].

We define a position P is a peak if:

A[P] > A[P-1] && A[P] > A[P+1]

Find a peak element in this array. Return the index of the peak.

Notice
  • It's guaranteed the array has at least one peak.
  • The array may contain multiple peeks, find any of them.
  • The array has at least 3 numbers in it.
Example

Given [1, 2, 1, 3, 4, 5, 7, 6]

Return index 1 (which is number 2) or 6 (which is number 7)

class Solution {
public:
    /*
     * @param A: An integers array.
     * @return: return any of peek positions.
     */
    int findPeak(vector<int>& A) {
        // write your code here
        int i = 0;
        int j = A.size() - 1;
        while (i < j) {
            int mid = (j - i) / 2 + i;
            if (A[mid] < A[mid + 1]) {
                i = mid + 1;
            } else {
                j = mid;
            }
        }
        return i;
    }
};
Median of two Sorted Arrays

There are two sorted arrays A and B of size m and n respectively. Find the median of the two sorted arrays.

Example

Given A=[1,2,3,4,5,6] and B=[2,3,4,5], the median is 3.5.

Given A=[1,2,3] and B=[4,5], the median is 3.

点题:base on pos is better than base on value

class Solution {
public:
    /*
     * @param A: An integer array
     * @param B: An integer array
     * @return: a double whose format is *.5 or *.0
     */
    double findMedianSortedArrays(vector<int> &A, vector<int> &B) {
        // write your code here
        int k = A.size() + B.size();
        if (k == 0) {
            return 0;
        } else if (k % 2 == 1) {
            return findMedianSortedArrays2(A, B, k/2 + 1, 0, A.size(), 0, B.size());
        } else if (k % 2 == 0) {
            return (findMedianSortedArrays2(A, B, k/2, 0, A.size(), 0, B.size())
             + findMedianSortedArrays2(A, B, k/2 + 1, 0, A.size(), 0, B.size())) / 2.0;
        }
    }
    // base on pos
    int findMedianSortedArrays(vector<int> &A, vector<int> &B, int k,
                                  int startA, int lenA, int startB, int lenB) {
        if (lenA > lenB) {
            return findMedianSortedArrays(B, A, k, startB, lenB, startA, lenA);
        }
        if (lenA == 0) {
            return B[startB + k - 1];
        }
        if (k == 1) {
            return min(A[startA], B[startB]);
        }
        int m = min(k/2, lenA);
        int n = k - m;
        if (A[startA + m - 1] < B[startB + n - 1]) {
            return findMedianSortedArrays(A, B, k - m, startA + m, lenA - m, startB, lenB);
        } else if (A[startA + m - 1] > B[startB + n - 1]) {
            return findMedianSortedArrays(A, B, k - n, startA, lenA, startB + n, lenB - n);
        } else if (A[startA + m - 1] == B[startB + n - 1]) {
            return A[startA + m - 1];
        }
    }
    // base on value
    int findMedianSortedArrays2(vector<int> &A, vector<int> &B, int k,
                                  int startA, int lenA, int startB, int lenB) {
        if (lenA <= 0) {
            return B[startB + k - 1];
        } else if (lenB <= 0) {
            return A[startA + k - 1];
        } // always can find the kth numbers

        if (k == 1) {
            return min(A[startA], B[startB]);
        }
        // value
        long long m = (k / 2 <= lenA ? A[startA + k / 2 - 1] : LLONG_MAX);
        long long n = (k / 2 <= lenB ? B[startB + k / 2 - 1] : LLONG_MAX);
        if (m < n) {
            return findMedianSortedArrays2(A, B, k - k/2, startA + k/2, lenA - k/2, startB, lenB);
        } else if (m > n) {
            return findMedianSortedArrays2(A, B, k - k/2, startA, lenA, startB + k/2, lenB - k/2);
        } else if (m == n) {
            return m;
        }
    }
};


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值