代码随想录DAY1|Leetcode704.二分查找,27.移除元素

Leetcode704.二分查找

题目链接

704. 二分查找 - 力扣(LeetCode)

文章链接

代码随想录 (programmercarl.com)

视频讲解

手把手带你撕出正确的二分法 | 二分查找法 | 二分搜索法 | LeetCode:704. 二分查找_哔哩哔哩_bilibili

题目简述:

给定一个 n 个元素有序的(升序)整型数组 nums 和一个目标值 target  ,写一个函数搜索 nums 中的 target,如果目标值存在返回下标,否则返回 -1。

做题情况

1.看讲解前按照普通方法做了一遍,编译通过了

2.看讲解后按照二分法做了一遍,弄清楚了左闭右开和左闭右闭的区别,编译通过

总结

1.在做题提交记录那里看到两次编译的用时和内存消耗那里都差不多,不太理解为什么要学习二分法,直到看到这个人的评论觉得很有意思

2.我认为那个普通解法就是全部遍历一遍,时间复杂度为O(n),但是二分法的时间复杂度为O(logn),所以当测试数据比较大的话二分法的好处就体现出来啦。

Leetcode35.搜索插入位置

题目链接:35. 搜索插入位置 - 力扣(LeetCode)

文章链接:代码随想录 (programmercarl.com)

题目简述:

给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。

做题情况

1.按照之前学的二分法磕磕绊绊编译通过了

2.看了题解还学会了暴力解法,编译通过

总结

1.暴力解法纠结了好一会儿,直到看了代码,感觉if这里写的很妙,既可以处理目标值与数组元素相等的情况,又可以在目标值不等的情况下直接输出它的排序位置,又学到了

class Solution {
public:
    int searchInsert(vector<int>& nums, int target) {
        for (int i = 0; i < nums.size(); i++) {
        // 分别处理如下三种情况
        // 目标值在数组所有元素之前
        // 目标值等于数组中某一个元素
        // 目标值插入数组中的位置
            if (nums[i] >= target) { // 一旦发现大于或者等于target的num[i],那么i就是我们要的结果
                return i;
            }
        }
        // 目标值在数组所有元素之后的情况
        return nums.size(); // 如果target是最大的,或者 nums为空,则返回nums的长度
    }
};

2.二分法不小心把else if写成了第二个if,导致代码出错,下次注意。

Leetcode27.移除元素

题目链接: 27. 移除元素 - 力扣(LeetCode)

文章链接 :代码随想录 (programmercarl.com)

视频链接:数组中移除元素并不容易! | LeetCode:27. 移除元素_哔哩哔哩_bilibili

题目简述:给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度 

做题情况

1.用库函数erase做了一遍明明感觉没什么问题,但是编译错误,以下会写原因

2.暴力解法,就是删除一个元素,后面的元素全部左移一位,编译正确

3.看了题解的双指针法跟着写了一遍,编译正确

总结

1.其实直接用erase是可以解这道题的,以下是我出错的代码,乍一看没什么问题,但是编译某些用例的时候就会出错。

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        for(int i = 0; i < nums.size(); i++)
        {
            if(nums[i] == val)
            {
                auto iter = nums.erase(nums.begin() + i);
            }
        }
        return nums.size();
    }
};

比如nums = [0,1,2,2,3,0,4,2],val = 2。

输出结果应为[0,1,3,0,4]

但我的输出结果却是[0,1,2,3,0,4]

后面才发现原来删除2这个目标元素让所有后续元素左移时,i的数值不变即指针指向元素的位置已经是删除的那个2的后一个元素,但后续i++会跳过一个元素的判断,当两个目标值挨在一起的时候就会漏删一个,所以正确的写法要在erase下一行写i--

2.暴力解法就是删除目标元素后,所有后续元素全部左移,其实和erase的逻辑应该是一样的,但是需要定义一个size。前两种的做法时间复杂度都是O(n^2)

3.最后学会了很有用的双指针法!能够通过一个快指针和慢指针在一个for循环下完成两个for循环的工作。这两个指针分为快指针和慢指针。

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

这样的时间复杂度就只有O(n)了。

DAY1学习小结

        其实之前也有刷过一点点代码随想录的数组部分,但那个时候连vector是什么都理解不了,好在通过暑假搞车间调度的代码频繁用到数组,对数组这部分的知识没那么恐惧了,但是二分查找、双指针之类的知识对我来说还是陌生邻域,算是新鲜的挑战吧,希望这两个月能顺利把代码随想录刷完。加油!

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值