func(h *IntHeap)Pop()interface{} { old := *h n := len(*h) x := old[n-1] *h = old[:n-1] return x }
funcmergeKLists(lists []*ListNode) *ListNode { l := len(lists) if l == 0 { returnnil } h := &IntHeap{} for i:=0; i<l; i++ { if lists[i] == nil { continue } node := lists[i] for node != nil { *h = append(*h, node.Val) node = node.Next } } if h.Len() == 0 { returnnil } heap.Init(h)
head := &ListNode{ Val : (*h)[0], Next : nil, } t := head heap.Pop(h) for h.Len() > 0 { x := heap.Pop(h).(int) node := &ListNode{ Val : x, Next : nil, } t.Next = node t = node }
/** * Definition for singly-linked list. * type ListNode struct { * Val int * Next *ListNode * } */ funcremoveNthFromEnd(head *ListNode, n int) *ListNode { fast, slow := head, head for i:=0; i<n; i++ { fast = fast.Next } if fast == nil { //fast指向nil,说明n=链表的节点数,即删除第一个节点 return head.Next }
for fast.Next != nil { // 定位到要删除节点的前一个节点 fast = fast.Next slow = slow.Next } slow.Next = slow.Next.Next return head }
/** * Definition for singly-linked list. * type ListNode struct { * Val int * Next *ListNode * } */ funcgetIntersectionNode(headA, headB *ListNode) *ListNode { a, b := headA, headB for a != b { if a != nil { a = a.Next } else { a = headB }
if b != nil { b = b.Next } else { b = headA } } return a }
这样,这道题就解决了,空间复杂度为 O(1),时间复杂度为 O(N)。
反转链表
反转整个链表
递归
1 2 3 4 5 6 7 8 9
funcreverse(head *ListNode) *ListNode { if head.Next == nil { // 递归出口 return head } last := reverse(head.Next) head.Next.Next = head head.Next = nil return last }
迭代
1 2 3 4 5 6 7 8 9 10 11 12 13 14
funcreverse(head *ListNode) *ListNode { first := head.Next.Next second := head.Next third := head head.Next = nil for first != nil { second.Next = third third = second second = first first = first.Next } second.Next = third return second }
反转链表前n个节点
比如说对于下图链表,执行 reverseN(head, 3):
递归
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
var successor *ListNode // 后驱节点 successor = nil
funcreverseN(head *ListNode, n int) *ListNode { if n == 1 { successor = head.Next return head } last := reverseN(head.Next,n-1) head.Next.Next = head head.Next = successor return last }
funcreverseN(head *ListNode, n int) *ListNode { first := head.Next.Next second := head.Next third := head if n == 1 { // n=1,不需要翻转 return head } if n == 2 { // n=2,直接翻转前两个节点即可 second.Next = third third.Next = first return second } for n-2 > 0 { // n>2时的情况,结合上图来推一遍会比较清晰 second.Next = third third = second second = first first = first.Next n-- } second.Next = third third.Next = first return second }
反转链表的一部分
给一个索引区间 [m,n](索引从 1 开始),仅仅反转区间中的链表元素。
递归
1 2 3 4 5 6 7 8
funcreverseBetween(head *ListNode, m,n int) *ListNode { if m == 1 { // base case return reverseN(head,n) // 相当于反转前n个元素 } // 前进到反转的起点触发 base case head.Next = reverseBetween(head.Next, m-1, n-1) return head }
/** * Definition for singly-linked list. * type ListNode struct { * Val int * Next *ListNode * } */ funcisPalindrome(head *ListNode)bool { if head == nil || head.Next == nil { returntrue }
fast, slow := head, head for fast != nil && fast.Next != nil { // 找到链表的中间位置 fast = fast.Next.Next slow = slow.Next }
if fast == nil { // 偶数串,slow指向后半部分的第一个节点处 backHead := reverse(slow) for backHead != nil { if backHead.Val != head.Val { returnfalse } backHead = backHead.Next head = head.Next } } else { // 奇数串,slow指向前后两段的正中间 slow = slow.Next backHead := reverse(slow) for backHead != nil { if backHead.Val != head.Val { returnfalse } backHead = backHead.Next head = head.Next } } returntrue }
funcreverse(head *ListNode) *ListNode { pre, cur := head, head.Next for cur != nil { nxt := cur.Next cur.Next = pre pre = cur cur = nxt } head.Next = nil return pre }
Post title:链表习题解析
Post author:洪笳淏
Create time:2021-09-24 20:10:00
Post link:https://jiahaohong1997.github.io/2021/09/24/链表习题解析/
Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.