LeetCode 25. Reverse Nodes in k-Group

栏目: 数据库 · 发布时间: 5年前

内容简介:给定一个链表,k个一组反转链表。

本文为LeetCode 25. Reverse Nodes in k-Group 的题解。

题意

给定一个链表,k个一组反转链表。

k 是一个正数,且小于链表长度。如果按照k个一组,最后剩下的不组k,则不反转剩下的元素。

例子:

对于链表: 1->2->3->4->5

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

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

注意:

  • 只允许O(1)的空间复杂度。
  • 不可以改变节点的值。

题解

这个题目麻烦的地方在于边界情况太多。但简单而言,可按照如下处理:

  1. k个一组分组,满k个为完整组,不满k个为不完整组
  2. 对于完整组,反转,然后接到结果中
  3. 对于不完整组,直接接到结果中

代码

/**
 * https://www.robberphex.com/reverse-nodes-in-k-group/
 * Runtime: 1 ms, faster than 41.14% of Java online submissions for Reverse Nodes in k-Group.
 * Memory Usage: 38.5 MB, less than 24.80% of Java online submissions for Reverse Nodes in k-Group.
 */
class Solution {
    public ListNode reverseKGroup(ListNode head, int k) {
        int length = 0;

        // 存储返回结果的第一个和最后一个节点
        ListNode totalHead = null;
        ListNode totalTail = null;
        // 存储当前组中第一个和最后一个节点
        ListNode segHead = null;
        ListNode segTail = null;
        // 遍历
        while (head != null) {
            // 将当前元素放到组中队首
            // 即反转了顺序
            ListNode tmp = head.next;
            head.next = segHead;
            segHead = head;

            // group首
            if (length % k == 0) {
                segTail = head;
            }

            // group 尾
            if (length % k == k - 1) {
                // 如果结果的head没有出现,则设置
                if (totalHead == null) {
                    totalHead = segHead;
                }
                // 如果有队列尾,则将当前组添加到尾部
                if (totalTail != null) {
                    totalTail.next = segHead;
                }
                totalTail = segTail;
                // 开始新的组
                segHead = null;
            }

            head = tmp;
            length++;
        }

        // 如果还剩下不完整的组,我们需要再次反转
        // 将其转换为正序
        if (length % k != 0) {
            head = segHead;
            segHead = null;
            while (head != null) {
                ListNode tmp = head.next;
                head.next = segHead;
                segHead = head;
                head = tmp;
            }
        }
        // 将不完整组添加到结果中
        if (totalTail != null) {
            totalTail.next = segHead;
        } else {
            totalHead = segHead;
        }
        return totalHead;
    }

    public static void main(String[] args) {
        ListNode head = new ListNode(1);
        head.next = new ListNode(2);
        head.next.next = new ListNode(3);
        head.next.next.next = new ListNode(4);
        head.next.next.next.next = new ListNode(5);
        ListNode res = new Solution().reverseKGroup(head, 2);

        while (res != null) {
            System.out.print(res.val);
            System.out.print(", ");
            res = res.next;
        }
        System.out.println();
        // 输出 2, 1, 4, 3, 5,
    }
}

备注

看了下,还有更快的 0ms 的解法:

/**
 * https://www.robberphex.com/reverse-nodes-in-k-group/
 * Runtime: 0 ms, faster than 100.00% of Java online submissions for Reverse Nodes in k-Group.
 * Memory Usage: 38.5 MB, less than 24.52% of Java online submissions for Reverse Nodes in k-Group.
 */
class Solution {
    public ListNode reverseKGroup(ListNode head, int k) {
        ListNode cur = head;
        int cnt = 0;
        ListNode prev = null;
        while (cnt < k) {
            if (cur == null) {
                // 当前不足k个,直接返回
                return head;
            }
            prev = cur;
            cur = cur.next;
            cnt++;
        }
        // 将k个从原链表中切出来
        prev.next = null;

        // 反转原链表,这时prev是头,head是尾了
        reverse(head);

        // 继续递归分剩下的
        head.next = reverseKGroup(cur, k);

        return prev;
    }

    private ListNode reverse(ListNode head) {
        if (head == null || head.next == null) {
            return head;
        }
        ListNode newHead = reverse(head.next);
        head.next.next = head;
        head.next = null;
        return newHead;
    }

    public static void main(String[] args) {
        ListNode head = new ListNode(1);
        head.next = new ListNode(2);
        head.next.next = new ListNode(3);
        head.next.next.next = new ListNode(4);
        head.next.next.next.next = new ListNode(5);
        ListNode res = new Solution().reverseKGroup(head, 2);

        while (res != null) {
            System.out.print(res.val);
            System.out.print(", ");
            res = res.next;
        }
        System.out.println();
        // 输出 2, 1, 4, 3, 5,
    }
}

但是这个解法根本不符合要求啊,reverse空间复杂度 O(n) ,reverseKGroup空间复杂度 O(n/k)+O(n)≈O(n) 。希望LeetCode能够再完善下测试数据集。


以上所述就是小编给大家介绍的《LeetCode 25. Reverse Nodes in k-Group》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

白话大数据与机器学习

白话大数据与机器学习

高扬、卫峥、尹会生 / 机械工业出版社 / 2016-6 / 69

本书通俗易懂,有高中数学基础即可看懂,同时结合大量案例与漫画,将高度抽象的数学、算法与应用,与现实生活中的案例和事件一一做了关联,将源自生活的抽象还原出来,帮助读者理解后,又带领大家将这些抽象的规律与算法应用于实践,贴合读者需求。同时,本书不是割裂讲解大数据与机器学习的算法和应用,还讲解了其生态环境与关联内容,让读者更全面地知晓渊源与未来,是系统学习大数据与机器学习的不二之选: ·大数据产业......一起来看看 《白话大数据与机器学习》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换