代码随想录算法训练营第一天 | 704. 二分查找、27. 移除元素

文章介绍了LeetCode中的两道题目,分别是704.二分查找问题,讨论了左闭右闭和左闭右开两种解法,强调了循环条件和避免整型溢出。另一题是27.移除元素,提到了暴力搜索和双指针法的解决方案,双指针法通过一个慢指针保存有效数据,一个快指针遍历并跳过不需要的元素。
摘要由CSDN通过智能技术生成

Leetcode 704. 二分查找

初见想法:之前做过,注意lo和hi的取值

左闭右闭解法:

class Solution {
public:
    int search(vector<int>& nums, int target) {
        
        int lo = 0, hi = nums.size()-1;

        while (lo <= hi)
        {
            // 注意mid不能直接等于(lo+hi)/2,int类型可能会越界,这样写能保证mid <= hi
            int mid = lo + (hi-lo)/2;
            // 先判断 < 和 >,大概率不会先直接相等
            if (target < nums[mid]) hi = mid-1;
            else if (target > nums[mid]) lo = mid+1;
            else return mid;
        }

        // 没有搜索到,返回-1
        return -1;
    }
};  
  1. 使用while循环不断缩小搜索区间,每次搜索范围为闭区间,因此可能出现lo == hi的情况,所以while的循环条件为lo <= hi,结束时lo = hi+1。

  1. lo的初始值为0, 而hi的初始值为nums.size()-1,因为搜索时会到nums.size()-1。

左闭右开解法:

class Solution {
public:
    int search(vector<int>& nums, int target) {
        
        int lo = 0, hi = nums.size();

        // 搜索区间:左闭右开, 相等时无意义, eg. [1,1)
        while (lo < hi)
        {
            int mid = lo + ((hi-lo) >> 1);
            // 虽然targert < nums[mid],表示target不等于nusm[mid],
            // 循环的搜索区间不会到达mid,所以hi = mid
            if (target < nums[mid]) hi = mid;
            // 搜索区间为左闭右开
            else if (target > nums[mid]) lo = mid+1;
            else return mid;
        }

        return -1;
    }
}; 
  1. 整个nums被拆分为[lo, hi),mid,[lo,hi)这样的区间

  1. 只有当lo < hi才会循环,一旦lo == hi就会停止循环

  1. while循环的判断条件和mid是否需要+1或者-1对应

Leetcode 27. 移除元素

初见想法:for循环暴力搜索,检测到对应元素就依次复制后面的

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        
        int cnt = 0;
        while (cnt != nums.size())
        {
            if (nums[cnt] == val)
            {
                for (int j = cnt+1; j < nums.size(); j++)
                {
                    nums[j-1] = nums[j];
                }
                nums.pop_back();
            }
            else
            {
                cnt++;
            }
        }

        return nums.size();
    }
};

双指针法:

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int j = 0, sz = nums.size(); 
        for (int i = 0; i < sz; i++)
        {
            if (nums[i] != val)
            {
                swap(nums[i], nums[j++]);
            }
        }

        return j;
    }
};
  1. 两个指针,慢指针用来保存数据,快指针用来遍历原数组

  1. swap的过程就是在记录不是val的值,遇到val,快指针就直接跳过去,不交换

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值