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;
    }
posted @ 2020-05-16 13:43  Edwin_Xu  阅读(133)  评论(0编辑  收藏  举报