算法训练营03-数组链表

本文探讨了编程中的常见问题,如容器装水、移动零、爬楼梯等经典算法,强调了在循环和逻辑处理中的边界条件检查。同时,讲解了如何通过双指针解决数组问题,如排序数组去重、数组旋转。在链表操作中,介绍了翻转链表、两两交换节点以及环的检测。此外,提出了复杂问题的拆解策略,以助于更有效地解决问题。文章还提醒读者尽量避免修改输入参数,以免产生意外的副作用。
摘要由CSDN通过智能技术生成

实战题目

Array 题目
容器装水
移动零
爬楼梯
3sum  (高频老题) 这题需要反复练习,问题很多

Linked List 实战题目
翻转链表
两两交换链表节点
链表中的环判断
链表中的环判断02
每k个一组翻转 : 这个要多做两遍,搞清楚需要的状态,

课后作业
排序数组中移除重复元素
数组旋转
有序list merge
有序array merge
2sum
移动零
加一操作

技巧,在for循环或者while循环中,有些情况下先执行业务逻辑再判断,可能更加合理

空间换时间,升维来降低复杂度

思考

1.仔细check那些非常规的迭代

当写出了不是正常的循环模式的时候一定要仔细检验自己的边界条件是否是正确的,比如这里
使用的是+1的模式,和平时的减一有很大的区别,导致没法向后面多走一步,走到想要的位置,这个时候很容易犯错误

if height[left] < height[right]:
                while left < right and height[left+1] <= height[left]:
                    left=left+1
                left=left+1  # 最开始没有写
            else:
                while left<right and height[right-1]<=height[right]:
                    right= right-1
                right=right-1

2.逻辑的合并导致了边界条件的失效

这里在写代码的时候发现可以进行逻辑合并,但是最最开始思考的时候并没有做逻辑合并,导致代码的边界检查出错

        while right < length and left <= right:

最开始写成了下面没有等号的,因为最开始的思考是left指向最左边的0,right指向left之后的第一个非零,所以left不会等于right,但是代码不容易写,逻辑合并之后变得简洁了,但是却没有修改边界条件

        while right < length and left < right:

3. 尽量不要修改入参

在修改入参之后有时候产生了复用,发生非常大的副作用,这里
最开始是直接操作的k,但是下面也用到了k,于是就产生了非常大的副作用。。。

 while c > 0 :

4.复杂问题拆解

有时候有些问题是单存的复杂,并不是没有思路的那种,这种问题贸然下笔可能就容易出错,需要按照下面的思路来进行拆解
复杂问题拆解为子问题

  1. 子问题解决需要哪些变量,解决什么问题
    1. 子串的开头(变量)
    2. 内部的反转 (问题)
  2. 合并子问题的时候需要哪些变量
    1. 两个子串之间的连接 (问题)
    2. 上一个子串的结尾+当前子串的开始+当前子串的结尾+下一个子串的开始

5.合并逻辑有可能可以优化边界的检查

合并逻辑有可能可以优化边界的检查,就像移动0一样,如果按照常规的思路,肯定是想着left要是左边的第一个0,right要到left后的第一个非零,这样就会多出一些边界check的代码,但是逻辑合并之后可能反而这些都不需要做了。挺有意思的。官方给的答案也是直接就是一个逻辑合并的答案,感觉还是需要多学习才行。
https://leetcode-cn.com/submissions/detail/308472794/

class Solution:
    def moveZeroes(self, nums: List[int]) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        # 可以使用双指针,左边的指针指向0,右边的指向非零,一旦遇到非零就left复制,然后前进
        # 感觉这个边界还是有点不容易,为了避免初始边界处理的问题,所以合并了逻辑
        left = 0
        for right in range(len(nums)) :
            if nums[right] != 0 :
                nums[left] = nums[right]
                left += 1
        for i in range(left,len(nums)) :
            nums[i] = 0

        
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值