leetcode_33_34_二分搜素

传送门: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:





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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值