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;
}
};
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]
.
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
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;
}
};