0
点赞
收藏
分享

微信扫一扫

一篇学会写出不会死循环的二分

萨科潘 2022-04-30 阅读 29
算法

在这里插入图片描述

不会死的二分模板

image-20220430191141660

int findPosition(vector<int> &nums,int target)
{
    int left=0;
    int right=nums.size()-1;
    //结束条件为left和right相邻
    while(left+1<right)
    {
        int mid=left+(right-left)/2;
        if(a[mid]==target)
            right=mid;
        else if(a[mid]<target)
            left=mid;
        else if(a[mid>target])
            right=mid;
    }
    if(a[left]==target)
        return left;
    if(a[right]==target)
        return right;
    return -1;
}
int findPosition(vector<int> &nums,int target)
{
    int left=0;
    int right=nums.size()-1;
    //结束条件为left和right相邻
    while(left+1<right)
    {
        int mid=left+(right-left)/2;
        if(a[mid]==target)
            left=mid;
        else if(a[mid]<target)
            left=mid;
        else if(a[mid>target])
            right=mid;
    }
    if(a[right]==target)
        return right;
    if(a[left]==target)
        return left;
    return -1;
}

题目

image-20220430222349773

题目一:457 · 经典二分查找问题 - LintCode

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PFiAESjd-1651328703475)(https://s2.loli.net/2022/04/30/KeFqb35RX1U6pfr.png)]

class Solution {
public:
    int findPosition(vector<int> &nums, int target) {
        // write your code here
        if(nums.size()==0)
            return -1;
        int left=0;
        int right=nums.size()-1;
        while(left+1<right)
        {
            int mid=left+(right-left)/2;
            if(nums[mid]==target)
            {
                right=mid;
            }
            else if(nums[mid]<target)
            {
                left=mid;
            }
            else if(nums[mid]>target)
            {
                right=mid;
            }
        }
        if(nums[left]==target)
            return left;
        if(nums[right]==target)
            return right;
        return -1;
    }
};

题目二:458 · 目标最后位置 - LintCode)

image-20220430184129109

class Solution {
public:
    /**
     * @param nums: An integer array sorted in ascending order
     * @param target: An integer
     * @return: An integer
     */
    int lastPosition(vector<int> &nums, int target) {
        // write your code here
        int left=0;
        int right=nums.size()-1;
        if(nums.size()==0)
            return -1;
        while(left+1<right)
        {
            int mid=left+(right-left)/2;
            if(nums[mid]==target)
                left=mid;
            else if(nums[mid]<target)
                left=mid;
            else if(nums[mid]>target)
                right=mid;
        }
        if(nums[right]==target)
            return right;
        if(nums[left]==target)
            return left;
        return -1;
    }
};

题目三:65 · 两个排序数组的中位数 - LintCode

class Solution {
public:
    /**
     * @param a: An integer array
     * @param b: An integer array
     * @return: a double whose format is *.5 or *.0
     */
    double found(vector<int> &a, vector<int> &b,int starta,int startb,int k)
    {
        //如果A数组里面没有数
        if(starta>=a.size())
            return b[startb+k-1];
        //如果B数组里面没有数
        if(startb>=b.size())
            return a[starta+k-1];
        //递归的退出条件,如果找最小的数就找两个数组第一个数的较小数
        if(k==1)
            return min(a[starta],b[startb]);
        //如果一个数组太短,那么删除的一定是长的数组的前k/2
        //所以如果数组长度不够,比较值设置为INT_MAX,删除的就是另一个数组的数
        int keya=starta+k/2-1>=a.size()?INT_MAX:a[starta+k/2-1];
        int keyb=startb+k/2-1>=b.size()?INT_MAX:b[startb+k/2-1];
        if(keya>keyb)
            return found(a,b,starta,startb+k/2,k-k/2);
        else
            return found(a,b,starta+k/2,startb,k-k/2);
    }
    double findMedianSortedArrays(vector<int> &a, vector<int> &b) {
        // write your code here
        int sum=a.size()+b.size();
        double ret;
        if(sum&1)
            ret=found(a,b,0,0,sum/2+1);
        else
            ret=(found(a,b,0,0,sum/2)+found(a,b,0,0,sum/2+1))/2;
        return ret;
    }
};

题目四:28 · 搜索二维矩阵 - LintCode

image-20220430183930151

class Solution {
public:
    /**
     * @param matrix: matrix, a list of lists of integers
     * @param target: An integer
     * @return: a boolean, indicate whether matrix contains target
     */
    bool searchMatrix(vector<vector<int>> &matrix, int target) {
        // write your code here
        int n=matrix.size();
        if(maxtrix==NULL||n==0) return false;
        int m=matrix[0].size();
        if(maxtrix[0]==NULL||m==0) return false;
        //进行二分查找
        int left=0;
        int right=n*m-1;
        while(left+1<right)
        {
            int mid=left+(right-left)/2;
            int row=mid/m;
            int col=mid%m;
            if(matrix[row][col]==target)
                return true;
            else if(matrix[row][col]>target)
                right=mid;
            else if(matrix[row][col]<target)
                left=mid;
        }
        if(matrix[left/m][left%m]==target)
            return true;
        if(matrix[right/m][right%m]==target)
            return true;
        return false;
    }
};

题目四:60 · 搜索插入位置 - LintCode

image-20220430183905174

class Solution {
public:
    /**
     * @param a: an integer sorted array
     * @param target: an integer to be inserted
     * @return: An integer
     */
    int searchInsert(vector<int> &a, int target) {
        // write your code here
        if(a.size()==0)
            return 0;
        int left=0;
        int right=a.size()-1;
        while(left+1<right)
        {
            int mid=left+(right-left)/2;
            if(a[mid]==target)  
                return mid;
            else if(a[mid]>target)
                right=mid;
            else if(a[mid]<target)
                left=mid;
        }
        if(target>a[right])
            return right+1;
        if(target>a[left])
            return right;
        return 0;
    }
};

题目五:447 · 在大数组中查找 - LintCode

image-20220430190219784

class Solution {
public:
    int searchBigSortedArray(ArrayReader * reader, int target) {
        int left=0,right=1;
        while(reader->get(right)<target)
            right<<=1;
        //在区间内二分查找
        while(left+1<right)
        {
            int mid=left+(right-left)/2;
            if(reader->get(mid)<target)
                left=mid;
            else
                right=mid;
        }
        if(reader->get(left)==target)
            return left;
        if(reader->get(right)==target)
            return right;
        return -1;
    }
};

题目六:159 · 寻找旋转排序数组中的最小值 - LintCode

image-20220430193745103

image-20220430194714865

class Solution {
public:
    int findMin(vector<int> &nums) {
        int left=0;
        int right=nums.size()-1;
        while(left+1<right)
        {
            int mid=left+(right-left)/2;
            if(nums[mid]>nums[right])
                left=mid;
            else 
                right=mid;
        }
        //相邻时退出
        return min(nums[left],nums[right]);
    }
};

题目七:62 · 搜索旋转排序数组 - LintCode

class Solution {
public:
    int search(vector<int> &a, int target) {
        int left=0,right=a.size()-1;
        if(left>right)
            return -1;
        while(left+1<right)
        {
            int mid=left+(right-left)/2;
            //如果mid落在了左区间
            if(a[mid]>a[left])
            {
                //如果target在mid的左边并且不再右区间
                if(target<a[mid]&&a[left]<=target)
                    right=mid;
                else
                    left=mid;
            }
            else
            {
                if(target>a[mid]&&target<=a[right])
                    left=mid;
                else
                    right=mid;
            }
        }
        if(a[left]==target) 
            return left;
        if(a[right]==target)
            return right;
        return -1;
    }
};

题目八:183 · 木材加工 - LintCode

image-20220430214628583

class Solution {
public:
    //判断是否长度是否合适
	bool cut(vector<int>&l,int len,int k)
	{
		int count=0;
		for(int i=0;i<l.size();i++)
		{
			count+=l[i]/len;
		}
		if(count>=k)
			return true;
		else
			return false;
	}
    int woodCut(vector<int> &l, int k) {
	    if(l.size()==0)	
	    		return 0;
		int maxl=0;
		for(int i=0;i<l.size();i++)
		{
			maxl=max(maxl,l[i]);
		}
		int start=0,end=maxl;
		while(start+1<end)
		{
			int mid=start+(end-start)/2;
			if(cut(l,mid,k))
			{
				start=mid;
			}
			else
				end=mid;
		}
		if(cut(l,end,k))	return end;
		return start;
    }
};
举报

相关推荐

0 条评论