首页 > 其他分享 >【K 个一组翻转链表】模拟

【K 个一组翻转链表】模拟

时间:2023-12-27 21:22:59浏览次数:40  
标签:head curHead ListNode 一组 curDummy next 链表 翻转

leetcode 25. K 个一组翻转链表

假设当前需要反转的子链表为[curHead, curTail]
curDummy:当前需要反转的子链表的虚拟节点
curHead:当前需要反转的子链表的头节点
curTail:当前需要反转的子链表的尾节点

  1. 找到尾节点curTail
  2. 反转子链表[curHead, curTail](反转子链表解法参考反转子链表题解2
  3. 更新curDummy、curHead
  4. 重复1、2、3步,直至尾节点curTail为null(子链表不满足长度),头节点curHead为null(已经反转完所有的子链表)

题解1

小细节:反转子链表时,如果head==tail,子链表长度为1时,记得将子链表与原链表断开,否则 while(curDummy.next != null)会死循环。

反转子链表——递归代码
/**
 * 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 dummy = new ListNode(0, head);
        ListNode curHead = head, curTail = head, curDummy = dummy;
        while(curHead != null) {
            curTail = cut(curHead, k);
            if(curTail == null) {
                curDummy.next = curHead;
                break;
            }
            ListNode next = curTail.next;
            curDummy.next = reverse(curHead, curTail);
            while(curDummy.next != null) curDummy = curDummy.next;
            curHead = next;
        }
        return dummy.next;
    }

    public ListNode cut(ListNode head, int len) { // 返回尾节点
        ListNode tail = head;
        -- len;
        while(tail != null && len -- > 0) {
            tail = tail.next;
        }
        if(len > 0) return null;
        return tail;
    }

    public ListNode reverse(ListNode head, ListNode tail) {
        if(head == tail) {
            head.next = null;
            return head;
        }
        ListNode res = reverse(head.next, tail);
        head.next.next = head;
        head.next = null;
        return res;
    }
}

题解2

小细节:该种解法没有断开子链表,因此 while(curDummy.next != next)循环直至子链表的下一个节点结束。

反转子链表——空间复杂度O(1)代码
/**
 * 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 dummy = new ListNode(0, head);
        ListNode curDummy = dummy, curHead = head, curTail;
        while(curHead != null) {
            curTail = findTail(curHead, k);

            if(curTail == null) {
                curDummy.next = curHead;
                break;
            }
            ListNode next = curTail.next;
            curDummy.next = reverse(curDummy, curHead, curTail, next);
            while(curDummy.next != next) curDummy = curDummy.next;
            curHead = next;
        }
        return dummy.next;
    }
    public ListNode findTail(ListNode head, int len) {
        -- len;
        while(head != null && len -- > 0) {
            head = head.next;
        }
        if(len > 0) return null; // 此时子链表不满足长度len
        return head;
    }
    public ListNode reverse(ListNode dummy, ListNode head, ListNode tail, ListNode next) {
        ListNode suc = head.next;
        while(suc != next) {
            head.next = suc.next;
            suc.next = dummy.next;
            dummy.next = suc;
            if(head != next) suc = head.next;
        }
        return dummy.next;
    }
}

标签:head,curHead,ListNode,一组,curDummy,next,链表,翻转
From: https://www.cnblogs.com/Eve7Xu/p/17931381.html

相关文章

  • 代码随想录算法训练营第十五天 | 层序遍历 ,226.翻转二叉树,101.对称二叉树
    一、二叉树层序遍历题目链接:LeetCode102.二叉树的层序遍历LeetCode107.二叉树的层序遍历IILeetCode199.二叉树的右视图LeetCode637.二叉树的层平均值LeetCode429.N叉树的层序遍历LeetCode515.在每个树行中找最大值LeetCode116.填充每个节点的下一个右侧节......
  • 单向链表
    突然发现一直没有链表1/*输入n,再输入n个(0-100)之间的正整数2(1)按输入次序建立单链表,并输出链表的值;(10分)3(2)对链表按值从小到大排序,并输出链表的值;(15分)4(3)删除值相同的结点,输出链表的值;(10分)5(4)将链表倒序,并输出。(5分)6例如:输入(文件名Test1.t......
  • 反转链表
    描述给定一个单链表的头结点pHead(该头节点是有值的,比如在下图,它的val是1),长度为n,反转该链表后,返回新链表的表头。数据范围:0≤n≤1000要求:空间复杂度O(1),时间复杂度O(n)。如当输入链表{1,2,3}时,经反转后,原链表变为{3,2,1},所以对应的输出为{3,2,1}。/***structListNo......
  • 反转链表指定区间
    描述将一个节点数为size链表m位置到n位置之间的区间反转,要求时间复杂度O(n),空间复杂度O(1)。例如:给出的链表为1→2→3→4→5→NULL,m=2,n=4,返回1→4→3→2→5→NULL.数据范围:链表长度0<size≤1000,0<m≤n≤size,链表中每个节点的值满足要求:时间复杂度O(n),空间......
  • 【线性表】链表
    本来要先讲数组的,介于之前已经总结过可变数组vector了,故不再开一个专题去介绍用法和原理。但是要提一嘴:数组作为数据结构可以高效地存储和查询给定索引(下标)的数据,其时间复杂度均为O(1),因为这个性质,数组可以用来模拟其他很多数据结构,但是如果要将整个数组进行移位操作,例如在中间插......
  • nordic—RTC+PPI定时驱动某外设做非单次触发(本次测试为驱动GPIO口做电平翻转)
    简介:在nordic的开发中使用到RTC时,对于比较通道0/1/2/3的中断来说如果不进行相关配置(如SDK中例子,使用的RTC比较通道就只能触发一次,不能多次触发),会导致比较中断只进入一次,如果说是使用RTC+PPI+ADC进行采样或者RTC+PPI+GPIOTE做IO口翻转等,都会只采样一次或者翻转一次就停止了,不能做的......
  • CSP-S 2023消消乐 字符串哈希做法and链表优化dp做法
    做完这题感觉整个人都升华了...打算说一下两种做法,字符串哈希和dp均可。dp则需要维护一个前向星去检索出第一个符合要求的位置。题解明天补,先写高数了。#include<bits/stdc++.h>#defineintlonglong#defineullunsignedlonglong#definerep(i,a,b)for(inti=(a);i<......
  • C++简单实现list链表数据结构(一)
    链表(list)是一种物理存储单元上非连续的存储结构,数据元素的逻辑顺序是通过链表中的指针链接实现的。链表的组成:链表由一系列结点组成结点的组成:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域C++STL中的链表是一个双向循环链表由于链表的存储方式并不是连续的内存空......
  • 142. 环形链表Ⅱ
    给定一个链表的头节点head,返回链表开始入环的第一个节点。如果链表无环,则返回null。如果链表中有某个节点,可以通过连续跟踪next指针再次到达,则链表中存在环。不允许修改链表。整数pos来表示链表尾连接到链表中的位置(索引从0开始)。如果pos是-1,则在该链表中没有环。......
  • c语言单链表
    #include<stdio.h>#include<stdlib.h>#defineERROR-1#defineSUCCESS0structlist_node{intdata;structlist_node*next;/*data*/};typedefstructlist_nodelink_list;intlist_get_size(link_list*list){intcount=0;......