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

LeetCode 704 二分查找

题目链接: https://leetcode.cn/problems/binary-search/submissions/
文章链接: https://programmercarl.com/0704.%E4%BA%8C%E5%88%86%E6%9F%A5%E6%89%BE.html#%E7%AE%97%E6%B3%95%E5%85%AC%E5%BC%80%E8%AF%BE

第一眼思路: 首先比较数组中间值与目标值的大小,根据大小调整搜索区间

遇到问题:

  1. 忘记一些处理数组的常用函数了,例如取数组中元素个数的nums.size(),这个博客里列举了一些常用函数:
    https://blog.csdn.net/u012011912/article/details/131682992?ops_request_misc=&request_id=&biz_id=102&utm_term=c++%E5%A4%84%E7%90%86%E6%95%B0%E7%BB%84%E7%9A%84%E5%87%BD%E6%95%B0&utm_medium=distribute.pc_search_result.none-task-blog-2allsobaiduweb~default-3-131682992.142v99pc_search_result_base4&spm=1018.2226.3001.4187

  2. 关于如何取中间值,因为太久没写代码,都有点记不清了,最开始将右下标减去左下标后除以二,忘记加左下标了。。

int middle = (right - left) / 2 + left;
  • 第三个问题,写的时候没想到把left和right的比较拿来做while循环的跳出条件,用的数组middle值与target的比较,怎么写感觉怎么不对呢。。结果运行也超时了

看文章收获:

  1. 左闭右闭
  • while (left <= right) 要使用 <= ,因为left == right是有意义的,所以使用 <=
  • if (nums[middle] > target) right 要赋值为 middle - 1,因为当前这个nums[middle]一定不是target,那么接下来要查找的左区间结束下标位置就是 middle - 1
  1. 左闭右开
  • while (left < right),这里使用 < ,因为left == right在区间[left, right)是没有意义的
  • if (nums[middle] > target) right 更新为 middle,因为当前nums[middle]不等于target,去左区间继续寻找,而寻找区间是左闭右开区间,所以right更新为middle,即:下一个查询区间不会去比较nums[middle]

最终代码!

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

提交后无意点开提交记录,这……真是零的突破啊,希望自己这次能真正地坚持下来!
在这里插入图片描述

LeetCode 27.移除元素

题目链接: https://leetcode.cn/problems/remove-element/description/
文章链接: https://www.programmercarl.com/0027.%E7%A7%BB%E9%99%A4%E5%85%83%E7%B4%A0.html#%E6%80%9D%E8%B7%AF
第一眼思路: 先用一个for循环检测数组中和目标数值相同的元素,然后再用一个for循环移动元素,这是暴力解法,时间复杂度为O(n^2)
暴力解法如下:

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

遇到的问题:

  • 使用暴力解法时没注意到for循环中要i–,因为i后面的元素整体前移了一位,循环到for的控制语句时要i++,这样就不能检测到移动的哪一位,故要i–;

看文章思路: 学到了双指针法,通过一个快指针和慢指针在一个for循环下完成两个for循环的工作。

  • 快指针:寻找新数组的元素 ,新数组就是不含有目标元素的数组
  • 慢指针:指向更新,新数组下标的位置

最终代码:

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int slowIndex = 0;
        for(int fastIndex = 0; fastIndex < nums.size();fastIndex ++){
            if(val != nums[fastIndex]){
                nums[slowIndex++] = nums[fastIndex];
            }
        }
        return slowIndex;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值