春招打卡|k个一组反转链表|go实现

527 阅读2分钟

Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情

一、题目描述

给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。

图片.png

**输入:**head = [1,2,3,4,5], k = 2 输出: [2,1,4,3,5]

二、思路分析

  1. k个一组反转链表是基于反转链表1和翻转链表2题目基础上,进一步深入,细节处理会稍微麻烦一些。
  2. 首先创建一个头结点,避免边界处理有麻烦,遍历tail,每组结点的tail为组内最后一个元素,如果tail为空,则代表不满k个,当前组不需要翻转,直接返回链表。
  3. 当前组tail的后一个节点为下一组的头节点记录为nextGroupHead ,pre.Next为当前组的第一个节点。
  4. 反转链表后,head为最后一个节点,tail为头部节点,pre.next指向tail,head.Next指向下一组的head。
  5. 更新pre到当前组尾部,即pre =head,head到下一组头部,即head = nextGroupHead。

三、AC 代码

func reverseKGroup(head *ListNode, k int) *ListNode {
    dummynode := &ListNode{Next:head}
    pre := dummynode
    for head != nil {
        tail := pre
        for i :=0;i<k;i++ {
            tail = tail.Next
            if tail == nil {
            return dummynode.Next
        }
        }
       
    
    //记录tail后一个节点,以及pre后一个节点
    nextGroupHead := tail.Next
    head = pre.Next
    //反转
    reverseList(head,tail)
    //拼接
    pre.Next = tail
    head.Next = nextGroupHead
    //更新pre和head
    pre = head
    head = nextGroupHead
    }
    return dummynode.Next
}

func reverseList(head *ListNode,tail *ListNode) {
    var pre *ListNode
    cur := head
    for pre != tail{
        next := cur.Next
        cur.Next = pre
        pre = cur
        cur = next
    }
}

四、总结

k个一组反转链表,如果处理过反转链表1与翻转链表2,就会稍微简单一些。有一些细节要注意,比如建立头结点、翻转后的头尾节点互换后变量名使用会有一些绕,多做几次就会比较熟练。