链表的定义
1 | class ListNode: |
2. Add Two Numbers
两个链表相加
1 | Input: (2 -> 4 -> 3) + (5 -> 6 -> 4) |
1 | def addTwoNumbers(l1, l2): |
445. Add Two Numbers II
跟上题类似,只不过是进位方式不同。原题
1 | Input: (7 -> 2 -> 4 -> 3) + (5 -> 6 -> 4) |
方法一:先reverse再相加,最后再reverse。
1 | def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode: |
1 | def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode: |
21. Merge Two Sorted Lists
合并两个有序链表。原题
1 | Input: 1->2->4, 1->3->4 |
方法1:iteratively 迭代
1 | def mergeTwoLists(l1, l2): |
方法2:recursively 递归
1 | def mergeTwoLists(l1, l2): |
23. Merge k Sorted Lists
合并k个有序列表。原题
1 | Input: |
方法一:Brute Force. time: O(NlogN)
1 | def mergeKLists(self, lists: List[ListNode]) -> ListNode: |
方法二:优先级队列。本来优先级就没有方法一快,再加上Python3中的比较符机制不同,导致要实现__lt__
方法,就更慢了。不过理论时间复杂度是比方法一小的。Time: O(Nlogk)
1 | class CmpNode: |
ListNode
的比较,以解决上述问题。只要加上该链表在原数组中的索引位置,就一定不会重复,从而忽略对ListNode
的比较。
1 | def mergeKLists(self, lists: List[ListNode]) -> ListNode: |
1 | def mergeKLists(self, lists: List[ListNode]) -> ListNode: |
1 | def mergeKLists(self, lists: List[ListNode]) -> ListNode: |
141. Linked List Cycle
判断一个链表是否有环。原题
经典的一道题,看成两个人在赛跑,如果有环,快的人会和慢的人相遇
1 | def hasCycle(self, head): |
142. Linked List Cycle II
求链表中环的入口节点。原题
- 首先判断此链表是否有环。
- 然后在相交点和头结点一起走,一定会在入口相遇。
Consider the following linked list, where E is the cylce entry and X, the crossing point of fast and slow. H: distance from head to cycle entry E D: distance from E to X L: cycle length _____ / \ head_____H______E \ \ / X_____/
If fast and slow both start at head, when fast catches slow, slow has traveled H+D and fast 2(H+D). Assume fast has traveled n loops in the cycle, we have: 2H + 2D = H + D + L --> H + D = nL --> H = nL - D Thus if two pointers start from head and X, respectively, one first reaches E, the other also reaches E. In my solution, since fast starts at head.next, we need to move slow one step forward in the beginning of part 2
1 | def detectCycle(self, head): |
206. Reverse Linked List
倒置一个链表。原题
1 | Input: 1->2->3->4->5->NULL |
方法一: iteratively
1 | def reverseList(head): |
方法二:使用一行赋值
1 | def reverseList(self, head): |
方法三:递归
1 | def reverseList(self, head, prev=None): |
92. Reverse Linked List II
跟上题不同的是,只倒置指定区间的部分。原题
1 | Input: 1->2->3->4->5->NULL, m = 2, n = 4 |
1 | def reverseBetween(self, head: ListNode, m: int, n: int) -> ListNode: |
1 | def reverseBetween(self, head: ListNode, m: int, n: int) -> ListNode: |
### 160. Intersection of Two Linked Lists
#### 两个链表求相交。原题
1 | def getIntersectionNode(self, headA, headB): |
### 138. Copy List with Random Pointer
#### 深拷贝一个复杂链表,链表多包含了一个随机指针。原题
Time-O(2n), Memory-O(n).
1 | def copyRandomList(self, head): |
defaultdict
,通过创建一个默认的对象,再去修改它的label值。1 | def copyRandomList(self, head): |
### 237. Delete Node in a Linked List
#### 在链表中删除节点。给定的节点不是尾节点。原题
1 | Input: head = [4,5,1,9], node = 5 |
开始看到这题的思路是,要是能拿到父节点就好了,然后这道题需要别的思路,其关键在于复制
1 | def deleteNode(self, node): |
### 203. Remove Linked List Elements
#### 删除链表中值为val的元素。原题
方法一:遍历
head
并构建新的ListNode
。1 | def removeElements(self, head, val): |
方法二:更喜欢这个方法。
1 | def removeElements(self, head: 'ListNode', val: 'int') -> 'ListNode': |
83. Remove Duplicates from Sorted List
删除有序链表中重复的节点。原题
1 | def delete_duplicates(head): |
82. Remove Duplicates from Sorted List II
和上题不同的是,重复的节点要全部删除。原题
1 | Input: 1->2->3->3->4->4->5 |
方法一:首次AC的方法。
1 | def deleteDuplicates(self, head: ListNode) -> ListNode: |
876. Middle of the Linked List
链表中点,如果偶数个,则返回第二个节点。原题
1 | Input: [1,2,3,4,5] |
1 | def middleNode(self, head: 'ListNode') -> 'ListNode': |
234. Palindrome Linked List
判断一个链表是否是回文链表。原题
1 | Input: 1->2->2->1 |
方法一:此题为倒置链表和快慢指针的总和应用。
1 | def isPalindrome(self, head: 'ListNode') -> 'bool': |
方法二:上述方法有一个缺点就是改变了原始的head,这里进行一些改进。
1 | def isPalindrome(self, head): |
24. Swap Nodes in Pairs
成对转换链表。原题
1 | Given 1->2->3->4, you should return the list as 2->1->4->3. |
1 | def swapPairs(self, head: ListNode) -> ListNode: |
方法二:这里有个阴间写法,只创建一个变量。注意复制顺序,不能将p.next放到前面。
1 | def swapPairs(self, head: ListNode) -> ListNode: |
19. Remove Nth Node From End of List
删除倒数第N个节点。原题
1 | Given linked list: 1->2->3->4->5, and n = 2. |
1 | def removeNthFromEnd(self, head: ListNode, n: int) -> ListNode: |
328. Odd Even Linked List
重排链表,使奇数位节点在前,偶数位节点在后,就地排序。原题
1 | Input: 1->2->3->4->5->NULL |
1 | def oddEvenList(self, head: ListNode) -> ListNode: |
***. Sort a linked list that is sorted alternating asc and desc
这题不是LC上的,是面经里的,要求将一个奇数位升序,偶数位降序的链表转成一个升序的链表。
1 | Input List: 10->40->53->30->67->12->89->NULL |
方法一:分别参考了328,206,21三题,但是有一个副作用,就是将输入的链表改变了,一开始我是想针对链表就地修改,但是发现最后合并的时候又不太好实现。
1 | def sort_alternating(head: ListNode) -> ListNode: |
方法二:修改了方法一中的不足,在一开始就建立两个链表。两个链表要分开迭代才不会遗漏元素。
1 | def sort_alternating(head: ListNode) -> ListNode: |
148. Sort List
给链表排序。原题
1 | Input: 4->2->1->3 |
方法一:
1 | def sortList(self, head: ListNode) -> ListNode: |
1 | def sortList(self, head: ListNode) -> ListNode: |
817. Linked List Components
链表的组件。给定一个集合G,然后根据是否在G中分成若干部分,求连起来在G中的部分的个数。原题
1 | Input: |
1 | def numComponents(self, head: ListNode, G: List[int]) -> int: |
86. Partition List
链表分区,将比x小的节点放到前面,其余节点放到后面,并保持原有顺序。原题
1 | Input: head = 1->4->3->2->5->2, x = 3 |
方法一:首次AC的方法。注意最后gt后面可能有残留的节点比如最后一个2.
1 | def partition(self, head: ListNode, x: int) -> ListNode: |
61. Rotate List
向右旋转链表k次。原题
1 | Input: 0->1->2->NULL, k = 4 |
1 | def rotateRight(self, head: ListNode, k: int) -> ListNode: |
725. Split Linked List in Parts
按部分拆分链表。如果不能整除,要保证前面部分的大。原题
1 | Input: |
1 | def splitListToParts(self, root: ListNode, k: int) -> List[ListNode]: |
143. Reorder List
1 | Given 1->2->3->4->5, reorder it to 1->5->2->4->3. |
1 | def reorderList(self, head: ListNode) -> None: |
1030. Next Greater Node In Linked List
链表中下一个比当前节点大的值。和503题类似。原题
1 | Input: [2,7,4,3,5] |
方法一:竞赛时没有做出来,虽然是一个链表题,但是跟链表没啥关系。思路vals
保存了之前所有节点的值,stack
按序存的索引,当遍历一个新的节点时,不断地去和之前的节点比较,如果大于,那么久更新ans
中的值,之前设为了0。
1 | def nextLargerNodes(self, head: ListNode) -> List[int]: |
1 | def nextLargerNodes(self, head: ListNode) -> List[int]: |
1171. Remove Zero Sum Consecutive Nodes from Linked List
移除相连和为0的节点。像祖玛一样,连续地删除。答案不唯一。原题
1 | Input: head = [1,2,-3,3,1] |
[1,3,2,-3,-2,5,5,-5,1]
结果为[1,5,5,-5,1]
居然对了。
1 | def removeZeroSumSublists(self, head: ListNode) -> ListNode: |
仔细分析一下上述代码,再结果变成[1,5,5,-5,1]
时,没有将vals中删除的节点清空。
1 | def removeZeroSumSublists(self, head: ListNode) -> ListNode: |
25. Reverse Nodes in k-Group
链表中每k个为一组,反转,要求常数空间复杂度。长度不够则不反转。
1 | Input: head = [1,2,3,4,5], k = 2 |
方法一:有点笨,fast指针被修改到前面去了,然后做了补偿,感觉笨笨的。
1 | def reverseKGroup(self, head: ListNode, k: int) -> ListNode: |
1 | def reverseKGroup(self, head: ListNode, k: int) -> ListNode: |
###1798. Maximum Number of Consecutive Values You Can Make
使用数组中的任意数组成0开始的连续序列,最多能组成到几。
1 | Input: coins = [1,1,1,4] |
方法一:竞赛时最后5分钟绝杀了,排序,按照最小的数开始组,如果连不上,则组不成这个最小的数。
1 | def getMaximumConsecutive(self, coins: List[int]) -> int: |