目录
Leetcode 24
题目:两两交换链表节点
学习资料:代码随想录
初始思路
- 首先画图,尝试双指针,发现后续遍历过程中无法将前一个节点链接至现有节点。进而需要3个指针,由于head位置可能特殊,所以引入虚拟节点。
- 实现过程中,发现指针更新的方式比较蠢
学习后
- 思路基本一致,主要是更新部分,其实就是每次更新pre指针就好,cur和ne指针都是根据pre指针来定义
实现过程
- 注意循环终止条件,画图就可以知道,就是cur和ne等于none时就终止,实现上就是pre.next和pre.next.next 不为none
dummy = ListNode(next=head)
pre = dummy
while pre.next and pre.next.next:
cur = pre.next
ne = pre.next.next
cur.next = ne.next
ne.next = cur
pre.next = ne
pre = pre.next.next
return dummy.next
Leetcode 19
题目:删除链表倒数第N个
学习资料:代码随想录
初始思路
- 两个距离为n的前后指针,其中cur含义为假设当前指针所指位置为最后一个,re指针含义就为倒数第n个节点的前一个节点。
- 思路有点类似滑动窗口,先确定窗口终止位置cur的位置,然后一起滑动;cur的初始位置就是虚拟节点后第n个节点
- 根据定义,那么当cur.next 为none时就停止。
- 考虑头节点的情况,引入虚拟节点
学习后
- 思路基本一致
- 学习其他方法后,感觉利用栈的思路也不错,先把所有入栈,然后遍历n次出栈,当前栈顶元素即为要被删除的前一个节点;空间复杂度较高
实现过程
- 重点要按照自己的定义来思考边界条件,如何处理
- 使用dummy节点
思路一
dummy = ListNode(next=head)
cur = dummy
re = dummy
for _ in range(n):
cur = cur.next
while cur.next:
cur = cur.next
re = re.next
re.next = re.next.next
思路二
dummy = ListNode(0, head)
s = list()
cur = dummy
while cur:
s.append(cur)
cur = cur.next
for i in range(n):
s.pop()
prev = s[-1]
prev.next = prev.next.next
return dummy.next
面试题02.07
题目:链表相交
学习资料:代码随想录
初始思路
- 利用hash存储,空间复杂度较高
学习后
- 先遍历自身链表,再遍历另一个链表;两个指针同时进行这一个操作,当两个指针相等时,即为相交节点。如果不存在这种情况即公共部分长度为0,则为null
- 理解如下图,当A遍历后,从B开始到达相交节点所走的距离为:a-c + c; 当B遍历后,从B开始到达相交节点所走的距离为:b-c + c
实现过程:
A = headA
B = headB
while(A!=B):
A = A.next if A else headB
B = B.next if B else headA
return A
Leetcode142
题目:环形链表
学习资料:代码随想录
初始思路
- 使用set来记录,如果出现重复即为环入口;存储的是指针而不是val值
学习后
- fast,slow指针,fast走2步,slow走1步,fast与slow一定在环中相遇。
- 如何判断环开始位置?
- 假设x为从头到入环口距离,y为slow从环到相遇点距离,z为从相遇点到入口点距离
- 那么相遇就有,slow走过的为x+y,fast走过的为n(z+y)+x
- 那么由于相差两倍,所以 2*(x+y) = n(z+y)+x;x = (n-1)(y+z)+z; n 大于等于1
- 当n=1时,x=z说明,从头到入口的距离和从相遇点到入口的距离相等。
- 这个方法需要的推理证明较多,较难理解
思路一
temp = set()
p = head
while p != None:
if p not in temp:
temp.add(p)
p = p.next
else:
return p
return None
思路二
slow = head
fast = head
while fast and fast.next:
slow = slow.next
fast = fast.next.next
if slow == fast:
index1 = head
index2 = slow
while index1 != index2:
index1 = index1.next
index2 = index2.next
return index1
return None
总结
- 重点为前两个题,后两个题有很多trick;用hash也不错
- 链表题一定要手动画图,还原指针变化的过程