leetcode刷题学习之路

本文深入探讨LeetCode中的二分查找技巧,包括循环条件、指针操作,并通过实例解析不同题型的应用。同时,讲解动态规划的倒序遍历策略,避免重复计算,提升解题效率。涉及数组、链表、哈希表、栈与队列等多个数据结构的实战应用。
摘要由CSDN通过智能技术生成

leetcode题型

2021【10.4】二分查找
循环条件left <=right
所以①结束条件一定是 left>right
②取中间指针
③根据条件 设置左右指针
结束情况 left = right+1
一定会有左右指针动
2023【3.12】
新的理解
①因为查询区间两端都是闭的[left,right]
因此当left=right时,两端相等闭区间也是存在1个值 因此循环下去的条件一定是left <=right
②因为之前区间是闭的,所以下一次要取的left = mid+1 right = mid-1
③中间值mid=(left+right)//2=(right-left)//2+left
2022【10.5】双指针
慢指针low
快指针fast
1.在做数组元素移动时,low一般是用来存放位置的标号
【11.5】滑动窗口
【10.24】位运算
判断是否为2的指数次方
n&(n-1)==0
因为2的次方最高位为1其余所有位是0 比2的次方小1的除了第一位是0其余全是1

一、数组

2022【7.20】
485最大连续1的个数
(遍历)
【7.21】
283移动零
(双指针 可以原地更改数组)
27移除元素
(双指针 相当于把val移动到最后)
【7.22】
剑指offer_03数组中重复的数字
(重复这个字眼–>哈希表)(技巧:因为把数当成索引的话,那么在数组中就有唯一一个属于它的位置 当一个位置出现两个元素时 就可得到重复的数)
【7.23】
2319 判断矩阵是否是一个 X 矩阵
(反对角线元素性质:i+j=n-1)
599 两个列表的最小索引总和
(相同的字眼:哈希表)
【7.24】
674 最长连续递增序列
(双指针可针对数组原地操作)

二、链表

【7.25】
剑指 Offer 04 二维数组中的查找
(因为数组是有序的,因此把它旋转45°能够得到类似于排序二叉树形式)
203 移除链表元素
(遍历)
【7.26】
剑指 Offer 18 删除链表的节点
(遍历)
剑指 Offer 06 从尾到头打印链表
(反过来的操作字眼:栈或递归)
206 反转链表
(双指针 改变相邻两个节点的方向)
【7.27】
剑指 Offer 22 链表中倒数第k个节点
(倒数K的位置是正数n-k)(双指针中间差K; 快的走到尾,慢的到倒数K位置)
【7.28】
剑指 Offer 25 合并两个排序的链表
(创建假头结点辅助判断大小,当做新链表往后添加元素)
【7.29】
19删除链表的倒数第 N 个结点
(同offer_22题,设置双指针差N个位置;再创建伪头结点让cur指向要删除节点前一个方便删除操作:cur.next=cur.next.next)
24 两两交换链表中的节点
(pre指向假头结点,双指针指向要交换节点:
①pre.next=node2
②node1.next=node2.next
③node2.next=node1
④ pre=node1;node1=node1.next;node2=node1.next.next)
【7.30】
160相交链表
(通过双指针转换成路程相遇问题:建立路程等式,相遇点即是相交点)
141环形链表
(同160题;通过快慢双指针转换成相遇问题)
【8.1】
707设计链表
(通过实现addindex来实现addhead(index=0)和addtail(index=size))

三、哈希表

【8.2】
217存在重复元素
(1.直接遍历时间复杂度太高,因此可以先排序,这样相同的数字就会出现在相邻)
(2.使用集合可实现查找快;或者使用字典利用数值当索引建立哈希表可实现查找快)
刷题知识点:判断某元素是否存在用set
【8.3】
242有效的字母异位词
(1.遍历取到各字符,排序后顺序比较每位)
(2.利用哈希表,哈希规则是一共26个字母建立26个索引)
【8.4】
349两个数组的交集
从此后用python3刷题就要利用其特性(掌握题目解题),用C++再强化底层(已掌握解题方法前提)
(1.建立哈希表 哈希规则 利用数值本身作为索引)
(2.遍历判断nums1元素在nums2中,同时不在results中)
(3.利用python中set直接消掉重复元素)
【8.5】
202快乐数
(1.循环停止条件,当n=1或者n重复出现时;不会出现无限增大循环的情况,因为999的下一个数变小了)
(2.每次得到下一个数,可以理解为链表;如果有重复数出现那么链表就会出现环,因此可以通过双指针判断环有没有出现)
【8.6】
1两数之和
(1.双重循环查找)
(2.解题关键点target-x 在不在nums,然后建立哈希表将第二重循环查找变为O1复杂度)
语法知识点:sorted()拷贝原数组后返回、某元素在不在哈希表可同时判断key和val
【8.7】
15三数之和
(排序后使用双指针可降低复杂度,相当于循环一层遍历2个数)
【8.8】
18四数之和
(排序加一层循环 同时判断一下第一层的去重)
【8.9】
454四数之和2
(1.nums1+nums2变为一个哈希表;以相加和作为key,以出现次数作为val;复杂度有效降低)
(2.利用python Collections.Conter直接统计nums1+nums2相加和出现次数)
语法知识点:列表解析可以同时遍历两个数组 collections.counter可直接统计次数
383赎金信
(同242题;利用counter可替代列表建立哈希表操作)
语法知识点:两个counter可直接作差得到相差key以及val
【8.10】
705设计哈希集合
(1.用空间换时间,设置一个超大数组,以元素本身当做key)
(2.用哈希函数构建set,用拉链法解决哈希冲突
①二维数组构建 第一维是桶buckets的个数,第二维是桶的大小 优点:查找快 ;缺点:需要预知数的范围
②链表构建 哈希函数设置为一个质数 优点:需要预知数的范围 ;缺点:桶内查找为遍历)

四、栈与队列

【8.11】
20有效的括号
(利用栈匹配,最先配对的是最后一个左括号)
(利用python特性字符串的replace将‘[]’等替代)
语法知识点:key在字典中,val不在
【8.12】
1047移动相邻相同的元素
(同20题 利用栈)
语法知识点:字符串反转切片法[::-1] 或者转成list再调reverse()
【8.13】
150逆波兰表达式
(利用栈 遇到表达式取出栈中两个数)
语法知识点:int()向下取整 round()四舍五入 ceil()向上取整
除法 “/” 是浮点除法, “-3 / 2 = -1.5” 地板除 “//” 是整数除法, “-3 // 2 = -2”
eval(“1*2”)可直接计算得数
【8.14】
1614 括号的最大嵌套深度
(利用栈匹配)
语法知识点:ans=max(以前最大值,现在传入值)可节省内存空间
【8.15】
496下一个更大元素1
(1.暴力遍历)
(2.单调栈+哈希表:使用单调栈从后往前遍历nums2,每次判断是否进栈 能够得到当前元素是否有比它大的值;例如示例1中4这个元素就直接到了栈底因此哈希表记录它的val就是-1;示例1中3这个元素判断进栈时到不了栈底 因此哈希表记录它的val 就是栈的下一个元素4)
语法知识点:A = Y if X else Z(如果X为真A=Y,否则A=Z)
【8.16】
1475商品折扣后的最终价格
(1.双重暴力遍历)
(2.单调栈:使用单调栈从前往后遍历prices,可以解决几个数字共有一个较小的折扣 例如:2,3,4,5,1 栈中会积累2,3,4,5遇到1时会出栈判断是不是栈底元素小于1。结果全部大于1,也就只找了一遍1就找到了2345的公共解)
【8.18】
387字符串中的第一个唯一字符
(1.使用collections.Counter)
(2.用队列)
8.19开始处理论文
【8.20】
1700无法吃午餐的学生数量
(1.查询三明治对应在不在学生队伍中)
【8.22】
2073买票需要的时间
(k之前最大k次 k之后最大k-1次)
【8.23】
344反转字符串
【8.25】
541反转字符串II
【8.27】
剑指offer 05替换空格
(双指针)
【8.28】
剑指 Offer 58 - II 左旋转字符串
(技巧:反转前n 反转n到最后 反转全部)
【8.30】
28 strStr()
(KMP匹配 )

五、二分查找

【2023.3.12】
35 搜索插入位置
二分查找只能查找到target在不在逐渐缩小的区间
当区间中查找不到target有三种情况,都可以right+1
①没有target值 right<left自然退出循环 插入在right+1的位置
②target在整个nums的最左边 right=-1退出循环
③target在整个nums的最右边 left跑到n+1位置>right 自然退出循环
【2023.4.1】双指针结束

六、动态规划

6.1倒序遍历是为了保证物品i只被放入一次!。但如果一旦正序遍历了,那么物品0就会被重复加入多次!

举一个例子:物品0的重量weight[0] = 1,价值value[0] = 15
如果正序遍历
dp[1] = dp[1 - weight[0]] + value[0] =dp[0]+15=0+15= 15
dp[2] = dp[2 - weight[0]] + value[0] =dp[1]+15=15+15= 30
此时dp[2]就已经是30了,意味着物品0,被放入了两次,所以不能正序遍历。

为什么倒序遍历,就可以保证物品只放入一次呢?
倒序就是先算dp[2]
dp[2] = dp[2 - weight[0]] + value[0] =dp[1]+15=0+15= 15 (dp数组已经都初始化为0)
dp[1] = dp[1 - weight[0]] + value[0] =dp[0]+15=0+15= 15

6.2先遍历物品再遍历背包容量得到的是组合数;先遍历背包容量再遍历物品得到的是排列数。

ACM模式学习

ACM的输入为单行时
a, b = [int(i) for i in input().split()]

多行时
 input()输入后进行split()按照空格分为每个元素添加进list
list = []
for i in range(行数):
    list.append([int(i) for i in input().split()])
print(list)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bu volcano

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值