今日题目:
24. 两两交换链表中的节点
19.删除链表的倒数第N个节点
面试题 02.07. 链表相交
142. 环形链表 II
今日总结
第一天刷栈和队列的题目,题目不难,但是实现的细节很丰富。算是对于之前栈和队列的复习了。栈实现队列不难,队列实现栈需要注意一个队列就能够实现。其中的Move操作需要仔细研究。
24. 两两交换链表中的节点
要点
- 添加虚拟头节点统一操作
- 反转过程类似于反转链表,需要使用tmp指针保证链表不断
- 按照我的做法,leftNode应该指向rightNode.Next.Next,不过官方解法只需要指向rightNode.Next
- 根据3 可以写出递归解法
代码:
func swapPairs(head *ListNode) *ListNode {
if head == nil || head.Next == nil {
return head
}
newHead := &ListNode{-1, head.Next}
LeftNode := head
rightNode := head.Next
for rightNode != nil {
tmp := rightNode.Next
rightNode.Next = LeftNode
if tmp == nil || tmp.Next == nil {
LeftNode.Next = tmp
break
}
LeftNode.Next = tmp.Next
LeftNode = tmp
rightNode = tmp.Next
}
return newHead.Next
}
19.删除链表的倒数第N个节点
要点:
- 使用类似快慢节点的想法,设置rightNode提前遍历N次链表,那么当rightNode变成nil的时候,leftNode刚好是倒数第N个节点的前一个节点
- 根据1,rightNode应该提前抢跑n+1次,才会让leftNode是目标的前一个节点而不是目标本身
func removeNthFromEnd(head *ListNode, n int) *ListNode {
if head == nil {
return head
}
newHead := &ListNode{-1, head}
leftNode := newHead
rightNode := newHead
for i :=0;i <=n;i++{
rightNode = rightNode.Next
}
for rightNode != nil {
leftNode = leftNode.Next
rightNode = rightNode.Next
}
leftNode.Next = leftNode.Next.Next
return newHead.Next
}
面试题 02.07. 链表相交
要点:
- 想到对齐两个链表就很简单了,如果A长了那么就A指针先 跑len(A)-len(B)次,这样两个指针同时运行就能刚好进行比较
- 更加高级的做法是当A指针遍历完A就将其赋值为B指针,B指针同理,这样的话,假设公共长度为C,A、B为非公共部分,两者遍历的总长度就会是A+B+C,即如果有公共部分就必定相遇
func getIntersectionNode(headA, headB *ListNode) *ListNode {
var lengthA, lengthB int
stepA, stepB := headA, headB
for headA != nil {
lengthA++
headA = headA.Next
}
for headB != nil {
lengthB++
headB = headB.Next
}
if lengthA >= lengthB {
dif := lengthA - lengthB
for i:=0;i < dif ;i++ {
stepA = stepA.Next
}
} else {
dif := lengthB - lengthA
for i:=0;i < dif ;i++ {
stepB = stepB.Next
}
}
for stepA != nil {
if stepA == stepB {
return stepA
} else {
stepA =stepA.Next
stepB = stepB.Next
}
}
return nil
}
142. 环形链表 II
要点:
- 最简单的做法就是哈希,记录出现过的元素
- 但是想让空间复杂度为O(1)的话就比较难了,之后再研究研究
- 注意map可以使用exist参数
func detectCycle(head *ListNode) *ListNode {
hash := make(map[*ListNode]int, 0)
//pre := &ListNode{0, head}
pos := 0
for head != nil {
_, exist := hash[head]; if !exist{
hash[head] = pos
pos++
} else {
return head
}
head = head.Next
}
return nil
}