传送门:https://leetcode.com/problems/search-in-rotated-sorted-array/
思路:
这里首先先提供一下自己一开始写的代码:
class Solution {
public:
int binary_search(vector<int>& vec,int begin,int end,int target)
{
while(begin<=end)
{
int mid=begin+(end-begin)/2;
if(vec[mid]==target) return mid;
if(vec[mid]>target) end=mid-1;
else begin=mid+1;
}
return -1;
}
int search(vector<int>& nums, int target) {
int i,j,k;
bool flag=true;
int begin=0,end=nums.size()-1;
if(begin==end) return binary_search(nums,0,0,target);
if(nums[begin]<nums[end]) return binary_search(nums,0,end,target);
else
{
for(i=1;i<=nums.size()-1;i++)
{
if((nums[i]>nums[i-1] && nums[i]<nums[i+1]) || (nums[i]<nums[i-1] && nums[i]>nums[i-1]))
return i;
}
return (binary_search(nums,begin,i,target)==-1?binary_search(nums,begin,end,target):binary_search(nums,i+1,end,target));
}
}
};
现在看来简直乱得一塌糊涂。
自己的思路是正确的:如果vec[begin]<vec[end],那么说明是有序的,可以直接用二分搜素。
((nums[i]>nums[i-1] && nums[i]<nums[i+1]) || (nums[i]<nums[i-1] && nums[i]>nums[i-1])
如果不能满足,那么找出中间节点,就是上述代码所满足的i;这样的代码毫无美感,过了2个测试用例后就再也过不去了。
所以自己转换思路,用另一种方法找到不是顺序队列的范围:递归。
设置search()函数,用(begin,mid)/(mid+1,end)依次去试。
还有一点是在看discuss后注意到的,要用vec[begin]<=vec[end]来判断,应对出现长度为1数组的情况。
AC代码如下:
class Solution {
public:
int binary_search(vector<int>& vec,int begin,int end,int target)
{
while(begin<=end)
{
int mid=begin+(end-begin)/2;
if(vec[mid]==target) return mid;
if(vec[mid]>target) end=mid-1;
else begin=mid+1;
}
return -1;
}
int search(vector<int>& vec,int begin,int end,int target)
{
if(vec[begin]<=vec[end]) return binary_search(vec,begin,end,target);
else
{
int mid=begin+(end-begin)/2;
int temp=search(vec,begin,mid,target);
if(temp!=-1) return temp;
return search(vec,mid+1,end,target);
}
}
int search(vector<int>& nums, int target) {
int i,j,k;
int begin=0,end=nums.size()-1;
return search(nums,begin,end,target);
}
};
34.传送门:
https://leetcode.com/problems/search-for-a-range/
这道题要求在O(logn)的时间复杂度内解决问题。
提供两套思路:
第一种是最常规的解决方法,从左右对每一个元素进行比较:AC代码1:
class Solution {
public:
vector<int> searchRange(vector<int>& nums, int target) {
int length=nums.size();
int i,j,k;
int start=-1,end=-1;
for(i=0;i<length;i++)
{
if(nums[i]==target) {start=i;break;}
}
for(int j=length-1;j>=0;j--)
{
if(nums[j]==target) {end=j;break;}
}
vector<int> vec;
if(start==end&&start==-1) {vec.push_back(-1);vec.push_back(-1);return vec;};
vec.push_back(start);vec.push_back(end); // 不能用vec[0]=-1这样直接赋值的方式?
return vec;
}
};
AC代码2:是用二分搜索的思路:
35. search_insert
传送门:https://leetcode.com/problems/search-insert-position/
首先上AC代码:
class Solution {
public:
int search(vector<int> &nums,int target)
{
int begin=0,end=nums.size()-1;
while(begin<=end)
{
int mid=begin+(end-begin)/2;
if(nums[mid]==target) return mid;
if(nums[mid]<target) begin=mid+1;
else end=mid-1;
}
return -1;
}
int searchInsert(vector<int>& nums, int target) {
int i;
int temp=search(nums,target);
if(temp!=-1) return temp;
else
{
for(i=0;i<nums.size();i++)
{
if(nums[i]>target) break;
}
return i;
}
}
};
上面的代码是只求AC的情况下写的,显然search和Insert是两个可以合并在一起的步骤,明天继续:
69 传送门:https://leetcode.com/problems/sqrtx/
开个玩笑,先水一下:AC代码1:
class Solution {
public:
int mySqrt(int x) {
return int(sqrt(x));
}
};
正规的思路是用二分搜索进行依次查找:
注意到mid*mid是一个极大的数值,所以用long long的数据类型来表示:
AC代码2:
class Solution {
public:
int binary_search(int x)
{
long long begin=0,end=x;
while(begin<=end)
{
long long mid=begin+(end-begin)/2;
long long mul=mid*mid;
if(mul==x) return mid;
if(mul<x) begin=mid+1;
else end=mid-1;
}
long long mul=end*end;
return mul>x?begin:end;
}
int mySqrt(int x) {
return binary_search(x);
}
};
74
传送门:
解题思路:先竖向查找,找出可能在的行。再横向二分查找,看是否有对应数值。
这道题唯一比较尴尬的是如果把自己AC代码里的注释去掉,会提醒无法通过测试用例[[1,3,5,7],[10,11,16,20],[23,30,34,50]], 30
而自己注释就是为了专门应对要求数值出现在最后一行的情况,sigh^……
AC代码1:
class Solution {
public:
bool binary_search(vector<int> vec,int target)
{
int begin=0,end=vec.size()-1;
while(begin<=end)
{
int mid=begin+(end-begin)/2;
if(vec[mid]==target) return true;
if(vec[mid]<target) begin=mid+1;
else end=mid-1;
}
return false;
}
bool searchMatrix(vector<vector<int> > &matrix, int target) {
int i;
bool flag=false;
if(matrix.size()==1) return binary_search(matrix[0],target);
for(i=0;i<matrix.size();i++)
{
if(matrix[i][0]==target) return true;
}
for(i=0;i<matrix.size()-1;i++)
{
if(matrix[i][0]<target && matrix[i+1][0]>target) {flag=true;break;}
}
/*if(i==matrix.size()-2)
{
if(binary_search(matrix[i+1],target)) return true;
}*/
//if(!flag) return false;
return binary_search(matrix[i],target);
}
};
AC代码2:后续:自己应该是在判断i的大小这里出现了问题,更改注释后重新AC:
class Solution {
public:
bool binary_search(vector<int> vec,int target)
{
int begin=0,end=vec.size()-1;
while(begin<=end)
{
int mid=begin+(end-begin)/2;
if(vec[mid]==target) return true;
if(vec[mid]<target) begin=mid+1;
else end=mid-1;
}
return false;
}
bool searchMatrix(vector<vector<int> > &matrix, int target) {
int i;
bool flag=false;
if(matrix.size()==1) return binary_search(matrix[0],target);
for(i=0;i<matrix.size();i++)
{
if(matrix[i][0]==target) return true;
}
for(i=0;i<matrix.size()-1;i++)
{
if(matrix[i][0]<target && matrix[i+1][0]>target) {flag=true;break;}
}
if(i==matrix.size()-1)
{
if(binary_search(matrix[i],target)) return true;
}
if(!flag) return false;
return binary_search(matrix[i],target);
}
};
81 search_rotated_array_2
传送门:
这道题感觉不会太难,但AC起来总是有难度:
要注意的是:如果数组[1,2,3,3]进行rotate后可以变为[3,1,2,3],就不能简单地用vec[begin]<=vec[end]来判断是否进行二分搜素
AC代码:
class Solution {
public:
int binary_search(vector<int>& vec,int begin,int end,int target)
{
while(begin<=end)
{
int mid=begin+(end-begin)/2;
if(vec[mid]==target) return true;
if(vec[mid]>target) end=mid-1;
else begin=mid+1;
}
return false;
}
int search(vector<int>& vec,int begin,int end,int target)
{
if(begin>=end) return vec[begin]==target;
if(vec[begin]<vec[end]) return binary_search(vec,begin,end,target);
else
{
int mid=begin+(end-begin)/2;
int temp=search(vec,begin,mid,target);
if(temp) return true;
return search(vec,mid+1,end,target);
}
}
bool search(vector<int>& nums, int target) {
int i,j,k;
int begin=0,end=nums.size()-1;
return search(nums,begin,end,target);
}
};
153,154
和之前的几个实例完全是一样的情况。
AC代码_153: