zoukankan      html  css  js  c++  java
  • LeetCode25-K个一组反转链表

    题目描述

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

    示例:
    给你这个链表:1->2->3->4->5
    当 k = 2 时,应当返回: 2->1->4->3->5
    当 k = 3 时,应当返回: 3->2->1->4->5

    说明:
    你的算法只能使用常数的额外空间。
    你不能只是单纯的改变节点内部的值,而是需要实际进行节点交换。

    分析

    反转链表的变形,思路比较简单,但是真写起来有很多细节的地方需要注意。
    我自己的思路就是K个一组进行翻转,翻转后链接起来,不足的就不翻转

    我的题解

        public ListNode reverseKGroup(ListNode head, int k) {
            if (k<=1)return head;
            ListNode res = null;
    //已经翻转了的头H,已经翻转了的尾T,下一个待翻转的头N
            ListNode H = head;
            ListNode T = head;
            ListNode N = head.next;
            ListNode tmp ;
            int num ;//用于判断后面有没有K个节点
            ListNode lastTail = null;
            while (N!=null){
                tmp = H;
                num = 0;
                while (tmp!=null && num<=k){
                    num++;
                    tmp = tmp.next;
                }
                if (num<k){//后面不足k个节点,结束
                    if (lastTail!=null)lastTail.next = H;
                    break;
                }else{
                    //这4步用于交换两个节点
                    num = 0;//统计已经交换的节点
                    while (num<k-1){
                        T.next = N.next;
                        N.next = H;
                        H = N;
                        N = T.next;
                        num++;
                    }
                    if (lastTail==null)lastTail = T;
                    else{
                        lastTail.next = H;
                        lastTail = T;
                    }
                    if (res==null)res = H;//判断是不是第一次翻转k个,是就赋值res为第一次翻转的链表尾,即元链表的第k个
                    //切换到下一组
                    H = N;
                    T = N;
                    N = N==null?null: N.next;
                }
            }
            if (res==null)res = head;
            return res;
        }
    

    写得有点复杂了,感觉不太好。

    看了下题解,有其他的解法:

    • 可以使用递归,降低了逻辑上的复杂度
    • 尾插法:就是组内把前面的搬到后面,翻转的不同方法而已,不过这里很适合。
    • 辅助栈(题目要求常数空间,栈需要O(K)空间)

    尾插法

        public ListNode reverseKGroup(ListNode head, int k) {
            ListNode dummy = new ListNode(0);
            dummy.next = head;
            ListNode pre = dummy;
            ListNode tail = dummy;
            while (true) {
                int count = 0;
                while (tail != null && count != k) {
                    count++;
                    tail = tail.next;
                }
                if (tail == null) break;
                ListNode head1 = pre.next;
                while (pre.next != tail) {
                    ListNode cur = pre.next;
                    pre.next = cur.next;
                    cur.next = tail.next;
                    tail.next = cur;
                }
                pre = head1;
                tail = head1;
            }
            return dummy.next;
        }
    

    递归

        public ListNode reverseKGroup(ListNode head, int k) {
            ListNode cur = head;
            int count = 0;
            while (cur != null && count != k) {
                cur = cur.next;
                count++;
            }
            if (count == k) {
                cur = reverseKGroup(cur, k);
                while (count != 0) {
                    count--;
                    ListNode tmp = head.next;
                    head.next = cur;
                    cur = head;
                    head = tmp;
                }
                head = cur;
            }
            return head;
        }
    

        public ListNode reverseKGroup(ListNode head, int k) {
            Deque<ListNode> stack = new ArrayDeque<ListNode>();
            ListNode dummy = new ListNode(0);
            ListNode p = dummy;
            while (true) {
                int count = 0;
                ListNode tmp = head;
                while (tmp != null && count < k) {
                    stack.add(tmp);
                    tmp = tmp.next;
                    count++;
                }
                if (count != k) {
                    p.next = head;
                    break;
                }
                while (!stack.isEmpty()){
                    p.next = stack.pollLast();
                    p = p.next;
                }
                p.next = tmp;
                head = tmp;
            }
            return dummy.next;
        }
    
  • 相关阅读:
    Luogu P2391 白雪皑皑 && BZOJ 2054: 疯狂的馒头 并查集
    Luogu P3391 文艺平衡树(Splay or FHQ Treap)
    [笔记] 平衡树合集(Treap,Splay,替罪羊,FHQ Treap)
    P1353_[USACO08JAN]跑步Running 我死了。。。
    Luogu P1436 棋盘分割 暴力DP
    Luogu P1131 [ZJOI2007]时态同步 树形DP
    Luogu P1282 多米诺骨牌 DP。。背包?
    Luogu P1273 有线电视网 树形DP
    Luogu P1272 重建道路 树形DP
    Luogu P1156 垃圾陷阱 DP
  • 原文地址:https://www.cnblogs.com/XT-xutao/p/12900210.html
Copyright © 2011-2022 走看看