K 个一组翻转链表

weblog 963 0 0

leetcode25题(困难)

原链接:https://leetcode-cn.com/problems/reverse-nodes-in-k-group/

问题描述

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

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

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

示例:

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

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

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

解题思路

整体思路是将原链表分成p(p=n个节点 / k)段(逻辑上的分),每段都有一个头节点和一个尾节点。

第一步先遍历一次整个原链表,当每一组节点满足有k个节点时,标记当前组的头节点和尾节点。

第二步翻转链表,改变每组的头节点和尾节点的引用。返回第一组的头节点即可。

这样的时间复杂度就是 O(n)+O(n/k)

示例

代码(java)

/**
 * 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) {
        return begin(head,k);
    }
    public static ListNode th;

    /**
     *  拼接反转的链表
     * @param listNode
     * @param k
     * @return
     */
    public static ListNode begin(ListNode listNode,int k){
        if(k==1){
            return listNode;
        }
        th=listNode;
        LinkedList<HeadTail> ov=new LinkedList();
        while(th!=null){
            ListNode head=th;
            ListNode tail=reversal(th,k);
            ov.addLast(new HeadTail(tail,head));
        }
        if(ov.size()==0){
            return null;
        }else{
            HeadTail headTail=ov.removeFirst();
            ListNode head=headTail.head;
            ListNode tail=headTail.tail;
            while(ov.size()>0){
                headTail=ov.removeFirst();
                tail.next=headTail.head;
                tail=headTail.tail;
            }
            return head;
        }
    }

    /**
     *  反转链表
     * @param node
     * @param k
     * @return
     */
    public static ListNode reversal(ListNode node,int k){
        ListNode p=null;
        ListNode n;
        int i=0;
        while(node.next!=null){
            n=node.next;
            node.next=p;
            p=node;
            node=n;
            i++;
            if(i==k-1){
                break;
            }
        }
        th=node.next;
        node.next=p;
        if(i<k-1){
            node=reversal2(node,k);
        }
        return node;
    }

    /**
     *  反转链表
     * @param node
     * @param k
     * @return
     */
    public static ListNode reversal2(ListNode node,int k){
        ListNode p=null;
        ListNode n;
        while(node.next!=null){
            n=node.next;
            node.next=p;
            p=node;
            node=n;
        }
        node.next=p;
        return node;
    }
    public static class HeadTail {
        ListNode head;
        ListNode tail;
        public HeadTail(ListNode head,ListNode tail){
            this.head=head;
            this.tail=tail;
        }
    }
}

猜你喜欢
official 1314 述给定二叉搜索树的根节点root,和整数k,请你设计算法查找其中第k最小元素(从1开始计数)。示例1输入:root=[3,1,4,null,2],k=1 输出:1示例2输入:root=[5
数据结构与算法 8005 单向t如下:t=1-2-3-4-5-6-7-8-9写方法反t如下:1-2-3-4-5-6-7-8-9=tjava代码:packagetest;/*** 节点类
数据结构与算法 1488 算法思想:对冒泡排序的种改进,每次从没有排序的集合a中拿取最大或最小的元素,放入有序的集合b中,直到a集合中的元素被取完算法描述:用变量i遍历整,用变量j遍历i后面的数,每次遍历i初始
数据结构与算法 2530 节点packageclub.test;/****节点*@authorjiajia**/publicclassNode{ publicintvalue; publicNodenext
java基础 1836 ++){ for(intj=0;j10;j++){ for(intk=0;k10;k++){ if(k==1){ breaka; } } } } }}在java中
数据结构,算法基础 840 连通,则q与p连通传递性:p与q连通且q与r连通,则p与r连通 二、算法实现首先我们用记录所有元素,对于set[i]==k,i示i元素,k示元素所属的集合,通常可以指向或者间接指向集合的
official 1035 请编写函数,使其可以删除某中给定的(非末尾)节点。传入函数的唯参数为要被删除的节点。现有--head=[4,5,1,9],它可以示为:示例1:输入:head=[4,5,1,9],n
计算机网络基础 2964 。字节:8二进制位构成1"字节(Byte)",它是存储空间的基本计量单位。1字节可以储存1英文字母或者半汉字,换句话说,1汉字占据2字节的存储空间。KB:在般的计量单位中,通常K示10
目录
没有一个冬天不可逾越,没有一个春天不会来临。最慢的步伐不是跬步,而是徘徊,最快的脚步不是冲刺,而是坚持。