题目类型上主要分为对链表重新排列,删除重复,删除给定值,反转,排序。
技巧上会反转,排序。
数组指针这个比较bug的,能ac,但效率不高,非常直观得解很多题目,优化技巧上可以通过realloc来一边前进一边扩展分配数组大小,而不必先走一趟得到链表长度,再分配。
2 AddTwo Numbers 23.6% Medium
两个链表相加,第一个,第二个数分别为个十百千万,依次。
循环while(p1&& p2), 信号量判断进位,其他没什么要注意的。时间O(n),空间O(1)
19 RemoveNth Node From End of List 29.9% Easy
删除链表中倒数第n个节点
两个指针,让一个先走n步(还是n-1步?画图举例看看),其他细节好处理。时间O(n), 空间O(1)
21 MergeTwo Sorted Lists 35.8% Easy
将两个有序链表合并成一个有序链表
循环while(p1&& p2) 哪个小先接哪个,走完即可, 时间O(n), 空间O(1)
23 Mergek Sorted Lists 23.7% Hard
24 SwapNodes in Pairs 35.6% Easy
成对交换节点
Given 1->2->3->4, you should return the list as2->1->4->3.
有两种方法:(1)交换,前进一步,再交换,注意要判断是否有next(这种没写过,写一遍)。(2)指针数组把每个数都存下来,成对交换,再连起来,这个要遍历3次。第一种方法时间O(n), 空间O(1)
25 ReverseNodes in k-Group 27.9% Hard
61 RotateList 23.1% Medium
快慢指针,找到给定节点的前一个节点p,记录新头节点,p的next置空,快指针指向尾节点和原头节点相连,其他没什么需要注意的了时间O(n),空间O(1)
82 RemoveDuplicates from Sorted List II 27.2% Medium
再做一遍,删除有序链表中相同值的节点,全删除。
For example,
Given 1->2->3->3->4->4->5, return1->2->5.
Given 1->1->1->2->3, return 2->3.
需要两个指针pre和p,p的处理同第83题,pre来删除p的结果。其他都是细节了,时间O(n), 空间O(1)
83 RemoveDuplicates from Sorted List 37.1% Easy
删除有序链表中相同值的节点。保留一个
For example,
Given 1->1->2, return 1->2.
Given 1->1->2->3->3, return 1->2->3.
节点p的next节点值相同,删除next,不同,前进。不是迭代过程中默认前进,这点需要判断,和一般的链表题有点不同。时间O(n),空间O(1)
86 PartitionList 29.8% Medium
链表根据给定值顺序进行调整。
For example,
Given 1->4->3->2->5->2 and x = 3,
return 1->2->2->4->3->5.
设置两个链表p1和p2,小于给定值的放p1,大于放p2,最后连在一起,这题和21题有点像。时间O(n), 空间O(1)
92 ReverseLinked List II 28.2% Medium
给定值m和n,将链表中第m和第n节点之间的所有节点顺序进行反转
Given 1->2->3->4->5->NULL, m = 2 and n = 4,
return 1->4->3->2->5->NULL.
有两种方法:(1)找到n和m这两个节点,反转的方法参照206题,需要多个指针记录边界的情况(没写过,要写一遍)。(2)用指针数组记录所有节点,最后重新拼接。
方法1时间O(n), 空间O(1)
109 ConvertSorted List to Binary Search Tree 30.8% Medium
138 CopyList with Random Pointer 26.1% Hard
141 LinkedList Cycle 36.6% Easy
判断指针是否有环
快慢指针,快指针的判断要注意先判断p->next再判断p->next->next,不能直接判断,否则有可能崩溃,时间O(n), 空间O(1)
142 LinkedList Cycle II 31.3% Medium
找出环的入口
快慢指针,这个要画图,把环画出来,给变量xy来推,最后能得到一个普遍性质的,开始点再走固定步长相交的点就是入口,好像???(当时推过,这个过程要重新推下)
时间O(n), 空间O(1),其实要走两趟
143 ReorderList 23.1% Medium
对链表重排列,例子:
Given a singly linked list L: L0→L1→…→Ln-1→Ln,
reorderit to: L0→Ln→L1→Ln-1→L2→Ln-2→…
方法1:指针数组,找下规则,重新放。时间O(n), 空间O(1)。可以写一遍方法。2:把链表分成两段,后面一段反转,再把两条链表交叉拼接。这题感觉是206和238的结合。时间O(n), 空间O(1)
147 InsertionSort List 29.8% Medium
148 SortList 25.3% Medium
排序
方法1,指针数组+快排。时间O(nlogn),空间O(n) 很慢,要672ms
方法2:这个要写一遍!!!!!
160 Intersectionof Two Linked Lists 30.4% Easy
想不起来的,还要仔细想想
203 RemoveLinked List Elements 29.1% Easy
删除链表中给定值的节点
Example
Given: 1 --> 2 --> 6 --> 3 --> 4 --> 5--> 6, val = 6
Return: 1 --> 2 --> 3 --> 4 --> 5
这里有两种特殊的情况,就是给定节点连续和这种节点是最后一位,两种情况都应该考虑。解法(1)先造一个空的节点ph,ph的next为头结点,一直判断当前节点的next是否是给定值得节点,则删除。(2)另外一种做法思路同237,如果当前节点是给定值,就是把next节点的值赋给当前节点,删除next,但是好像无法处理连续相同节点的情况??(可以处理,但是最后一个节点是给定节点这种情况无法处理)时间O(n), 空间O(1)
206 ReverseLinked List 40.2% Easy
(典型的面试题)链表的反转
把head节点的next一直放到头部,需要三个指针,画图,其他没什么要注意的了,时间O(n),空间O(1)
234 PalindromeLinked List 28.8% Easy
判断链表是否是回文
因为是判断性质,不需要改链表结构,用一个int数组得到链表所有值,转换为判断数组是否是回文求解即可。优化:可以通过realloc函数动态动态扩展int数组大小(一趟即可),不然的话要先走一遍链条得到链表长度,需要两趟。时间O(n),空间O(n)
237 DeleteNode in a Linked List 44.0% Easy
删除链表当前节,例:1-2-3-4,给定3,最终得到1-2-4
void deleteNode(struct ListNode* node)
把当前节点的next节点的值赋给当前节点后,删除next节点,时间O(1),空间O(1)
328 OddEven Linked List 38.8% Medium
奇数节点和偶数节点都各自形成链,再拼接
Example:
Given 1->2->3->4->5->NULL,
return 1->3->5->2->4->NULL.
奇数节点和偶数节点都各自形成链,再拼接,要注意偶数链表最后一个节点的next要置为NULL,判断奇偶用if(pos%2 == 0) 和 if(pos& 1) 都可以,前者好像还快一点,why??
时间O(n),空间O(n)