代码随想录数组链表总结(day1-day4)

数组

1.二分查找

习惯写左闭右闭,终止条件尽量放最前面,放后面有可能递归再经过一次处理就出不来了

顺序存储查找定位的题目优先想是否为二分查找的变形(二分查找的条件太苛刻了感觉,但是效果也很好,所以如果是顺序存储的话,尽量先想二分查找)

class Solution:
    def search(self, nums: List[int], target: int) -> int:
        def binary(low,high):
            if low>high:
                return -1
            mid=(low+high)//2
            tmp=nums[mid]
            if target==tmp:
                return mid
            elif target>tmp:
                return binary(mid+1,high)
            else:
                return binary(low,mid-1)
        return binary(0,len(nums)-1)

2.双指针

1.快慢指针目前见过的有俩种,一种是fast一直动,slow遇到特定条件才动,一种是fast和slow以不同的速度动,日后见过更多的再补充

2.还有一种双指针是左右俩段同时向中间逼近

3.滑动窗口

结果有着数据相邻的要求优先考虑滑动窗口

窗口初始化的逻辑一般与滑动的逻辑相同,所以初始化其实可以就放在滑动的逻辑里面写

满足条件就开滑,滑到不满足条件就再变(初始化就写在这个变里面)

最大滑动窗口模板

while j < len(nums):
    判断[i, j]是否满足条件
    while 不满足条件:
        i += 1 (最保守的压缩i,一旦满足条件了就退出压缩i的过程,使得滑窗尽可能的大)
    不断更新结果(注意在while外更新!)
    j += 1

最小滑动窗口模板

while j < len(nums):
    判断[i, j]是否满足条件
    while 满足条件:
        不断更新结果(注意在while内更新!)
        i += 1 (最大程度的压缩i,使得滑窗尽可能的小)
    j += 1

关键的区别在于,最大滑窗是在迭代右移右边界的过程中更新结果,而最小滑窗是在迭代右移左边界的过程中更新结果

链表

1.移除元素

1.给val删节点

移除头结点和移除其他节点的操作是不一样的,因为链表的其他节点都是通过前一个节点来移除当前节点,而头结点没有前一个节点。

所以头结点如何移除呢,其实只要将头结点向后移动一位就可以,这样就从链表中移除了一个头结点。(利用虚拟头节点就可以不用分开讨论了)

2.删倒数第n个节点

利用数组存储每个节点及其对应的序号然后删除

双指针,fast先跑n下,然后fast到终点时,slow就是要删的

2.反转链表

代码随想录数组链表总结(day1-day4)_第1张图片

3.两两交换节点代码随想录数组链表总结(day1-day4)_第2张图片

4.链表相交

AO+OC+BO=BO+OC+AO

代码随想录数组链表总结(day1-day4)_第3张图片

5.环形链表

fast是走两步,slow是走一步,其实相对于slow来说,fast是一个节点一个节点的靠近slow的,所以fast一定可以和slow重合。

如果有环,如何找到这个环的入口

此时已经可以判断链表是否有环了,那么接下来要找这个环的入口了。

假设从头结点到环形入口节点 的节点数为x。 环形入口节点到 fast指针与slow指针相遇节点 节点数为y。 从相遇节点 再到环形入口节点节点数为 z。 如图所示:

代码随想录数组链表总结(day1-day4)_第4张图片

那么相遇时: slow指针走过的节点数为: x + y, fast指针走过的节点数:x + y + n (y + z),n为fast指针在环内走了n圈才遇到slow指针, (y+z)为 一圈内节点的个数A。

因为fast指针是一步走两个节点,slow指针一步走一个节点, 所以 fast指针走过的节点数 = slow指针走过的节点数 * 2:

(x + y) * 2 = x + y + n (y + z)

两边消掉一个(x+y): x + y = n (y + z)

因为要找环形的入口,那么要求的是x,因为x表示 头结点到 环形入口节点的的距离。

所以要求x ,将x单独放在左面:x = n (y + z) - y ,

再从n(y+z)中提出一个 (y+z)来,整理公式之后为如下公式:x = (n - 1) (y + z) + z 注意这里n一定是大于等于1的,因为 fast指针至少要多走一圈才能相遇slow指针。

这个公式说明什么呢?

先拿n为1的情况来举例,意味着fast指针在环形里转了一圈之后,就遇到了 slow指针了。

当 n为1的时候,公式就化解为 x = z

这就意味着,从头结点出发一个指针,从相遇节点 也出发一个指针,这两个指针每次只走一个节点, 那么当这两个指针相遇的时候就是 环形入口的节点

你可能感兴趣的:(链表,算法,数据结构,python)