题解 | #牛群的重新分组#

牛群的重新分组

https://www.nowcoder.com/practice/267c0deb9a6a41e4bdeb1b2addc64c93

import java.util.*;

/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 *   public ListNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param head ListNode类 
     * @param k int整型 
     * @return ListNode类
     */
    public ListNode reverseKGroup (ListNode head, int k) {
        // write code here
        ListNode hair = new ListNode(0), cur = hair, next = null, p = head;
        hair.next = head;
        while (true) {
            for (int i = 0; i < k; i++) {
                if (p == null) return hair.next;
                p = p.next;
            }
            next = cur.next;
            if ((cur.next = reverseK(cur.next, k)) == next) break;
            cur = next;
        }
        return hair.next;
    }
    private ListNode reverseK(ListNode head, int k) {
        ListNode p = null, cur = head, next;
        while (k-- > 0) {
            next = cur.next;
            cur.next = p;
            p = cur;
            cur = next;
        }
        head.next = cur;
        return p;
    }
}

1、首先可以考虑实现对一个链表的前 k 项进行翻转

  • 基本思路是:定义一个虚拟头节点 p,用于遍历链表的指针 cur 和 指针 next,循环开启:
  • 先用 next 记录 cur 的下一个节点,
  • 借住 p 将 cur 指向翻转,即 cur.next = p;
  • 接着,p 向后移即 p = cur,cur 向后移即 cur = next
  • 循环出来后,p 就是翻转之后的链表头节点
  • 这里需要注意的是,对于前 k 项翻转,最后的 cur 指向到了原链表的第 k+1 个节点,而 head 的指向此时是 null,因此需要将 head 接到 cur 上即 head.next = cur,否则仅仅翻转了链表的前 k 项,后续链表节点会丢失

2、借助前 k 项翻转的实现方法,再进行 k 个一组的翻转实现

  • 基本思路是:定义一个虚拟头节点 hair,并将 hair.next = head,定义 cur 指向 hair
  • 定义一个 p 指针,用于判断链表剩余的节点个数是否足够 k 个,如果不够,说明后续节点不需要翻转,可以直接返回结果了
  • 如果足够,那么对前 k 项进行翻转
  • 这里做了一个特殊判断,即如果翻转后的节点等于next,表示没有翻转,即 k = 1,可以提前结束
#链表翻转#
线性表基础 文章被收录于专栏

链表、递归、栈

全部评论

相关推荐

Noob1024:一笔传三代,人走笔还在
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务