61. 旋转链表

146 阅读1分钟

题目描述

image.png

方法一:把后K个整体挪到前面 O(N)

class Solution {
    public ListNode rotateRight(ListNode head, int k) {
        if (head == null) {
            return null;
        }
        ListNode dummy = new ListNode();
        dummy.next = head;
        //计算链表长度
        ListNode cur = dummy;
        int length = 0;
        while (cur.next != null) {
            cur = cur.next;//退出时cur停在最后一个节点
            length++;
        }
        //计算移动几个节点
        int step = k % length;
        //tmp为新的尾节点
        ListNode tmp = dummy;
        for (int i = 0; i < length - step; i++) {
            tmp = tmp.next;
        }
        //如果正好循环length轮,返回原链表
        if (tmp.next == null) {
            return head;
        }
        //把后k个节点移到head前面
        ListNode newHead = tmp.next;
        tmp.next = null;
        cur.next = head;
        return newHead;
    }
}

方法一:把最后一位挪到前面,挪K次 O(NK),不可取

class Solution {
    public ListNode rotateRight(ListNode head, int k) {
        if (head == null) {
            return null;
        }
        ListNode dummy = new ListNode();
        dummy.next = head;
        
        ListNode pre = dummy, cur = head;
        while (cur.next != null) {
            cur = cur.next;
            pre = pre.next;
        }

        if (pre == dummy) {
            return dummy.next;
        }

        for (int i = 0; i < k; i++) {
            pre.next = null;
            cur.next = dummy.next;
            dummy.next = cur;
            cur = pre;
            
            pre = dummy.next;
            while (pre.next != cur) {
                pre = pre.next;
            }
        }
        return dummy.next;
    }
}