首页 > 其他分享 >LeetCode25.K个一组翻转链表

LeetCode25.K个一组翻转链表

时间:2025-01-19 11:13:21浏览次数:1  
标签:head ListNode next 链表 tail LeetCode25 节点 翻转

题目:

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

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

你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。

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

思路:

  • 构建一个伪节点
  • 遍历链表,每 k个循环一次
  • 找到这k个节点的首尾节点
  • 反转链表
  • 将反转后的链表拼接回原来的链表

代码:


    public ListNode reverseKGroup(ListNode head, int k) {
        //伪节点
        ListNode fake = new ListNode(0);
        fake.next = head;
        ListNode pre = fake;

        while (head != null) {
            ListNode tail = pre;
            // 查看剩余部分长度是否大于等于 k
            for (int i = 0; i < k; ++i) {
                tail = tail.next;
                if (tail == null) {
                    return fake.next;
                }
            }
            ListNode nex = tail.next;
            //反转链表,返回链表的首尾节点
            ListNode[] reverse = myReverse(head, tail);
            head = reverse[0];
            tail = reverse[1];
            // 把子链表重新接回原链表
            pre.next = head;
            tail.next = nex;
            pre = tail;
            head = tail.next;
        }

        return fake.next;
    }



    /**
     *   反转链表
     */
    public ListNode[] myReverse(ListNode head, ListNode tail) {
        ListNode prev = tail.next;
        ListNode p = head;
        while (prev != tail) {
            ListNode nex = p.next;
            p.next = prev;
            prev = p;
            p = nex;
        }
        return new ListNode[]{tail, head};
    }


}



另一种解法:

这种解法,反转链表跟普通的反转链表一样。可以顺便练一下反转链表。
如果追求 通过率,用这种方式好些。

class Solution {
    public ListNode reverseKGroup(ListNode head, int k) {
        //k个一组反转链表
        //创建一个虚拟节点
        ListNode fake = new ListNode(0);
        fake.next = head;

        //pre 代表待翻转链表的前驱,end 代表待翻转链表的末尾
        ListNode pre = fake;
        ListNode end = fake;


        while (end.next!=null) {
            //检查下剩下的还有没有 k 个
            for (int i=0;i<k && end!=null;i++) {
                end = end.next;
            }
            //记录待翻转链表的后继 end,如果 end为 null,说明已经到达末尾了,不足k个。
            if (end == null) {
                break;
            }
            
            //先记下待翻转的首节点、尾节点
            ListNode start = pre.next;
            ListNode next = end.next; 
            //k个一组,先断开链表
            end.next = null;
            //翻转链表, pre.next指向翻转后的链表
            pre.next = reverse(start);
            //翻转之后,start变成了已翻转部分的末尾,需要跟未翻转部分连接。
            start.next = next;
            //重置变量,继续迭代
            pre = start;
            end = pre;

        }

        return fake.next;

    }



    /**
     *   反转链表
     */
    public ListNode reverse(ListNode head) {
        //反转链表
        if (head==null) {
            return null;
        }
        ListNode pre = null;
        ListNode curr = head;

        //上一个节点,当前节点,下一个节点
        //记住下一个节点
        while (curr!=null) {
            ListNode next = curr.next;
            //当前节点指向上一个节点
            curr.next = pre;
            
            //向后迭代,当前节点变成上一个节点,下一个节点,变成当前节点
            pre = curr;
            curr = next;
            
        }

        return pre;
    }



}

标签:head,ListNode,next,链表,tail,LeetCode25,节点,翻转
From: https://www.cnblogs.com/expiator/p/18679387

相关文章

  • 扬帆数据结构算法之雅舟航程,漫步C++幽谷——链表分类探析与双链表之定义与构筑
    人无完人,持之以恒,方能见真我!!!共同进步!!文章目录一、链表的分类二、双链表的实现1.双链表结构的定义2.双链表的初始化和销毁初始化函数1初始化函数2销毁函数3.双链表的打印以及节点的申请打印函数节点的申请4.双链表的头插和尾插头插函数尾插函数5.双链表的查找和......
  • 单链表
    单链表/*单链表*/#include<stdio.h>#include<stdlib.h>typedefstructNode{ intdata; structNode*next;}Node;Node*initList(){ Node*list=(Node*)malloc(sizeof(Node)); list->data=0; list->next=NULL; returnlist;}void......
  • 算法2-25 有序单链表删除重复元素(附加代码模式)
    题目描述根据一个递增的整数序列构造有序单链表,删除其中的重复元素本题是附加代码模式,主函数main和打印链表的代码会自动附加在同学们提交的代码后面,请同学们在提交的时候注释附加代码。附加代码如下:void PrintList(const List &list){    Node *p = list->nex......
  • 介绍1个简单好用的英文文本翻转网站,关键还免费不用登录
    输入英文,会生成对应的翻转、反向、镜像、......
  • C语言数据结构编程练习-单向不带头链表的操作
    单向链表单向链表是由若干个节点组成的数据结构,每个节点包含两个部分:数据域和指针域。数据域存储节点的数据,指针域存储下一个节点的地址。  #include"03.h"voidfn3(){ intorder=0; elementTypeval; elementTypeelementVal; LinkNode*ListNode=NULL; ......
  • 代码随想录算法训练营第四天 | 24. 两两交换链表中的节点、19. 删除链表的倒数第N个节
    9-24.两两交换链表中的节点给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。 示例1:输入:head=[1,2,3,4]输出:[2,1,4,3]示例2:输入:head=[]输出:[]示例3:输入:head=[1]输出:[1] 提......
  • LeetCode:21.合并两个有序链表
    LeetCode:21.合并两个有序链表解题思路与归并排序中的合并两个有序数组很相似。将数组替换成链表就能解此题。解题步骤新建一个新链表,作为返回结果。用指针遍历两个有序链表,并比较两个链表的当前节点,较小者先接入新链表,并将指针后移一步。链表遍历结束,返回新链表。/***Defini......
  • 【LeetCode】回文链表
    【LeetCode】回文链表......
  • 数据结构——链表(概念,类型,java实现、增删、优缺点)
    文章目录链表链表介绍链表类型1.单向链表2.双向链表3.循环链表链表实现(增删改查)链表节点插入节点删除节点链表的特点与优势......
  • LeetCode:23.合并K个排序链表
    LeetCode:23.合并K个排序链表解题思路新链表的下一个节点一定是k个链表头中的最小节点。考虑选择使用最小堆。解题步骤构建一个最小堆,并依次把链表头插入堆中。弹出堆顶接到输出链表,并将堆顶所在链表的新链表头插入堆中。等堆元素全部弹出,合并工作就完成了。classMinHeap{......