leetcode_33_34_二分搜素
2015-04-24 21:01
295 查看
传送门:https://leetcode.com/problems/search-in-rotated-sorted-array/
思路:
这里首先先提供一下自己一开始写的代码:
现在看来简直乱得一塌糊涂。
自己的思路是正确的:如果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代码如下:
34.传送门:
https://leetcode.com/problems/search-for-a-range/
这道题要求在O(logn)的时间复杂度内解决问题。
提供两套思路:
第一种是最常规的解决方法,从左右对每一个元素进行比较:AC代码1:
35. search_insert
传送门:https://leetcode.com/problems/search-insert-position/
首先上AC代码:
上面的代码是只求AC的情况下写的,显然search和Insert是两个可以合并在一起的步骤,明天继续:
69 传送门:https://leetcode.com/problems/sqrtx/
开个玩笑,先水一下:AC代码1:
注意到mid*mid是一个极大的数值,所以用long long的数据类型来表示:
AC代码2:
74
传送门:
解题思路:先竖向查找,找出可能在的行。再横向二分查找,看是否有对应数值。
这道题唯一比较尴尬的是如果把自己AC代码里的注释去掉,会提醒无法通过测试用例[[1,3,5,7],[10,11,16,20],[23,30,34,50]], 30
而自己注释就是为了专门应对要求数值出现在最后一行的情况,sigh^……
AC代码1:
AC代码2:后续:自己应该是在判断i的大小这里出现了问题,更改注释后重新AC:
81 search_rotated_array_2
传送门:
这道题感觉不会太难,但AC起来总是有难度:
要注意的是:如果数组[1,2,3,3]进行rotate后可以变为[3,1,2,3],就不能简单地用vec[begin]<=vec[end]来判断是否进行二分搜素
AC代码:
和之前的几个实例完全是一样的情况。
AC代码_153:
思路:
这里首先先提供一下自己一开始写的代码:
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:
相关文章推荐
- [LeetCode]Array主题系列{1,11,15,16,18,26,27,31,33,34题}
- leetcode_34——Search for a Range(二分查找)
- leetcode 编程题 系列 (二分查找)旋转数组的查找、重复数字 33 153
- leetcode 33. Search in Rotated Sorted Array (复杂二分查找)
- leetcode 34. Search for a Range (二分查找)
- leetcode34题理解--二分
- 二分查找 检查边界条件 Leetcode 33. Search in Rotated Sorted Array
- leetcode 33. Search in Rotated Sorted Array(二分查找)
- Leetcode 34 Search for a Range (二分搜索 lower_bound和upper_bound)
- leetcode 33. Search in Rotated Sorted Array 二分查找
- LeetCode - 34/278/35 - 二分查找
- LeetCode 33~34
- LeetCode 33 Search in Rotated Sorted Array (二分查找 推荐)
- leetcode 34. Search for a Range 二分查找
- [LeetCode 33]Search in Rotated Sorted Array (二分查找)
- Leetcode 33 Search in Rotated Sorted Array 二分查找变式
- [leetcode-二分查找]--34. Search for a Range
- leetCode 33.Search in Rotated Sorted Array(排序旋转数组的查找) 解题思路和方法
- LeetCode 34 — Search for a Range(C++ Java Python)
- leetcode 34. Search for a Range