关于链表的解题
LeetCode 147、对链表进行插入排序 https://leetcode-cn.com/problems/insertion-sort-list/
参见前文对普通数组的插入排序,这里又有对链表的插入排序。
实际上实质是一样的,比较前后大小,然后交换位置。
在这里我们引入一个虚拟头节点(dummynode),使用该节点的好处就是我们不用考虑头节点是不是为空,这些繁杂的边界情况。引入dummy,可以为我们省去很多麻烦.
在这里我们引入了两个指针,其实双指针在解决链表问题时也非常方便.
- 其实插入排序就是比较当插入新元素时,与前一个元素进行比较,如果此时新元素>前一个元素,即是有序的。此时我们只需要继续插入元素即可。
- 如果此时新元素<前一个元素,我们就需要找一个合适的位置将其插入。
1 | class Solution { |
LeetCode141、环形链表 https://leetcode-cn.com/problems/linked-list-cycle/
还是利用双指针思想,这里我们利用到一个快慢指针的方法。
想象一下我们在操场上跑步,跑的快的人和跑的慢的人,如果假设他们一直跑下去。那么他们一定会在某个时刻相遇,在第一次相遇这个时刻,跑的快的正好比跑的慢的多跑一圈。
那么这个环形链表也是同样的,我们让快指针每次走两步,慢指针每次走一步。如果链表中有环的话,那么快指针与慢指针一定会相遇。
同样的,我们还是引入一个dummynode,这样为我们省去很多麻烦.
1 | public class Solution { |
LeetCode 142、环形链表二 https://leetcode-cn.com/problems/linked-list-cycle-ii/
此题是在上一题的基础上,如果有环的话,要返回环的位置。
我们假设环的长度为m+n,并且快慢指针在相遇的位置为m.假设头节点到环开始的距离为a。那么慢指针此时应该走了a+m。快指针走了a+n+2m,并且二者的速度分别为v和2v,且在相等的时间内,这时候我们就可以列出一个等式.
(a+m)/v=(a+2m+n)/2v. 通过这个等式,我们求的a=n.这是一个非常有用的信息.
1 | public class Solution { |
LeetCode 92、反转链表二 https://leetcode-cn.com/problems/reverse-linked-list-ii/
此题是之前反转链表的升级版,有了上面一题的基础,这个题应该有一定的思路了。
由于这里是反转由m-n的节点,我们首先要定位到m位置的前一个节点
1 | class Solution { |
本思路是参照之前反转链表一,接下来提供另外一种思路。
由于题目需要反转, 我们很容易联想到栈这一数据结构,栈具有后进先出的性质。我们完全可以先把节点值存进栈中,然后再取出,完成反转操作。
1 | class Solution { |
上述解法的巧妙之处在于,我们避开了链表中那些繁杂的指向操作,有时候因为那些连接的操作,导致我们头晕,但是栈的使用也只是在特定的情况下。