代码随想录算法训练营第一天|704.二分查找

704.二分查找

思路:首尾双指针比较中间元素,若target小于中间则在左边区域 ,否则在右边区域,有一点递归思想。

第一次解答:

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int n=nums.size();
        int middle=n/2;
        int left=0;
        int right=n-1;
        while(left!=right){
            if(target<=nums[middle]){return middle;}

            if(target<nums[middle]){
                right=middle;
                middle=(left+middle)/2;
            }else{
                left=middle;
                middle=(right+middle)/2;
            }   
        }   
        return -1; 
    }
};

 错误原因:if(target<=nums[middle]){return middle;}这里判断条件书写错误  

第二次解答:

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int n=nums.size();
        
        int left=0;
        int right=n-1;
        while(left!=right){
            int middle=(left+right)/2;
            if(target==nums[middle]){return middle;}
            if(target<nums[middle]){
                right=middle;
            }else{
                left=middle;
            }   
        }   
        return -1; 
    }
};

出现超时原因:问题出在 leftright 的更新逻辑上。具体来说,当 target 不在数组中时,leftright 的更新可能会导致它们永远无法相等,从而陷入无限循环。会出现不管怎么更新 left一直等于middle,从而进入死循环。突破点在于每次更新都要缩小范围。

正确解答:

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int n=nums.size();
        
        int left=0;
        int right=n-1;
        while(left<=right){
            int middle = left+(right - left) / 2;  // 防止溢出
            if(target==nums[middle]){return middle;}
            if(target<nums[middle]){
                right=middle-1;   //这里缩小范围
            }else{
                left=middle+1;    //这里缩小范围
            }   
        }   
        return -1; 
    }
};

提示:直接使用 (left + right) / 2 来计算 middle 可能会导致整数溢出,尤其是当 leftright 的值非常大时。例如,如果 leftINT_MAXrightINT_MAX,直接加法 left + right 会超出整数类型的范围。比如 left = 2147483647(即 INT_MAX),right = 2147483647。直接使用 middle = (left + right) / 2 会得到:4294967294 会超出整数范围
因此推荐用:middle = left+(right - left) / 2;

 解答思路:

遍历nums中的所有元素,每次遍历k都加1,如果出现当前元素等于val,将当前元素之后的所有元素前移一格,然后k-1。

错误解答:

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int k=0;
        int length=nums.size();
        for(int i=0;i<length;i++){
            if(nums[i]==val){
                for(int j=i;j<length-1;j++){
                    nums[j]=nums[j+1];
                }
                k--;
            }
            k++;
        }
      return k;  
    }
};

 问题在于后面的元素前移后,应该继续从当前元素开始遍历,而且遍历长度也应该减1。

正确解答:

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int k=0;
        int length=nums.size();
        for(int i=0;i<length;i++){
            if(nums[i]==val){
                for(int j=i;j<length-1;j++){
                    nums[j]=nums[j+1];
                }
                i--;length--;  //这里的作用是让下次遍历仍然从当前位置开始,并且总的遍历长度减一
                k--;
            }
            k++;
        }
      return k;  
    }
};

其他优秀解答:

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int k = 0;
        for (int x : nums) {
            if (x != val) {
                nums[k++] = x;
            }
        }
        return k;
    }
};

作者:灵茶山艾府
链接:https://leetcode.cn/problems/remove-element/solutions/2802809/jian-dan-ti-jian-dan-zuo-pythonjavaccgoj-72bn/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

思路:第一种,求绝对值后排序

第二种,双指针 找绝对值最小的  然后从最小值的两端开始比较  ,这个思路实现起来太复杂了,还不如从最边边开始比较。

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        vector<int>ans(nums.size());
        int left=0;
        int right=nums.size()-1;
        int maxIndex=nums.size()-1;
        while(left<right){
            if(abs(nums[left])<abs(nums[right])){
                ans[maxIndex]=nums[right]*nums[right];
                right--;
            }
            else{
                ans[maxIndex]=nums[left]*nums[left];
                left++;
            }
            maxIndex--;
        }
        return ans;
    }
};

这种判断条件少了个等号 导致 第一个元素一直为0

正确解答:

class Solution {
public:
    vector<int> sortedSquares(vector<int>& nums) {
        vector<int>ans(nums.size());
        int left=0;
        int right=nums.size()-1;
        int maxIndex=nums.size()-1;   
        while(left<=right){    //这里判断条件是小于等于
            if(abs(nums[left])<abs(nums[right])){
                ans[maxIndex]=nums[right]*nums[right];
                right--;
            }
            else{
                ans[maxIndex]=nums[left]*nums[left];
                left++;
            }
            maxIndex--;
        }
        return ans;
    }
};

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值