1. 两两交换链表中的节点
- 第一想法:创建虚拟头指针,然后模拟
- 看到题解想法:思路差不多
- 遇到困难:循环内指针pre与n需要更新
public ListNode swapPairs(ListNode head) {
ListNode vHead = new ListNode(-1);
vHead.next = head;
// 循环语句条件包括了该两种情况
// if (head == null || head.next == null) return head;
ListNode pre = vHead;
ListNode n = head;
while (n != null && n.next != null) {
ListNode aft = n.next;
pre.next = n.next;
n.next = aft.next;
aft.next = n;
// 先给pre赋值为n,后更新n
pre = n;
n = n.next;
}
return vHead.next;
}
- 总结与收获:熟悉了虚拟头结点的使用,用时10min
2. 删除链表的倒数第N个节点
- 第一想法:一开始想到的是两次遍历,第一次算出节点总数,第二次找到倒数位置
- 看到题解想法:快慢指针比两次遍历运算速度快一些些,但是时间复杂度都是O(n)
- 遇到困难:快慢指针间隔的元素个数想了一阵子
1/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func removeNthFromEnd(head *ListNode, n int) *ListNode {
vHead := &ListNode {Val: -1, Next: head}
/** vHead := &ListNode {
Val: -1,
Next: head,
}**/
pre, curr, aft:= vHead, head, head
//快指针先往右移动n
for i := 0; i < n; i++ {
if aft == nil && i < n - 1 {
return nil;
}
aft = aft.Next
}
// 快慢指针一起移动,aft移动到最右
for aft != nil {
pre = pre.Next;
curr = curr.Next;
aft = aft.Next;
}
//删除当前节点
pre.Next = curr.Next
return vHead.Next;
}
- 总结与收获:由于学习需要,本题尝试使用Go语言编写,以练习Go语言语法知识,如:
- Go语言结构体单行赋值如代码所示,分行赋值需要在最后一条语句加逗号
- 循环语句都使用for,代替Java的while
- 变量声明赋值时,使用:=符号
3. 链表相交
- 第一想法:一刷时使用了哈希表进行解题;二刷知道规律
- 看到题解想法:和题解解法相似
- 遇到困难:使用标志位进行保存
1/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func getIntersectionNode(headA, headB *ListNode) *ListNode {
a, b := headA, headB
aFlag, bFlag := false, false
// 空链表直接返回null
if headA == nil || headB == nil {
return nil;
}
for !((aFlag == true && a == nil) || (bFlag == true && b == nil)) {
if a == b {
return a
}
a = a.Next
b = b.Next
if a == nil && aFlag == false {
aFlag = true
a = headB
}
if b == nil && bFlag == false {
bFlag = true
b = headA
}
}
return nil;
}
4. 环形链表II
- 第一想法:一刷想到用HashSet来判断是否存在重复元素,第一个出现的重复元素即为环形起点
- 看到题解想法:通过slow和fast指针来写,是另一种巧妙的方法,空间复杂度较低
- 遇到困难:公式推导没记住,不熟练
/**
* Definition for singly-linked list.
* type ListNode struct {
* Val int
* Next *ListNode
* }
*/
func detectCycle(head *ListNode) *ListNode {
slow, fast := head, head
for fast != nil && fast.Next != nil {
slow = slow.Next
fast = fast.Next.Next
if fast == slow {
var n1, n2 *ListNode
n1 = head
n2 = slow
for n1 != n2 {
n1 = n1.Next
n2 = n2.Next
}
return n1
}
}
return nil;
}