面向小白的 力扣25. K 个一组翻转链表

237 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第10天,点击查看活动详情

一起来学点算法,这里是慢慢学算法,我是小coder,昨天我们学习了反转链表,今天我们来进阶一下k个一组反转链表,这是一道hard题,我们来实现一下。

这里简单介绍一下保护节点,后续会用到:保护节点是我们在上一个指向下一个为了防止头节点为空,发生空指针,所以增加保护节点。

题目描述

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

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

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

image.png

题目分析

我们昨天完成了链表的反转,今天我们来指定链表反转,就是k个为一组,那首先我们就需要把链表进行分组,找到开始和截止,接着用昨天的反转方法处理内部反转,反转之后处理边界,然后再找到下一个就可以了。

解题思路

  1. 确定操作数组:本题中,操作数组就一个head
  2. 确定操作条件:操作条件为遍历所有节点。
  3. 确定操作过程:操作过程为:分组反转,首先找到分组(head - end),然后对分组进行反转,之后处理边界,处理边界的时候新增保护节点,防止处理边界时出错。
  4. 确定结果返回:将反转后的头节点返回(保护节点的下一个节点)

代码

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode reverseKGroup(ListNode head, int k) {
        ListNode protect = new ListNode(0,head);
        ListNode last = protect;
        while(head != null){
        
            ListNode end=getEnd(head,k);
            if(end == null) break;
           ListNode nextGroupStart = end.next;
            reverseList(head,nextGroupStart);
            head.next=nextGroupStart;
            last.next=end;
            last = head;
            head = nextGroupStart;

        }
        return protect.next;
    }

  public ListNode getEnd(ListNode head, int k){
        while(head !=null){
            k--;
            if(k==0) return head;
            ListNode end = head.next;
            head=end;
        }
        return null;
    }

     public void reverseList(ListNode head,ListNode stop) {
     ListNode last =head;
     head =head.next;
      while(head !=stop){
         ListNode nextNode= head.next;
         head.next=last;
         last = head;
         head=nextNode;

      }

    }

}

题目总结

本题的难度在于反转之后边界的处理和分组还有节点返回,综合性还是有的,不过只要把任务分解,就容易处理一些了。