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

一、数组理论基础

文章链接:

知识点总结:

1. 数组在内存中的存储方式:

数组是存储在连续的内存空间相同类型数据的集合。通过下标索引获取下标对应的数据。 

2. 注意:1)下标从0开始;2)数组内存空间的地址连续

因为数组在内存空间地址连续,所以在增删元素的时候,需要移动其他元素的地址

3. 数组元素不可以删除,只能覆盖。

二、704.二分查找

题目链接:704. 二分查找 - 力扣(LeetCode)

文章链接:代码随想录

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

1. 看到题目的第一想法:

没有注意到题目要求使用二分查找,于是打算使用暴力解法,即按索引遍历数组每一个元素,如果元素等于target,则返回其下标。

2. 看完代码随想录的想法:

二分查找需要涉及到Python中的双指针问题:

左闭右闭区间法:

        1)初始化左指针left和右指针right,使其分别指向数组的头元素下标、尾元素下标;

        2)写while循环防止指针溢出,即左指针如果大于右指针就跳出循环;

        3)写出中间指针middle的更新公式:middle = left + (right - left) // 2 或者 middle = (left+right) // 2

                更加推荐第一个公式的写法,如果left和right非常大容易发生整数溢出,而公式一因为先计算出差值,所以相对更加安全。

                注意:指针指向的是下标索引,是整数类型,所以不能(左指针+右指针)/2

        4)比较middle对应的数组元素与target二者的大小:

                如果target等于该元素,则返回的下标就是middle;

                如果target大于该元素,说明target在右区间内,那么将left指针移动到middle+1处;

                如果target小于该元素,说明target在左区间内,那么将右指针移动到middle-1处;

        5)最后如果循环结束没有找到目标值,则返回-1。

左闭右开区间法:

注意更新右区间时,使其等于middle,其余同上。

3. 实现过程中遇到的困难:

        1)循环函数使用混乱

        2)指针定义模糊不清

        3)刻意区分元素个数的奇偶,导致代码逻辑复杂

        4)没有考虑抛出异常、以及指针溢出的情况

4. 今日收获:

1. Python双指针:

        1)对撞指针:一个从头到尾,一个从尾到头,相向而行-->left = 0, right = len(nums)-1

        2)快慢指针:一个指针移动速度快、一个指针移动速度慢,常用于环形链表-->fast, slow

2. Python循环体:

三、27.移除元素

1. 看到题目的第一想法:

        1)暴力解法:

        遍历数组每一个元素,如果发现其等于val,则循环后面的元素依次向前覆盖,每遇到一个等于val的元素就循环一次;

        但是不知道如何统计不等于val元素的数组大小,因为覆盖不会删除原来的元素,所以数组大小并没有改变,无法返回移除元素后的数组大小。

        2)快慢指针法:

        用快指针遍历数组每个元素,遇到元素等于val的值则continue跳过,遇到不等于val的值则将其放入新数组,最后统计新数组的大小并返回。

2. 看完代码随想录的想法:

        1)初始化快慢指针均指向数组索引0的位置,并且设置数组大小size = len(nums)

        2)以指针是否溢出作为循环条件,若快指针大于数组大小则跳出循环

        3)比较快指针指向元素是否等于val:                

                若不等于则慢指针+1;

                若等于则慢指针不变。

                一次循环结束快指针无论如何也+1,继续遍历下一个元素的值,并进行比较。

        4)最后返回慢指针的数值即可。

3. 实现过程中遇到的困难:

        1)不会灵活利用指针将其作为一个计数工具,只想到将它作为下标索引使用

        2)快慢指针使用时需要防止指针溢出数组长度,要对其进行size设置与限定

四、977.有序数组的平方

1. 看到题目的第一想法:

        使用对撞指针,初始化左指针和右指针分别在数组的头和尾,然后以左指针小于等于右指针为循环终止条件进入循环,然后比较头尾指针指向的元素平方的大小,选取值较大的优先纳入新数组。

2. 看完代码随想录的想法:

        1)设置对撞指针,初始化使其分别指向数组的头和尾;设置新数组的指针,指向数组尾部;

定义存放元素的新数组。

        2)以左指针小于等于右指针为循环终止条件进入循环。

        3)比较头尾指针指向的元素大小:

                如果left指针指向的元素平方更大,则将其加入新数组,并且左指针向右移动一位;

                如果right指针指向的元素平方更大,则将其加入新数组,并且右指针向左移动一位。

                一次循环结束,新数组的指针向左移动一位。

        4)最后返回新数组的大小。

3. 实现过程中遇到的困难:

        1)不知道如何定义新数组及其新指针:

res = [float('inf')] * len(nums)

        2)新指针的元素存放应该是从后往前、从大到小。

        3)左右指针完成循环一次的移动方向并不一样。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值