zoukankan      html  css  js  c++  java
  • 【每日一题-leetcode】25.reverse-nodes-in-k-group

    25.K 个一组翻转链表

    难度困难416

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

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

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

    示例:

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

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

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

    说明:

    • 你的算法只能使用常数的额外空间。
    • 你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。
     /***
             * 迭代法
             * 1.链表分区已翻转 + 待翻转 + 未翻转部分
             * 2.翻转前确定翻转的范围 通过k来决定
             * 3.记录链表前驱和后继 方便翻转完成后,把已翻转和未翻转连接起来。
             * 4.初始化两个边路pre  end  pre >代表待翻转链表的前驱,end代表待翻转的末尾。
             * 5.经过k次 end到达链表末尾。  记录待翻转链表的后继 next = end.next
             * 6.翻转链表,将三部分连接起来,然后重置pre 和 end 指针 进入下一个循环
             * 7.特殊情况 翻转部分长度不足k时,在定位end 完成后,end = null 已经到达末尾。
             * 8.时间复杂度为 O(n*K) 最好的情况为 O(n) 最差的情况未 O(n^2)
             * 9.空间复杂度为 O(1)
             * @param head
             * @param k
             * @return
             */
            public ListNode reverseKGroup(ListNode head, int k) {
                ListNode dumy = new ListNode(0);
                dumy.next = head;
        
                ListNode pre = dumy;
                ListNode end = dumy;
        
                while (end.next != null) {
                    //确定待翻转的范围
                    for (int i = 0; i < k && end != null; i++) {
                        end = end.next;
                    }
        
                    if (end == null) {
                        break;
                    }
        
                    ListNode start = pre.next;//待翻转链表的开始位置
                    ListNode next = end.next;//下一个待翻转链表的起始位置
        
                    end.next = null;//和后继待翻转链表断开
        
                    pre.next = reverse(start);
                    start.next = next;
                    pre = start;
        
                    end = pre;
                }
                return dumy.next;
            }
        
            public static ListNode reverse(ListNode head) {
                ListNode pre = null;
                ListNode curr = head;
                //假设 1 -> 2 -> 3
                while (curr != null) {
                    ListNode next = curr.next; // next = 2   // next = 3
                    curr.next = pre;// 1.next = null        // 3.next = 1
                    pre = curr;// pre = 1;                 //  1 = 3
                    curr = next; // curr = 2              // 3  = null
                }
                return pre; //
            }
    
  • 相关阅读:
    链表--判断一个链表是否为回文结构
    矩阵--“之”字形打印矩阵
    二叉树——平衡二叉树,二叉搜索树,完全二叉树
    链表--反转单向和双向链表
    codeforces 490C. Hacking Cypher 解题报告
    codeforces 490B.Queue 解题报告
    BestCoder19 1001.Alexandra and Prime Numbers(hdu 5108) 解题报告
    codeforces 488A. Giga Tower 解题报告
    codeforces 489C.Given Length and Sum of Digits... 解题报告
    codeforces 489B. BerSU Ball 解题报告
  • 原文地址:https://www.cnblogs.com/qxlxi/p/12860689.html
Copyright © 2011-2022 走看看