把之前的刷题内容和笔记整理一波,前半部分
git链接
20.有效括号:
(1)使用list构造栈时进行了测试,空列表是不可以取值的,会报越界
(2)list可以直接用下标修改内容,可以很方便的做成栈,不需要栈元素大小统一
21.合并两个有序链表:
(1)实现了c语言的版本
26.移除有序链表里的重复元素
(1)类似len(xx)这样的,如果写在条件里,每次都会计算从而变慢
(2)这题一开始实现的解法写出了不必要的条件判断语句,写了4个版本。无意间发现for循环慢一些。查资料证实了这一点,但是当迭代对象已经存在时则是for快一点。参考资料
27.移除元素
(1)还是写了无用的判断条件,参见精选解法的双指针,只需要用两个指针将要求以外的元素向前写即可,但我想复杂了还利用了类似快排的前后交换法,着实没有必要
28.字符串匹配**
(1)学习了KMP算法的初步版本并实现之
(2)教材和网上材料的下标都是从1开始的,很长时间才反应过来并修改
35.查找插入位置
(1)使用二分查找结合递归实现
38. count and say
(1)算一道趣味题吧,比较简单,做的时候没有注意边界值处理浪费了一些时间
53.最大子序和
(1)动态规划版本中发现自己写的最大值求值不如直接利用自带函数max(),查了次啊可能是max()自身会进行一点优化
58.最后一个单词的长度
(1)如果从最后一个字母往回倒,需要考虑’ ‘这样的情况,因为这种情况下先去空格就会把字符串清空,再用索引就越界了。仅一个单词的例如’hello’也一样,因为只有一个词且没有空格,如果倒回时按照检查前面是否有空格就会越界
66.加一
67.二进制
二进制 (1)就是字符串处理,没什么难度
69.x的平方根
x的平方根 (1)二分查找,答案给了其他数学方法没有实现
70.爬楼梯
爬楼梯 (1)动态规划
83.删除排序链表中的重复元素
88.合并两个有序数组
合并两个有序数组 (1)在python下可以投机取巧,并且python可以用a[2:8] = b这种方式赋值 (2)即便变量名不变,例如传参叫nums1,在类中重新写了nums1 = xxxx,此时nums1也不是原来的nums1而是临时变量
100.判断二叉树是否相同
判断二叉树是否相同 (1)一开始写了前后续遍历,但是前后序都相同无法确定一个二叉树 (2)仅用循环结果无法判断[1,1]和[1,null,1]的区别 (3)后来在遇到空节点时也写入结果,此时只需要一种遍历即可 (4)直接使用递归判断更快
101.判断对称二叉树
判断对称二叉树 (1)一开始想用两个遍历对比,但是实际上行不通 (2)参考了官方的解法,在左右子树对称的扫描
104.二叉树深度
二叉树深度 (1)使用递归即可
2.两数相加
两数相加 (1)采用了死板的解法,然而在相加时,即便链表长度不相等,用空链表代替,就可以按照统一的方式循环处理,不需要分类讨论,可以减少代码量。参见题解里的别人的答案
3.无重复字符的最长子串
无重复字符的最长子串 (1)参考了官方解答,使用滑动窗口加hash集合
4.两个正序数组的中位数
两个正序数组的中位数 (1)取巧采用了拼接数组并sort,效果不错 (2)官方第一种方法log(m+n),第二种解答问题就没写
5.最长回文子串
最长回文子串 (1)参考了官方第一种解答动态规划
LCD_7 传递信息
传递信息 (1)典型的动态规划题
10.正则表达式
正则表达式 (1)比较难,作为dp非常典型
11.水桶装最多水
水桶装最多水 (1)贪心算法问题
15.三数之和
三数之和 (1)某次循环中删除了列表元素,后续循环会受影响 (2)一个很好的解释这个方法巧妙在,排序后判断,当nums[i]>0时可以直接返回了,因为后面不再有结果了 (3)题目使用了排序来减少循环的复杂度,我写的通俗方法复杂度太高(虽然已经通过下标递增减少了复杂度)
17.电话号码的字母组合
电话号码的字母组合 (1)题解花里胡哨,我用三个循环就做出来了且效果很好。非常简单不值得再看
19.删除倒数第n个链表
删除倒数第n个链表 (1)新建一个头指向链表头,可以使得操作更方便
22.生成括号
生成括号 (1)深度优先搜索,递归实现即可
19.合并K个升序链表
合并K个升序链表 (1)这题考察的应该是堆问题,但是pyhton直接提供了堆的实现,取巧了一下
31.下一个排列
下一个排列 (1)这题考察的知识点不太好归纳,直接看的参考答案,找到规律就很好做
32.最长有效括号
最长有效括号 (1)用:取列表范围,越界无影响 (2)自己尝试用栈实现失败了 (3)按照官方解答写了一下顺序逆序匹配和动态规划,官方的栈解答也很有意思,就没写了
617.合并二叉树
合并二叉树 (1)用递归实现很简单,也就是深度优先,广度优先有些麻烦。广度优先速度更快
33.搜索旋转数组
搜索旋转数组 (1)看了题解,觉得自己想多了,对于切割数组得到321456这种区间,根本无所谓内部是不是有增减,只要区间右端大于左端,就可以判断target在不在区间里就行了。
34.在排序数组中查找第一个和最后一个位置
在排序数组中查找第一个和最后一个位置 (1)二分查找微微改一下就行
39.组合总和
组合综合 (1)基本思路上来就对了,利用回溯,但是在减少循环次数上还是没想清楚,参考了别人的解答
29.除法
除法 (1)这题要注意的点就是对最小值先加一次才能使用绝对值继续处理 (2)使用移位进行除法的思路值得学习
46.全排列
全排列 (1)这题遇到了局部变量有效范围的问题
48.旋转图像
旋转图像 (1)总的来说就是在找规律
126.抛售股票
抛售股票 (1)一开始没处理好[]
55.跳跃游戏
跳跃游戏 (1)动态规划 (2)遇到了许多细节错误,并且可以用enumerate提高速度
56.合并区间
合并区间 (1)思路很容易,在实现方式上看了解答
42.接雨水
.接雨水 (1)按官方思路写的
110.判断平衡二叉树
判断平衡二叉树 (1)递归,利用类似后序遍历来递归
25.K个一组翻转链表
25.K个一组翻转链表 (1)思路看似很简单,写起来挺复杂的
155.最小栈
155.最小栈 (1)使用额外的辅助栈,也可以使用栈存储差值+额外的最小值
124.二叉树中的最大路径和
124.二叉树中的最大路径和 (1)官方解答很简洁,以某个点作为树得到的值判断下是否是最大值,继续向上传的时候只能加左右子树中的一个
199.二叉树的右视图
二叉树的右视图 (1)直接想到了利用特殊的层序遍历来实现 (2)deque比list快,因为deque实际上在移动指针
108.将有序数组转化为二叉搜索树
108.将有序数组转化为二叉搜索树 (1)比较简单,始终取中间值即可
236.二叉树的最近公共祖先
236.二叉树的最近公共祖先 (1)独立做出来了,一开始没考虑某一个节点即为父节点的情况
322.零钱兑换
322.零钱兑换 (1)暴力加剪枝效果极好,但是一开始自己写的剪枝条件不够好,参考了大佬的
205.反转链表
205.反转链表 (1)easy
215.第k大的数
215.第K大的数 (1)利用快排来实现
146.LRU缓存机制
146.LRU缓存机制 (1)参考了答案,利用字典作为hashmap结合双链表实现
102.二叉树层序遍历
102.二叉树层序遍历 (1)层序遍历,又一次使用了deque
518.零钱兑换2
518.零钱兑换2 (1)动态规划经典题,看了答案
剑指offer09.两个栈实现队列
剑指offer09.两个栈实现队列 (1)双栈倒腾,两个后进先出就变成了后进后出了
54.螺旋举证
54.螺旋矩阵 (1)判断条件中非零值都是True
1299.将每个元素替换为右侧最大元素
1299.将每个元素替换为右侧最大元素 (1)easy
105.从前序与中序遍历序列构造二叉树
105. 从前序与中序遍历序列构造二叉树 (1)利用递归,参考了答案下一个别人解答
160.相交链表
160.相交链表 (1)拼接链表法,别人的答案更简洁
139.单词拆分
139.单词拆分 (1)dp问题
230.二叉搜索树中第K小的数
230.二叉搜索树中第K小的数 (1) 结合dfs加剪枝,nonlocal和global辨析
剑指offer61.扑克牌中顺子
剑指offer61.扑克牌中顺子 (1)有很多细节需要注意
543.二叉树的直径
543.二叉树的直径 (1)递归就完事了,合理使用 外部变量
112.二叉树的路径总和
112.路径总和 (1)第一版有错误修了第二版,错误在于处理反馈的位置必须在叶节点
1143.最长公共子序列
1143.最长公共子序列 (1)二维动态规划问题,看的答案写的 (2)这是解答链接
141.环形链表
141.环形链表 (1)有hash表和快慢指针两种办法
515.在每个树行中找最大值表
515.在每个树行中找最大值表 (1)层序遍历改,利用了deque