1.1. 题目

1.1.1. K 个一组翻转链表

给你一个链表,每 k 个节点一组进行翻转,请你返回翻转后的链表。

k 是一个正整数,它的值小于或等于链表的长度。

如果节点总数不是 k 的整数倍,那么请将最后剩余的节点保持原有顺序。

示例 :

给定这个链表:1->2->3->4->5

当 k = 2 时,应当返回: 2->1->4->3->5

当 k = 3 时,应当返回: 3->2->1->4->5

说明 :

  • 你的算法只能使用常数的额外空间。
  • 你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。



1.1.2. 题解:

  • 这是递归反转链表的高级版
  • 按照题目要求是必须在原链表操作,不能另起一个链表进行赋值
  • 题目且要求是必须进行节点交换,不是把值换掉即可,不然可以把值复制出来,进行转换,然后重新赋值进去!哈哈哈

1.1.3. 思路:

  • 会做这题,必须会知道怎么去反转一个普通的单向链表!必须得先解反转链表
  • 然后这题就可以把一个大链表拆分一个个的小链表,然后把各个反转后的小链表连接起来
  • 我虽不擅长递归,但还是用递归来解了
  • 要注意,每k个遍历,得先把开始的节点保存下来,否则指针已经移动到k个后了...
比如链表是 1->2->3->4->5->6->6->7->8->9->10

先递归到最里面,每k个一组,那么就是 1->2->3 4->5->6 7->8->9 10

发现10后面没有了,且10所在的组不够k个,所以10直接返回!

递归开始往回走

7->8->9 一组, 开始反转 

得 9>8->7 , 并把7的next 指向 上面返回的值 也就是 10,然后返回 9所在的地址

递归继续往回走

4->5->6 一组,开始反转

得 6->5->4 , 并把4的next 指向 上面返回的值 也就是 9,然后返回 6所在的地址

递归继续往回走

1->2->3 一组, 开始反转

得 3->2->1 , 并把 1的next 指向 上面返回的值 也就是 6,然后返回3所在的地址

递归结束,返回上面的结果 3

最后打印结果  3->2->1->6->5->4->9->8->7->10

1.1.4. 代码:

点击显示
 // 反转一个普通的链表,返回反转后的链表头节点和最后的末尾节点,
 func reverse(head *ListNode) (res *ListNode, h *ListNode) {
     if head == nil || head.Next == nil {
         return head,head
     }
     s,h := reverse(head.Next)
     head.Next.Next = head
     head.Next = nil
     return s,head
 }
 func reverseK(head,ss *ListNode,k int) (res *ListNode) {
     // 定义一个节点=指针移动k个节点的下个节点
     var headN *ListNode
     // 存储一个当前节点,比如 1->2->3 指针已经移动到了3,但是转换的时候 还是得把1传进去
     oldHead := head
     for i:=0;i<k;i++ {
         // 如果正好符合k个,存储下个节点,把当前的指针的next指向nil,防止循环卡死
         if i == k - 1 {
             headN = head.Next
             head.Next = nil
         } else {
             if head != nil && head.Next != nil {// 如果不够k个,且后续还有节点,指针继续往后移动
                 head = head.Next
             } else {// 不符合k个且后续没有节点了,直接返回
                 return oldHead
             }
         }
     }
     // 递归,ss存储上个 一组数据反转的结果
     ss = reverseK(headN,ss,k)
     // 把小组数据进行反转,并返回反转后 链表的头节点和末尾节点
     s,h := reverse(oldHead)
     if ss == nil { // 如果是递归最里层,把最里层反转的小组的头节点进行赋值
         ss = s
     } else {
         h.Next = ss // 把当前小组的末尾指向上一层反转的头
     }

     return s
 }
 func reverseKGroup(head *ListNode, k int) *ListNode {
     // 如果 k = 1 ,直接不用反转了
     if k == 1 {
         return head
     }
     return reverseK(head,nil,k)
 }

github代码

results matching ""

    No results matching ""