您的位置:首页 > 其它

leetcode_33_34_二分搜素

2015-04-24 21:01 295 查看
传送门: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:
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: