目录

数据结构与算法

面试注意点

练习

链表

基本技能

常见题型

​83. 删除排序链表中的重复元素:remove-duplicates-from-sorted-list​

​82. 删除排序链表中的重复元素 II remove-duplicates-from-sorted-list-ii​

​206. 反转链表:reverse-linked-list​

​92. 反转链表 II:reverse-linked-list-ii​

​21. 合并两个有序链表merge-two-sorted-lists​

​86. 分隔链表:partition-list​

​148. 排序链表sort-list​

​143. 重排链表reorder-list​

​141. 环形链表linked-list-cycle​

142 ​环形链表 Ⅱ linked-list-cycle-ii​

​234. 回文链表palindrome-linked-list​

​138. 复制带随机指针的链表copy-list-with-random-pointer​

总结

练习

1. 两数之和

2. 两数相加

26. 删除排序数组中的重复项

160 相交链表(easy)

19 删除链表的倒数第N个结点(medium)

203 移除链表元素(easy)

328 奇偶链表

430 扁平化多级双向链表

61 旋转链表(medium)


算法快速入门

数据结构与算法

数据结构是一种数据的表现形式,如链表、二叉树、栈、队列等都是内存中一段数据表现的形式。 算法是一种通用的解决问题的模板或者思路,大部分数据结构都有一套通用的算法模板,所以掌握这些通用的算法模板即可解决各种算法问题。

后面会分专题讲解各种数据结构、基本的算法模板、和一些高级算法模板,每一个专题都有一些经典练习题,完成所有练习的题后,你对数据结构和算法会有新的收获和体会。

先介绍两个算法题,试试感觉~

示例 1

​strStr​

给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从 0 开始)。如果不存在,则返回 -1。

思路:核心点遍历给定字符串字符,判断以当前字符开头字符串是否等于目标字符串

需要注意点
  • 循环时,i 不需要到 len-1

  • 如果找到目标字符串,len(needle)==j

示例 2

​subsets​

给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。

思路:这是一个典型的应用回溯法的题目,简单来说就是穷尽所有可能性,算法模板如下

通过不停的选择,撤销选择,来穷尽所有可能性,最后将满足条件的结果返回

说明:后面会深入讲解几个典型的回溯算法问题,如果当前不太了解可以暂时先跳过

面试注意点

我们大多数时候,刷算法题可能都是为了准备面试,所以面试的时候需要注意一些点

  • 快速定位到题目的知识点,找到知识点的通用模板,可能需要根据题目特殊情况做特殊处理

  • 先去朝一个解决问题的方向!先抛出可行解,而不是最优解!先解决,再优化!

  • 代码的风格要统一,熟悉各类语言的代码规范。

    • 命名尽量简洁明了,尽量不用数字命名如:i1、node1、a1、b2

  • 常见错误总结

    • 访问下标时,不能访问越界

    • 空值 nil 问题 run time error

练习

  • ​strStr​

  • ​subsets​

链表

基本技能

链表相关的核心点

  • null/nil 异常处理

  • dummy node 哑巴节点

  • 快慢指针

  • 插入一个节点到排序链表

  • 从一个链表中移除一个节点

  • 翻转链表

  • 合并两个链表

  • 找到链表的中间节点

常见题型

​83. 删除排序链表中的重复元素:remove-duplicates-from-sorted-list​

83. 删除排序链表中的重复元素:模拟题,直接遍历链表,遇到重复值的节点删除即可。

给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。

83. 删除排序链表中的重复元素#直接法:
这是一个简单的问题,仅测试你操作列表的结点指针的能力。由于输入的列表已排序,
# 因此我们可以通过将结点的值与它之后的结点进行比较来确定它是否为重复结点。
# 如果它是重复的,我们更改当前结点的 next 指针,
# 以便它跳过下一个结点并直接指向下一个结点之后的结点。解法https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list/solution/hua-jie-suan-fa-83-shan-chu-pai-xu-lian-biao-zhong/
图解https://pic.leetcode-cn.com/c61a88b9fe012a9b85b842f4a12a5310c96b462ea4801e6227fc6a04aa140351-frame_00001.png# Python3
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:def deleteDuplicates(self, head: ListNode) -> ListNode:cur=headwhile cur and cur.next:if cur.val==cur.next.val:cur.next=cur.next.nextelse:cur=cur.nextreturn head# 输入      输出
# [1,2,2]   [1,2]
# [1,1,1]   [1]# 复杂度分析
# 时间复杂度:O(n),因为列表中的每个结点都检查一次以确定它是否重复,
# 所以总运行时间为 O(n),其中 n 是列表中的结点数。
# 空间复杂度:O(1),没有使用额外的空间。# 此题需要返回一个没有重复元素的新链表,因为没有链表没有下标,
# 如果使用「双指针」(双引用),后面覆盖前面,可行。
# 但返回新链表,实现起来比较复杂。
# 此题可借助链表的特性「指针」(Pointer)来实现。
# 如果当前节点的值等于下一个节点的值,指向下下个节点(跳过下一个节点),
# 引用 head 并后移一位。

​82. 删除排序链表中的重复元素 II remove-duplicates-from-sorted-list-ii​

82. 删除排序链表中的重复元素 II:模拟题,遍历链表,若head的节点值与head的next节点值不相等,则pre指向head,也就是不重复节点;若相等,我们需要找到重复值子链表的最后一个节点,然后令pre指向head->next,同时head移动到下一个节点。

思路:链表头结点可能被删除,所以用 dummy node 辅助删除

给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现的数字。

示例 1:
输入: 1->2->3->3->4->4->5
输出: 1->2->5

示例 2:
输入: 1->1->1->2->3
输出: 2->3

解法二

https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list-ii/solution/san-chong-jie-fa-duo-tu-zhan-shi-82-shan-chu-pai-x/

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution(object):def deleteDuplicates(self, head):if not (head and head.next):return headdummy = ListNode(-1)dummy.next = heada = dummyb = headwhile b and b.next:# 初始化的时a指向的是哑结点,所以比较逻辑应该是a的下一个节点和b的下一个节点if a.next.val!=b.next.val:a = a.nextb = b.nextelse:# 如果a、b指向的节点值相等,就不断移动b,直到a、b指向的值不相等 while b and b.next and a.next.val==b.next.val:b = b.nexta.next = b.nextb = b.nextreturn dummy.next

206. 反转链表:reverse-linked-list​

206. 反转链表:双指针法,指针pre用来表示前驱节点,指针cur用来遍历链表,每次循环改变将pre->cur的方向改变为pre<-cur,直到遍历结束。

反转一个单链表。

思路:用一个 prev 节点保存向前指针,temp 保存向后的临时指针

https://leetcode-cn.com/problems/reverse-linked-list/solution/dong-hua-yan-shi-206-fan-zhuan-lian-biao-by-user74/

https://mp.weixin.qq.com/s?__biz=MzAxODQxMDM0Mw==&mid=2247484467&idx=1&sn=beb3ae89993b812eeaa6bbdeda63c494&chksm=9bd7fa3baca0732dc3f9ae9202ecaf5c925b4048514eeca6ac81bc340930a82fc62bb67681fa&scene=21#wechat_redirect

双指针迭代
用 O(1) 空间复杂度来实现这道题。class Solution(object):def reverseList(self, head):""":type head: ListNode:rtype: ListNode"""# 申请两个节点,pre和 cur,pre指向Nonepre = Nonecur = head# 遍历链表,while循环里面的内容其实可以写成一行# 这里只做演示,就不搞那么骚气的写法了while cur:# 记录当前节点的下一个节点tmp = cur.next #相当于赋值# 然后将当前节点指向precur.next = pre  #相当于指向# pre和cur节点都前进一位pre = curcur = tmpreturn pre 
递归解法:
class Solution(object):def reverseList(self, head):""":type head: ListNode:rtype: ListNode"""# 递归终止条件是当前为空,或者下一个节点为空if(head==None or head.next==None):return head# 这里的last就是最后一个节点last = self.reverseList(head.next)head.next.next = head# 防止链表循环,需要将head.next设置为空head.next = None# 每层递归函数都返回last,也就是最后一个节点return last
#输入一个节点head,将“以head为起点”的链表反转,并返回反转之后的头结点
def reverse(self,head):#反转整个链表if not head or not head.next:return headlast = self.reverse(head.next)head.next.next = headhead.next = Nonereturn last

​反转前N个链表是:

#反转链表前N个节点
def reverseN(self,head,n):if n == 1:# 记录第 n + 1 个节点succeessor=head.nextreturn head# 以 head.next 为起点,需要反转前 n - 1 个节点last = self.reverseN(head.next,n-1)# 让反转之后的 head 节点和后面的节点连起来head.next.next = headhead.next = successorreturn last

92. 反转链表 II:reverse-linked-list-ii​

92. 反转链表 II:双指针法,指针pre指针指向m的前驱节点,用来将cur的next节点插入到pre后面,指针cur指向位置m起始节点,该节点保持不变,每次需要将cur连接上nxt后边的部分。换句话说,我们要将[m+1,n]的节点每次都要插到位置m之前,这样就完成了反转。

反转从位置 mn 的链表。请使用一趟扫描完成反转。

思路:先遍历到 m 处,翻转,再拼接后续,注意指针处理

# recurse 递归
# Reverse 反转,颠倒
回溯法(Backtrcking)
读音huí sù,也叫试探法,它是一种系统地搜索问题的解的方法,是一种思想。
有一类问题,我们不知道它明确的计算法则。而是先进行试探,试探到最终状况,发现不满足问题的要求,则回溯到上一个状态继续试探。这种不断试探和回溯的思想,称为回溯法(Backtrcking)
这类问题有求最优解、一组解、求全部解这类问题,例如八皇后问题
【回溯的算法思想】一直往下走,然后再一步步往回走
面对一个问题,每一步有多种做法。先做其中一个做法,然后再此基础上一直做下去,把这个做法的所有可能全部做完,再回来,做第二种做法。

【例子】

深度优先搜索
求一个序列的幂集
八皇后问题
涂色问题

【回溯法实质】它的求解过程实质上是先序遍历一棵“状态树”的过程。
只不过,这棵树不是遍历前预先建立的,而是隐含在遍历过程中。
如果认识到这点,很多问题的递归过程设计也就迎刃而解了。
https://blog.csdn.net/summer_dew/article/details/83921581

解法:

https://leetcode-cn.com/problems/reverse-linked-list-ii/solution/fan-zhuan-lian-biao-ii-by-leetcode/

方法一: 递归
# 说明:
# 1 ≤ m ≤ n ≤ 链表长度。# 示例:# 输入: 1->2->3->4->5->NULL, m = 2, n = 4
# 输出: 1->4->3->2->5->NULL# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = Noneclass Solution:def reverseBetween(self, head, m, n):#递归if m == 1:return self.reverseN(head,n)head.next = self.reverseBetween(head.next,m-1,n-1)return head#反转链表前N个节点def reverseN(self,head,n):if n == 1:# 记录第 n + 1 个节点succeessor=head.nextreturn head# 以 head.next 为起点,需要反转前 n - 1 个节点last = self.reverseN(head.next,n-1)# 让反转之后的 head 节点和后面的节点连起来head.next.next = headhead.next = successorreturn last下面的看不懂class Solution:def reverseBetween(self, head: ListNode, m: int, n: int) -> ListNode:""":type head: ListNode:type m: int:type n: int:rtype: ListNode"""if not head:return Noneleft, right = head, headstop = Falsedef recurseAndReverse(right, m, n):nonlocal left, stop# base case. Don't proceed any furtherif n == 1:return# Keep moving the right pointer one step forward until (n == 1)right = right.next# Keep moving left pointer to the right until we reach the proper node# from where the reversal is to start.if m > 1:left = left.next# Recurse with m and n reduced.recurseAndReverse(right, m - 1, n - 1)# In case both the pointers cross each other or become equal, we# stop i.e. don't swap data any further. We are done reversing at this# point.if left == right or right.next == left:stop = True# Until the boolean stop is false, swap data between the two pointers     if not stop:left.val, right.val = right.val, left.val# Move left one step to the right.# The right pointer moves one step back via backtracking.left = left.next           recurseAndReverse(right, m, n)return head
方法二: 迭代链接反转:
复杂度分析
时间复杂度: O(N)。考虑包含 N 个结点的链表。对每个节点最多会处理(第 n个结点之后的结点不处理)。
空间复杂度: O(1)。我们仅仅在原有链表的基础上调整了一些指针,只使用了 O(1)的额外存储空间来获得结果。
class Solution:def reverseBetween(self, head, m, n):""":type head: ListNode:type m: int:type n: int:rtype: ListNode"""# Empty listif not head:return None# Move the two pointers until they reach the proper starting point# in the list.cur, prev = head, Nonewhile m > 1:prev = curcur = cur.nextm, n = m - 1, n - 1# The two pointers that will fix the final connections.tail, con = cur, prev# Iteratively reverse the nodes until n becomes 0.while n:third = cur.nextcur.next = prevprev = curcur = thirdn -= 1# Adjust the final connections as explained in the algorithmif con:con.next = prevelse:head = prevtail.next = curreturn head

​25. K 个一组翻转链表

给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。

k 是一个正整数,它的值小于或等于链表的长度。

如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。

示例:

给你这个链表:1->2->3->4->5

当 k = 2 时,应当返回: 2->1->4->3->5

当 k = 3 时,应当返回: 3->2->1->4->5

https://mp.weixin.qq.com/s?__biz=MzAxODQxMDM0Mw==&mid=2247484597&idx=1&sn=c603f1752e33cb2701e371d84254aee2&chksm=9bd7fabdaca073abd512d8fff18016c9092ede45fed65c307852c65a2026d8568ee294563c78&scene=21#wechat_redirect

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:# 翻转一个子链表,并且返回新的头与尾def reverse(self, a :ListNode, b: ListNode):pre=Nonecur=a        while cur != b:third = cur.nextcur.next = prepre = curcur = thirdreturn pre    def reverseKGroup(self, head: ListNode, k: int) -> ListNode:if head==None:return Nonea=b=headfor i in range(k):# 不足 k 个,不需要反转,base caseif b == None:return headb = b.next#  反转前 k 个元素   newhead=self.reverse(a,b)#  递归反转后续链表并连接起来a.next=self.reverseKGroup(b,k)return newhead

21. 合并两个有序链表merge-two-sorted-lists​

21. 合并两个有序链表:模拟题,每次循环比较l1->vall2->val,若l1->val<l2->val,则在cur后面添加l1;否则在cur后面添加l2

将两个升序链表合并为一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

思路:通过 dummy node 链表,连接各个元素

21. 合并两个有序链表
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 示例:输入:1->2->4, 1->3->4
输出:1->1->2->3->4->4链接:https://leetcode-cn.com/problems/merge-two-sorted-lists/solution/he-bing-liang-ge-you-xu-lian-biao-by-leetcode-solu/方法二:迭代
复杂度分析
时间复杂度:O(n + m) ,其中 n 和 m 分别为两个链表的长度。因为每次循环迭代中,l1 和 l2 只有一个元素会被放进合并链表中, 因此 while 循环的次数不会超过两个链表的长度之和。所有其他操作的时间复杂度都是常数级别的,因此总的时间复杂度为 O(n+m)O(n+m)。
空间复杂度:O(1) 。我们只需要常数的空间存放若干变量。# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:prehead = ListNode(-1)cur = preheadwhile l1 and l2:if l1.val <= l2.val:cur.next = l1l1 = l1.nextelse:cur.next = l2l2 = l2.next            cur = cur.next# 合并后 l1 和 l2 最多只有一个还未被合并完,我们直接将链表末尾指向未合并完的链表即可cur.next = l1 if l1 is not None else l2return prehead.next方法一:递归
复杂度分析
时间复杂度:O(n + m),其中 n 和 m 分别为两个链表的长度。因为每次调用递归都会去掉 l1 或者 l2 的头节点(直到至少有一个链表为空),函数 mergeTwoList 至多只会递归调用每个节点一次。因此,时间复杂度取决于合并后的链表长度,即 O(n+m)O(n+m)。
空间复杂度:O(n + m),其中 n 和 m 分别为两个链表的长度。递归调用 mergeTwoLists 函数时需要消耗栈空间,栈空间的大小取决于递归调用的深度。结束递归调用时 mergeTwoLists 函数最多调用 n+mn+m 次,因此空间复杂度为 O(n+m)O(n+m)。class Solution:def mergeTwoLists(self, l1, l2):if l1 is None:return l2elif l2 is None:return l1elif l1.val < l2.val:l1.next = self.mergeTwoLists(l1.next, l2)return l1else:l2.next = self.mergeTwoLists(l1, l2.next)return l2

​86. 分隔链表:partition-list​

86. 分隔链表:双指针法

before_head链表存放比x小的节点,after_head链表存放比x大于或等于的节点,我们分别用before和after来前面两个链表添加节点,用head来遍历原始链表。当原始链表遍历完成时,我们需要将before_head链表连接上after_head链表,即before->next=after_head->next;after->next=nullptr;。

给定一个链表和一个特定值 x,对链表进行分隔,使得所有小于 x 的节点都在大于或等于 x 的节点之前。

思路:将大于 x 的节点,放到另外一个链表,最后连接这两个链表

哑巴节点使用场景

当头节点不确定的时候,使用哑巴节点

86. 分隔链表
给定一个链表和一个特定值 x,对链表进行分隔,使得所有小于 x 的节点都在大于或等于 x 的节点之前。你应当保留两个分区中每个节点的初始相对位置。示例:输入: head = 1->4->3->2->5->2, x = 3
输出: 1->2->2->4->3->5链接:https://leetcode-cn.com/problems/partition-list/solution/fen-ge-lian-biao-by-leetcode/复杂度分析时间复杂度: O(N),其中N是原链表的长度,我们对该链表进行了遍历。
空间复杂度: O(1),我们没有申请任何新空间。值得注意的是,我们只移动了原有的结点,因此没有使用任何额外空间。# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = Noneclass Solution:def partition(self, head: ListNode, x: int) -> ListNode:""":type head: ListNode:type x: int:rtype: ListNode"""# before and after are the two pointers used to create two list# before_head and after_head are used to save the heads of the two lists.# All of these are initialized with the dummy nodes created.before = before_head = ListNode(0)after = after_head = ListNode(0)while head:# If the original list node is lesser than the given x,# assign it to the before list.if head.val < x:before.next = headbefore = before.nextelse:# If the original list node is greater or equal to the given x,# assign it to the after list.after.next = headafter = after.next# move ahead in the original listhead = head.next# Last node of "after" list would also be ending node of the reformed listafter.next = None# Once all the nodes are correctly assigned to the two lists,# combine them to form a single list which would be returned.before.next = after_head.nextreturn before_head.next

​148. 排序链表sort-list​

没看懂

148. 排序链表:归并排序,先2个2个的 merge,完成一趟后,再 4个4个的 merge,直到结束。

O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。

思路:归并排序,找中点和合并操作

注意点
  • 快慢指针 判断 fast 及 fast.Next 是否为 nil 值

  • 递归 mergeSort 需要断开中间节点

  • 递归返回条件为 head 为 nil 或者 head.Next 为 nil

148. 排序链表
在 O(n log n) 时间复杂度和常数级空间复杂度下,对链表进行排序。示例 1:输入: 4->2->1->3
输出: 1->2->3->4
示例 2:输入: -1->5->3->4->0
输出: -1->0->3->4->5
链接:https://leetcode-cn.com/problems/sort-list/solution/sort-list-gui-bing-pai-xu-lian-biao-by-jyd/
class Solution:def sortList(self, head: ListNode) -> ListNode:h, length, intv = head, 0, 1while h:h, length = h.next, length + 1res = ListNode(0)res.next = head# merge the list in different intv.while intv < length:pre, h = res, res.nextwhile h:# get the two merge head `h1`, `h2`h1, i = h, intvwhile i and h: h, i = h.next, i - 1if i: break # no need to merge because the `h2` is None.h2, i = h, intvwhile i and h: h, i = h.next, i - 1c1, c2 = intv, intv - i # the `c2`: length of `h2` can be small than the `intv`.# merge the `h1` and `h2`.while c1 and c2:if h1.val < h2.val: pre.next, h1, c1 = h1, h1.next, c1 - 1else: pre.next, h2, c2 = h2, h2.next, c2 - 1pre = pre.nextpre.next = h1 if c1 else h2while c1 > 0 or c2 > 0: pre, c1, c2 = pre.next, c1 - 1, c2 - 1pre.next = h intv *= 2return res.next

​143. 重排链表reorder-list​

143. 重排链表:首尾指针法,首先将原始链表的每一个节点存放在一个数组中,然后我们取首尾指针向中间遍历,每次循环我们需要将左指针的节点连上右指针的节点,在节点连上之后,我们需要将右指针连上未排序的首节点。

给定一个单链表 LLL→…→L__nL 将其重新排列后变为: LL__nLL__nLL__n→…

思路:找到中点断开,翻转后面部分,然后合并前后两个链表

143. 重排链表
给定一个单链表 L:L0→L1→…→Ln-1→Ln ,
将其重新排列后变为: L0→Ln→L1→Ln-1→L2→Ln-2→…你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。示例 1:给定链表 1->2->3->4, 重新排列为 1->4->2->3.
示例 2:给定链表 1->2->3->4->5, 重新排列为 1->5->2->4->3.# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:def reorderList(self, head: ListNode) -> None:"""Do not return anything, modify head in-place instead."""if not head or not head.next: return head# 1 2 3 4 5fast = headpre_mid = head# 找到中点, 偶数个找到时上界那个while fast.next and fast.next.next:pre_mid = pre_mid.nextfast = fast.next.next# 翻转中点之后的链表,采用是pre, cur双指针方法pre = Nonecur = pre_mid.next# 1 2 5 4 3while cur:tmp = cur.nextcur.next = prepre = curcur = tmp# 翻转链表和前面链表拼接pre_mid.next = pre# 1 5 2 4 3# 链表头p1 = head# 翻转头p2 = pre_mid.next#print(p1.val, p2.val)while p1 != pre_mid:# 建议大家这部分画图, 很容易理解pre_mid.next = p2.nextp2.next = p1.nextp1.next = p2p1 = p2.nextp2 = pre_mid.next链接:https://leetcode-cn.com/problems/reorder-list/solution/yong-zhan-fan-zhuan-huo-zhe-zhi-jie-fan-zhuan-by-p/

​141. 环形链表linked-list-cycle​

141. 环形链表:快慢指针法,若存在环最终快慢指针会相遇;若不存在环,那么快指针一定会先走到链表尾部。

给定一个链表,判断链表中是否有环。

思路:快慢指针,快慢指针相同则有环,证明:如果有环每走一步快慢指针距离会减 1

141. 环形链表
给定一个链表,判断链表中是否有环。为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。
如果 pos 是 -1,则在该链表中没有环。双指针,漫画小灰 5.2节时间空间复杂度分析:
https://leetcode-cn.com/problems/linked-list-cycle/solution/huan-xing-lian-biao-by-leetcode/# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = Noneclass Solution:def hasCycle(self, head: ListNode) -> bool:slow = fast = head# if not head:  # 没必要这样写可以加入while循环判断更简洁#     return Falsewhile fast and fast.next:  # 防止head为空和出现空指针的next的情况slow = slow.nextfast = fast.next.nextif slow == fast:return Truereturn False作者:gulugulu_go
链接:https://leetcode-cn.com/problems/linked-list-cycle/solution/141-linked-list-cycle_li-jie-by-gulugulu_go/

142 ​环形链表 Ⅱ linked-list-cycle-ii​

给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null

思路:快慢指针,快慢相遇之后,慢指针回到头,快慢指针步调一致一起移动,相遇点即为入环点

 

坑点

  • 指针比较时直接比较对象,不要用值比较,链表中有可能存在重复值情况

  • 第一次相交后,快指针需要从下一个节点开始和头指针一起匀速移动

另外一种方式是 fast=head,slow=head

这两种方式不同点在于,一般用 fast=head.Next 较多,因为这样可以知道中点的上一个节点,可以用来删除等操作。

  • fast 如果初始化为 head.Next 则中点在 slow.Next

  • fast 初始化为 head,则中点在 slow

142. 环形链表 II
给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置
(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。说明:不允许修改给定的链表。
漫画小灰,5.2 拓展class Solution(object):def detectCycle(self, head):slow = fast = head# if not head:  # 没必要这样写可以加入while循环判断更简洁#     return Falsewhile True:if not(fast and fast.next):#无环的问题,走到边界了。return Falseslow = slow.nextfast = fast.next.nextif slow == fast:breakfast = headwhile fast != slow:slow = slow.nextfast = fast.nextreturn fast作者:jyd
链接:https://leetcode-cn.com/problems/linked-list-cycle-ii/solution/linked-list-cycle-ii-kuai-man-zhi-zhen-shuang-zhi-/

​234. 回文链表palindrome-linked-list​

234. 回文链表:快慢指针法,快指针走两步,慢指针走一步,找到链表的中点。然后,翻转后半部分。最后从前半部分链表和后半部分链表是否相同。

请判断一个链表是否为回文链表。

234. 回文链表
请判断一个链表是否为回文链表。示例 1:输入: 1->2
输出: false
示例 2:输入: 1->2->2->1
输出: true
进阶:
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?方法三:我们可以分为以下几个步骤:找到前半部分链表的尾节点。
反转后半部分链表。
判断是否为回文。
恢复链表。
返回结果。
链接:https://leetcode-cn.com/problems/palindrome-linked-list/solution/hui-wen-lian-biao-by-leetcode/class Solution:def isPalindrome(self, head: ListNode) -> bool:if head is None:return True# Find the end of first half and reverse second half.first_half_end = self.end_of_first_half(head)second_half_start = self.reverse_list(first_half_end.next)# Check whether or not there's a palindrome.result = Truefirst_position = headsecond_position = second_half_startwhile result and second_position is not None:if first_position.val != second_position.val:result = Falsefirst_position = first_position.nextsecond_position = second_position.next# Restore the list and return the result.first_half_end.next = self.reverse_list(second_half_start)return result    def end_of_first_half(self, head):fast = headslow = headwhile fast.next is not None and fast.next.next is not None:fast = fast.next.nextslow = slow.nextreturn slowdef reverse_list(self, head):previous = Nonecurrent = headwhile current is not None:next_node = current.nextcurrent.next = previousprevious = currentcurrent = next_nodereturn previous

​138. 复制带随机指针的链表copy-list-with-random-pointer​

138. 复制带随机指针的链表:模拟题,分三步,第一步在原链表的每个节点后面拷贝出一个新的节点,第二步拷贝random,第三步断开链表。

给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点。 要求返回这个链表的 深拷贝。

思路:1、hash 表存储指针,2、复制节点跟在原节点后面

138. 复制带随机指针的链表
给定一个链表,每个节点包含一个额外增加的随机指针,该指针可以指向链表中的任何节点或空节点。要求返回这个链表的 深拷贝。 我们用一个由 n 个节点组成的链表来表示输入/输出中的链表。每个节点用一个 [val, random_index] 表示:val:一个表示 Node.val 的整数。
random_index:随机指针指向的节点索引(范围从 0 到 n-1);如果不指向任何节点,则为  null 。解法一
class Solution(object):def copyRandomList(self, head):if not head:return Nonep = head# 第一步,在每个原节点后面创建一个新节点# 1->1'->2->2'->3->3'while p:new_node = Node(p.val,None,None)new_node.next = p.nextp.next = new_nodep = new_node.nextp = head# 第二步,设置新节点的随机节点while p:if p.random:p.next.random = p.random.nextp = p.next.next# 第三步,将两个链表分离p = headdummy = Node(-1,None,None)cur = dummywhile p:cur.next = p.nextcur = cur.nextp.next = cur.nextp = p.nextreturn dummy.next作者:wang_ni_ma
链接:https://leetcode-cn.com/problems/copy-list-with-random-pointer/solution/liang-chong-shi-xian-tu-jie-138-fu-zhi-dai-sui-ji-/

总结

链表必须要掌握的一些点,通过下面练习题,基本大部分的链表类的题目都是手到擒来~

  • null/nil 异常处理

  • dummy node 哑巴节点

  • 快慢指针

  • 插入一个节点到排序链表

  • 从一个链表中移除一个节点

  • 翻转链表

  • 合并两个链表

  • 找到链表的中间节点

练习

  • ​remove-duplicates-from-sorted-list​

  • ​remove-duplicates-from-sorted-list-ii​

  • ​reverse-linked-list​

  • ​reverse-linked-list-ii​

  • ​merge-two-sorted-lists​

  • ​partition-list​

  • ​sort-list​

  • ​reorder-list​

  • ​linked-list-cycle​

  • ​linked-list-cycle-ii​

  • palindrome-linked-list​

  • ​copy-list-with-random-pointer​

1. 两数之和

1. 两数之和
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。

示例:

给定 nums = [2, 7, 11, 15], target = 9

因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]


class Solution:def twoSum(self, nums: List[int], target: int) -> List[int]:hashmap = {}for index, num in enumerate(nums):another_num = target - numif another_num in hashmap:return [hashmap[another_num], index]#不能直接放前面,有可能两个数相等的情况,比如2+2=4hashmap[num] = indexreturn None #错误要有返回值

2. 两数相加

给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式
存储的,并且它们的每个节点只能存储一位数字。
如果我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
您可以假设除了数字 0 之外,这两个数都不会以 0 开头。

示例:

输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807

模拟题,由于链表是逆序存放数字的,所以链表数字从左至右低位对低位,高位对高位,
因此我们从左至右遍历两个链表模拟加法运算即可,注意向高位进位。

这个解法里面的图片很形象
https://leetcode-cn.com/problems/add-two-numbers/solution/hua-jie-suan-fa-2-liang-shu-xiang-jia-by-guanpengc/


# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = Noneclass Solution:def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:pre = cur = ListNode(None) #保存头结点,返回结果carry = 0 #每一步的求和暂存变量,进位while l1 or l2 or carry:           #循环条件:l1 或者l2(没有遍历完成),carry(进位)不为0carry += (l1.val if l1 else 0) + (l2.val if l2 else 0)           #这其实是好多代码,我自己写了好多行,但是作者这样写非常简洁,赞cur.next = ListNode(carry % 10)             #构建新的list存储结果,其实用较长的加数链表存也可以,%10:求个位cur = cur.next                        carry //= 10   地板除                                         #求进位l1 = l1.next if l1 else None           l2 = l2.next if l2 else Nonereturn pre.next

26. 删除排序数组中的重复项

给定一个排序数组,你需要在 原地 删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。

不要使用额外的数组空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。

示例 1:

给定数组 nums = [1,1,2],

函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2。

你不需要考虑数组中超出新长度后面的元素。
示例 2:

给定 nums = [0,0,1,1,1,2,2,3,3,4],

函数应该返回新的长度 5, 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4。

你不需要考虑数组中超出新长度后面的元素。
链接:https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array

26. 删除排序数组中的重复项# 双指针法:
# 数组完成排序后,我们可以放置两个指针 i 和 j,其中 i 是慢指针,而 j 是快指针。
# 只要 nums[i] = nums[j],我们就增加 j 以跳过重复项。# 当我们遇到 nums[j] !=nums[i] 时,跳过重复项的运行已经结束,
# 然后递增 i,因此我们必须把它(nums[j])的值复制到 nums[i + 1]。
# 接着我们将再次重复相同的过程,直到j到达数组的末尾为止。class Solution:def removeDuplicates(self,nums:list[int])->int:if not nums:return 0#if (len(nums) == 0) return 0;i=0for j in range(1,len(nums)):if nums[i]!=nums[j]:i+=1   #注意这一行,为啥在下一行的前面,她俩顺序不能颠倒。nums[i]=nums[j]return i+1  #注意是i+1nums = [1,1,2]
[1,2]
return 2nums = [0,0,1,1,1,2,2,3,3,4]
[0,1,2,3,4]
return 5# 26题,有序数组删除重复元素,可使用「双指针」:
# 不真正删除,找到后面不重复元素,依次覆盖前面元素,最后只返回不重复元素的长度。
# 因为数组有下标,所以「双指针」实现比较简单。# 复杂度分析
# 时间复杂度:O(n),假设数组的长度是 n,那么 i 和 j 分别最多遍历 n 步。
# 空间复杂度:O(1)。

160 相交链表(easy)

编写一个程序,找到两个单链表相交的起始节点。

方法三:双指针法
创建两个指针 pA 和 pB,分别初始化为链表 A 和 B 的头结点。然后让它们向后逐结点遍历。
当 pA 到达链表的尾部时,将它重定位到链表 B 的头结点 (你没看错,就是链表 B); 类似的,当 pB 到达链表的尾部时,将它重定位到链表 A 的头结点。
若在某一时刻 pA 和 pB 相遇,则 pA/pB 为相交结点。
想弄清楚为什么这样可行, 可以考虑以下两个链表: A={1,3,5,7,9,11} 和 B={2,4,9,11},相交于结点 9。 由于 B.length (=4) < A.length (=6),pB 比 pA 少经过 22 个结点,会先到达尾部。将 pB 重定向到 A 的头结点,pA 重定向到 B 的头结点后,pB 要比 pA 多走 2 个结点。因此,它们会同时到达交点。
如果两个链表存在相交,它们末尾的结点必然相同。因此当 pA/pB 到达链表结尾时,记录下链表 A/B 对应的元素。若最后元素不相同,则两个链表不相交。
复杂度分析

时间复杂度 : O(m+n)。
空间复杂度 : O(1)。

视频牛逼啊https://leetcode-cn.com/problems/intersection-of-two-linked-lists/solution/jiao-ni-yong-lang-man-de-fang-shi-zhao-dao-liang-2/

https://leetcode-cn.com/problems/intersection-of-two-linked-lists/solution/tu-jie-xiang-jiao-lian-biao-by-user7208t/

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = Noneclass Solution:def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> ListNode:if not headA or not headB:return NonenodeA = headAnodeB = headBwhile(nodeA !=nodeB):nodeA = nodeA.next if nodeA else headBnodeB = nodeB.next if nodeB else headAreturn nodeA

19 删除链表的倒数第N个结点(medium)

给定一个链表,删除链表的倒数第 个节点,并且返回链表的头结点。

示例:

给定一个链表: 1->2->3->4->5, 和 n = 2.

当删除了倒数第二个节点后,链表变为 1->2->3->5.

说明:给定的 n 保证是有效的。

进阶:你能尝试使用一趟扫描实现吗?

快慢指针法,起始快指针走n步后,若此时快指针已为空,表示我们删除第一个节点,直接返回head->next即可;否则此时快慢指针一起走,也就是慢指针走size-n步到达倒数第N个节点的前驱节点,快指针会到达链表的尾节点,此时我们删除slow->next节点即可。

链接:https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/solution/chao-ke-ai-dong-hua-jiao-ni-ru-he-shan-chu-lian-bi/

# Definition for singly-linked list.
class ListNode:def __init__(self, x):self.val = xself.next = Noneclass Solution:def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode:if not head:return headslownode = ListNode(None)slownode.next = headfastnode = slownodefor i in range(n):fastnode = fastnode.nextwhile(fastnode.next!=None):slownode = slownode.nextfastnode = fastnode.next#注意是指去掉链表表头的那个点,fast已经走到最后一点了,slow未移动if slownode.next == head:head = head.nextelse:slownode.next = slownode.next.nextreturn head

203 移除链表元素(easy)

模拟题,直接遍历链表确定是否删除节点即可。

删除链表中等于给定值 val 的所有节点。

示例:

输入: 1->2->6->3->4->5->6, val = 6
输出: 1->2->3->4->5

复杂度分析

  • 时间复杂度:O(N),只遍历了一次。
  • 空间复杂度:O(1)。

链接:https://leetcode-cn.com/problems/remove-linked-list-elements/solution/yi-chu-lian-biao-yuan-su-by-leetcode/

class Solution:def removeElements(self, head: ListNode, val: int) -> ListNode:sentinel = ListNode(0)sentinel.next = headprev, curr = sentinel, headwhile curr:if curr.val == val:prev.next = curr.nextelse:prev = currcurr = curr.nextreturn sentinel.next

328 奇偶链表

给定一个单链表,把所有的奇数节点和偶数节点分别排在一起。请注意,这里的奇数节点和偶数节点指的是节点编号的奇偶性,而不是节点的值的奇偶性。

请尝试使用原地算法完成。你的算法的空间复杂度应为 O(1),时间复杂度应为 O(nodes),nodes 为节点总数。

示例 1:

输入: 1->2->3->4->5->NULL
输出: 1->3->5->2->4->NULL
示例 2:

输入: 2->1->3->5->6->4->7->NULL 
输出: 2->3->6->7->1->5->4->NULL

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
复杂度分析时间复杂度: O(n) 。总共有 n 个节点,我们每个遍历一次。空间复杂度: O(1) 。我们只需要 4 个指针。class Solution:def oddEvenList(self, head: ListNode) -> ListNode:if not head:return headodd = headeven_head = even = head.nextwhile odd.next and even.next:odd.next = odd.next.nexteven.next = even.next.nextodd,even = odd.next,even.nextodd.next = even_headreturn head作者:zbzzbz
链接:https://leetcode-cn.com/problems/odd-even-linked-list/solution/zui-po-su-de-xiang-fa-dai-ma-zhu-shi-fei-chang-xia/

430 扁平化多级双向链表

还没看

模拟题,迭代法,遍历链表,若发现该链表存在child节点那么就将[child,tail]这段子链表插入到当前节点的后面去,然后继续遍历链表。

多级双向链表中,除了指向下一个节点和前一个节点指针之外,它还有一个子链表指针,可能指向单独的双向链表。这些子列表也可能会有一个或多个自己的子项,依此类推,生成多级数据结构,如下面的示例所示。

给你位于列表第一级的头节点,请你扁平化列表,使所有结点出现在单级双链表中。

复杂度分析

  • 时间复杂度:O(N)。
  • 空间复杂度:O(N)。
"""
# Definition for a Node.
class Node(object):def __init__(self, val, prev, next, child):self.val = valself.prev = prevself.next = nextself.child = child
"""
class Solution(object):def flatten(self, head):if not head:returnpseudoHead = Node(0,None,head,None)prev = pseudoHeadstack = []stack.append(head)while stack:curr = stack.pop()prev.next = currcurr.prev = previf curr.next:stack.append(curr.next)if curr.child:stack.append(curr.child)# don't forget to remove all child pointers.curr.child = Noneprev = curr# detach the pseudo head node from the result.pseudoHead.next.prev = Nonereturn pseudoHead.next作者:LeetCode
链接:https://leetcode-cn.com/problems/flatten-a-multilevel-doubly-linked-list/solution/bian-ping-hua-duo-ji-shuang-xiang-lian-biao-by-lee/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

61 旋转链表(medium)

模拟题,先求出链表长度size,若k取余size为空,那么不用旋转了,直接返回head;否则将链表首尾相连形成环形链表,由于k表示尾节点移动k%size位,那么头节点移动size-k%size位。

给定一个链表,旋转链表,将链表每个节点向右移动 k 个位置,其中 k 是非负数。

示例 1:

输入: 1->2->3->4->5->NULL, k = 2
输出: 4->5->1->2->3->NULL
解释:
向右旋转 1 步: 5->1->2->3->4->NULL
向右旋转 2 步: 4->5->1->2->3->NULL
示例 2:

输入: 0->1->2->NULL, k = 4
输出: 2->0->1->NULL
解释:
向右旋转 1 步: 2->0->1->NULL
向右旋转 2 步: 1->2->0->NULL
向右旋转 3 步: 0->1->2->NULL
向右旋转 4 步: 2->0->1->NULL

class Solution:def rotateRight(self, head: 'ListNode', k: 'int') -> 'ListNode':# base casesif not head:return Noneif not head.next:return head# close the linked list into the ringold_tail = headn = 1while old_tail.next:old_tail = old_tail.nextn += 1old_tail.next = head# find new tail : (n - k % n - 1)th node# and new head : (n - k % n)th nodenew_tail = headfor i in range(n - k % n - 1):new_tail = new_tail.nextnew_head = new_tail.next# break the ringnew_tail.next = Nonereturn new_head作者:LeetCode
链接:https://leetcode-cn.com/problems/rotate-list/solution/xuan-zhuan-lian-biao-by-leetcode/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

剑指 Offer 24 反转链表

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = Noneclass Solution:def reverseList(self, head: ListNode) -> ListNode:pre=Nonecur=headwhile cur:third=cur.nextcur.next=prepre=curcur=thirdreturn pre

剑指 Offer 18 删除链表的节点

剑指 Offer 18. 删除链表的节点

给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点。

返回删除后的链表的头节点。

注意:此题对比原题有改动

示例 1:

输入: head = [4,5,1,9], val = 5
输出: [4,1,9]
解释: 给定你链表中值为 5 的第二个节点,那么在调用了你的函数之后,该链表应变为 4 -> 1 -> 9.

示例 2:

输入: head = [4,5,1,9], val = 1
输出: [4,5,9]
解释: 给定你链表中值为 1 的第三个节点,那么在调用了你的函数之后,该链表应变为 4 -> 5 -> 9.

说明:

  • 题目保证链表中节点的值互不相同
  • 若使用 C 或 C++ 语言,你不需要 free 或 delete 被删除的节点
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:def deleteNode(self, head: ListNode, val: int) -> ListNode:if not head:return headcur=dummy=ListNode(None)dummy.next=headwhile cur.next:if cur.next.val==val:cur.next=cur.next.nextbreakelse:cur=cur.nextreturn dummy.next

剑指 Offer 22 链表中倒数第k个节点

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = Noneclass Solution:def getKthFromEnd(self, head: ListNode, k: int) -> ListNode:if not head :return head left=right=headwhile k:right=right.nextk-=1while right :left=left.nextright=right.nextreturn left

剑指 Offer 25 合并两个排序的链表

class Solution:def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:cur = dum = ListNode(0)while l1 and l2:if l1.val < l2.val:cur.next, l1 = l1, l1.nextelse:cur.next, l2 = l2, l2.nextcur = cur.nextcur.next = l1 if l1 else l2return dum.next

剑指 Offer 06 从尾到头打印链表

辅助栈法

class Solution:def reversePrint(self, head: ListNode) -> List[int]:stack = []while head:stack.append(head.val)head = head.nextreturn stack[::-1]

剑指 Offer 35 复杂链表的复制   中等

注意:本题与主站 138 题相同:https://leetcode-cn.com/problems/copy-list-with-random-pointer/

leetcode链表刷题 python相关推荐

  1. 【Leetcode】 刷题之路1(python)

    leetcode 刷题之路1(python) 看到有大佬总结了一些相关题目,想着先刷一类. 1.两数之和 15.三数之和 16.最接近的三数之和 11.盛最多的水 18.四数之和 454.四数相加II ...

  2. LeetCode刷题Python实录

    使用Python的LeetCode刷题 前言 题目 1408. 数组中的字符串匹配 508. 出现次数最多的子树元素和 1089. 复写零 剑指 Offer 14- I. 剪绳子 1175. 质数排列 ...

  3. leetcode分类刷题笔记

    leetcode分类刷题笔记--基于python3 写在前面 1.做题如果实在想不出时间复杂度比较优的解法,可以先写出暴力解法,尝试在其基础上优化 2.排序.双指针.二分等--经常可以优化时间复杂度 ...

  4. leetcode每日刷题计划-简单篇day8

    leetcode每日刷题计划-简单篇day8 今天是纠结要不要新买手机的一天QAQ想了想还是算了吧,等自己赚钱买,加油 Num 70 爬楼梯 Climbing Stairs class Solutio ...

  5. LeetCode代码刷题(17~24)

    目录 17. 电话号码的字母组合 18. 四数之和 19. 删除链表的倒数第 N 个结点 20. 有效的括号 21. 合并两个有序链表 22. 括号生成 23. 合并K个升序链表 24. 两两交换链表 ...

  6. 刷题 Python: 明码

    刷题 Python: 明码 4 0 4 0 4 0 4 32 -1 -16 4 32 4 32 4 32 4 32 4 32 8 32 8 32 16 34 16 34 32 30 -64 0 16 ...

  7. 【Leetcode】刷题之路2(python)

    哈希映射类题目(简单题小试牛刀啦bhn) 242.有效的字母异位词 349.两个数组的交集 1002.查找常用字符 202.快乐数 383.赎金信 242. 有效的字母异位词 用python的Coun ...

  8. 看了这篇 LeetCode 的刷题心得,再也不用抄别人代码了

    作者:VioletJack 原文:<LeetCode 算法题刷题心得>https://www.jianshu.com/p/8876704ea9c8 花了十几天,把<算法>看了一 ...

  9. 【Leetcode】刷题题单记录

    程序=算法+数据结构,不管干哪一行,只要涉及到编程算法始终是最重要的!!! 算法基础差,变做题巩固!!! LeetCode刷题,搞起来! 由于我只会C++和Python, 所以题解只有C++ 和 Py ...

  10. 如何在 LeetCode 高效刷题,才能拿到一线大厂 Offer

    有人说写代码就像我们平时开车,仅凭经验你就可以将车开走:但当有一天,这辆车出问题跑不起来的时候,你不懂汽车的运行机制,你要怎么排除和解决问题?所以拥有扎实的数据结构和算法,才能开好编程这辆车. 作为程 ...

最新文章

  1. 十大经典排序算法Python版实现(附动图演示)
  2. P4factory ReadMe Quickstart 安装p4factory
  3. 程序员的奋斗史(八)——懒人造就方法
  4. vue 定义全局弹框_VUE路由拦截:Vue自定义全局弹窗组件
  5. 【APP Web架构】企业web高可用集群实战之haproxy篇续(二)
  6. spyder 崩溃解决方案
  7. 神策数据罗彦博:如何正确使用漏斗分析提升转化?
  8. 不分大小写的Strstr
  9. 产品经验谈:一文讲清楚商业模式梳理怎么做?
  10. iview tag 标签点击事件
  11. 抢注“哔哩哔哩”商标卖成人用品?A站回应:不符合价值观 已申请注销
  12. TeamCenter开发系统设计系列之一
  13. 腾讯云 AI 在新基建领域下一盘什么大棋
  14. ExtJS2.0实用简明教程 - Form布局
  15. mysql api百度云盘_利用百度云盘API上传文件至百度云盘
  16. 《中国人工智能学会通讯》——3.33 长期研究需求 (Long-Term Research Needs)
  17. CSDN写文章——不要使用默认标题
  18. matlab ode45求解微分方程
  19. Django笔记二十八之数据库查询优化汇总
  20. 什么是生产历史追溯系统

热门文章

  1. java调用短信api接口发送短信demo实例
  2. [webpack] Content not from webpack is served from “xxxx“ 并且 http://localhost:8080/ 数据为空解决方案
  3. python井字棋_python实现井字棋游戏
  4. SwiftUI4 iOS16 新特性之 WeatherKit免费天气API使用教程(WWDC 2022教程含源码)
  5. 软考信息系统项目管理师知识点总结(高项十大管理案例分析作文)
  6. 知网海外版(硕博论文pdf下载方式)
  7. 流殇三月,誓言碎落于天涯
  8. SQLSTATE[23000]: Integrity constraint violation:1062 Duplicate entry1664187678631531497821000‘ 解决办法
  9. 【题解】LuoGu4408:[NOI2003]逃学的小孩
  10. Arduino实验二十五 超声波传感器测距实验