Binary Search

4. Median of Two Sorted Arrays


There are two sorted arrays nums1 and nums2 of size m and n respectively.

Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).

Example 1:

nums1 = [1, 3]
nums2 = [2]

The median is 2.0

Example 2:

nums1 = [1, 2]
nums2 = [3, 4]

The median is (2 + 3)/2 = 2.5
基本思路是使用二分搜索,保证时间复杂度为O(log(m+n))。子函数ans用于寻找nums1和nums2中第k大的数,具体实现时,将搜索范围划分为left和right两个部分,left取k/2和较短数组长度的较小值,right取k/2-left。当nums1[left-1]<nums2[right-1]时,表示nums1中第left个数字比nums2中第right个数字小,由于数组均有序,nums1中位于nums1[left]之前的数字均不需要再遍历了。在下一次搜索时,将nums1中前left个数字去除,并搜索新nums1和nums2中第k-left大的数字。同理,当nums1[left-1]>nums2[right-1]时,nums2中位于nums2[right]之前的数字均不需要再遍历了,进一步搜索nums1和新nums2中第k-right大的数字。这样,平均每次搜索时减少了1/2的搜索范围。

class Solution {
public:
    int ans(vector<int>& nums1,vector<int>& nums2,int k){
        int n=nums1.size();
        int m=nums2.size();
        if(n>m){
            return ans(nums2,nums1,k);
        }
        if(n==0) return nums2[k-1];
        if(k==1) return min(nums1[0],nums2[0]);
        int left=min(k/2,n),right=k-left;
        if(nums1[left-1]<nums2[right-1]){
            vector<int> a(nums1.begin()+left,nums1.end());
            return ans(a,nums2,k-left);
        }
        else if(nums1[left-1]>nums2[right-1]){
            vector<int> b(nums2.begin()+right,nums2.end());
            return ans(nums1,b,k-right);
        }
        else return nums1[left-1];
    }
    
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int n=nums1.size();
        int m=nums2.size();
        int k=(m+n)/2;
        if((m+n)%2){
            return ans(nums1,nums2,k+1);
        }
        else{
            return (ans(nums1,nums2,k)+ans(nums1,nums2,k+1))/2.0;
        }
    }
};

33. Search in Rotated Sorted Array


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.

在旋转数组中查找目标值,和正常查找一样使用二分法,但要考虑一些分支情况。当左值小于右值时,与正常查找一样处理。当左值大于右值时,意味着当前查找的数组分为被截断的两段。此时要根据中值位于左半段还是右半段分别进一步判断:当中值位于右半段时,再次需要根据target在中值左侧还是右侧进一步判断;当中值位于左半段时,也需要进一步判断。

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int l=0,r=nums.size()-1;
        while(l<=r){
            int m=(l+r)/2;
            if(target==nums[m]) return m;
            if(nums[l]<nums[r]){
                if(target>nums[m]) l=m+1;
                if(target<nums[m]) r=m-1;
            }
            else{
                if(nums[m]>=nums[l]){
                    if(target>nums[m] || target<=nums[r]){
                        l=m+1;
                    }else{
                        r=m-1;
                    }
                }else{
                    if(target<nums[m] || target>=nums[l]){
                        r=m-1;
                    }else{
                        l=m+1;
                    }
                }
            }
        }
        return -1;
    }
};


34. Search for a Range


Given a sorted array of integers, find the starting and ending position of a given target value.

Your algorithm's runtime complexity must be in the order of O(log n).

If the target is not found in the array, return [-1, -1].

For example,
Given [5, 7, 7, 8, 8, 10] and target value 8,
return [3, 4].

在有序数组中查找值的范围,要求时间复杂度为O(log n)。不断使用二分法查找,直到找到两个边界值为止。
class Solution {
public:
    int binary_search(vector<int> num, int low, int high, int key){
    while (low<=high) {
        int mid = low + (high-low)/2;
        if (num[mid] == key) {
            return mid;
        }
        if (key > num[mid]) {
            low = mid + 1;
        }
        if (key < num[mid]) {
            high = mid - 1;
        }
    }
    return -1;
    }
    
    vector<int> searchRange(vector<int>& nums, int target) {
        int n=nums.size();
        int pos = binary_search(nums, 0, n-1, target);
        vector<int> v;
        int low = -1, high = -1;
        if (pos >=0){
            low = high = pos;
            int l = low;
            do {
                low = l;
                l = binary_search(nums, 0, low - 1, target);
            }while (l>=0);
            int h = high;
            do {
                high = h;
                h = binary_search(nums, high + 1, n-1, target);
            }while (h>=0);
        }
        v.push_back(low);
        v.push_back(high);
        return v;
    }
};

35. Search Insert Position


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.

Here are few examples.
[1,3,5,6], 5 → 2
[1,3,5,6], 2 → 1
[1,3,5,6], 7 → 4
[1,3,5,6], 0 → 0

在有序数组中查找插入目标值的位置,标准的二分查找,最后返回查找范围的左边界l即可。

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


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值