训练营第一天| 704. 二分查找、27. 移除元素

一、704. 二分查找

题目链接:力扣

1.1 题目的第一想法
class Solution {
public:
        int search(vector<int>& nums, int target) {
          int left=0,right=nums.size(),mid;
          while(left<=right) {
          mid=(right+left)/2;
          if(nums[mid]==target)
          return mid;
          else if(nums[mid]>target) {
          right=mid;
          }
          else{
               left=mid;
           }
          }
            return -1;
        }
};
        结果:通过测试用例:6 / 47。
1.2  看完代码随想录之后的想法
        自己的想法跟接近左闭右开的区间里,也就是[left, right),但是while循环的条件和左边界left的更新错误。
        
 int middle = left + ((right - left) / 2);// 防止溢出 等同于(left + right)/2

文章讲解:代码随想录

1.3  今日收获和学习时长
        知道了二分法的两种思路:
        1)第一种写法,我们定义 target 是在一个在左闭右闭的区间里,也就是[left, right] (这个很重要非常重要)。
区间的定义这就决定了二分法的代码应该如何写,因为定义target在[left, right]区间,所以有如下三点:
        1.
while (left <= right) 要使用 <= ,因为left == right是有意义的,所以使用 <=
        2.
if (nums[middle] > target) right 要赋值为 middle - 1 ,因为当前这个nums[middle]一定不是target,那么接下来要查找的左区间结束下标位置就是 middle - 1   !!
        3. if (nums[middle] < target) left 要赋值为 middle + 1   !!
        2)二分法第二种写法
如果说定义 target 是在一个在左闭右开的区间里,也就是[left, right) ,那么二分法的边界处理方式则截然不同。
有如下两点:
while (left < right),这里使用 < ,因为left == right在区间[left, right)是没有意义的
if (nums[middle] > target) right 更新为 middle,因为当前nums[middle]不等于target,去左区间继续寻找,而寻找区间是左闭右开区间,所以right更新为middle,即:下一个查询区间不会去比较nums[middle]。
        3)学习时长45min。
二、27. 移除元素

题目链接:力扣

2.1 题目的第一想法
class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        sort(nums.begin(),nums.end());
        int ans=nums.size();
        for(int i=0;i<ans;i++)
        {
            if(nums[i]==val)
            {
                int temp=nums[ans-1];
                nums[ans-1]=nums[i];
                nums[i]=temp;
                ans--;
            }
        }
        return ans;
    }
};
        结果:通过测试用例:91/ 113。因为ans和ans-1变化了,导致遍历不完整。
2.2  看完代码随想录之后的想法

文章讲解:代码随想录

        1)先试试暴力的双for循环
                开始没理解i--的含义,其实就是i的值变了,需要重新判断。
                 同时,在自已的方法的if条件句中加入i--,也能通过全部样例。
        2)双指针法
                fast遍历原数组,slow保存需要的值、再++,最后slow的大小也就是新数组的大小。
class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int i=0,j=0;
        for(;i<nums.size();i++)
        {
            if(nums[i]!=val)
            {
                nums[j]=nums[i];
                j++;
            }
                
        }
        return j;
    }
};
2.3  今日收获和学习时长
        接触过类似的题目,就是在原数组上实现覆盖操作。
        时长1h。
        
        
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值