给定一个链表,旋转链表,将链表每个节点向右移动 k 个位置,其中 k 是非负数。
示例 1:
输入: 1->2->3->4->5->NULL, k = 2
输出: 4->5->1->2->3->NULL
解释:
向右旋转 1 步: 5->1->2->3->4->NULL
向右旋转 2 步: 4->5->1->2->3->NULL
示例 2:
输入: 0->1->2->NULL, k = 4
输出: 2->0->1->NULL
解释:
向右旋转 1 步: 2->0->1->NULL
向右旋转 2 步: 1->2->0->NULL
向右旋转 3 步: 0->1->2->NULL
向右旋转 4 步: 2->0->1->NULL
@Data public static class ListNode { private int val; private ListNode next; public ListNode(int val) { this.val = val; } }
解法1: 一次一次的把节点向后移动一位,时间复杂度是O((k%n)n)
public static ListNode rotateRight(ListNode head, int k) { /*定义一个哑节点*/ ListNode dumb = new ListNode(0); /*哑节点的下一个节点指向头节点*/ dumb.next = head; /*定义一个引用指向哑节点*/ ListNode h = dumb; /*定义一个临时节点指向哑节点*/ ListNode temp = dumb; /*链表长度*/ int count = 0; while (head != null) { count++; head = head.next; } /*计算实际要向前走的步数*/ if (count != 0) { k = k % count; } /*当k不为0时继续循环*/ while (k > 0) { /*尾节点的前一个节点*/ ListNode finalBefore = null; /*头节点*/ ListNode h1 = temp.next; /*当未到达尾节点时继续循环*/ while (dumb.next != null) { /*赋值尾节点的前一个节点*/ if (dumb.next.next == null) { finalBefore = dumb; } /*引用指向自身的下一个节点*/ dumb = dumb.next; } /*当尾节点的前一个节点不为空时,把自己的下一个节点变为null*/ if (finalBefore != null) { finalBefore.next = null; } /*定义一个引用指向尾节点*/ ListNode fina = dumb; /*当尾节点和头节点相等时,说明链表里只有一个节点,直接返回*/ if (fina == h1) { return fina; } /*哑节点的下一个节点指向尾节点*/ temp.next = fina; /*尾节点的下一个指向头节点*/ fina.next = h1; k--; } return h.next; }
解法2:把链表结成一个环,用一个指针在环上移动,然后再分开,定义头节点和尾节点,时间复杂度O(n);
public static ListNode rotateRight1(ListNode head, int k) { /*判断如果链表里没有元素返回null*/ if (head == null) { return null; } /*定义一个哑节点*/ ListNode dumb = new ListNode(0); /*哑节点的下一个节点指向头节点*/ dumb.next = head; /*定义一个遍历引用,指向头节点*/ ListNode traver = head; /*链表数量*/ int total = 1; /*计算链表数量且找到尾节点*/ while (traver.next != null) { traver = traver.next; total++; } /*定义一个尾节点引用*/ ListNode fina = traver; /*尾节点的下一个节点指向头节点,形成一个环形链表*/ fina.next = head; /*计算从投节点开始的指针要走的步数*/ int count = total - k % total - 1; /*定义一个指针,赋值头节点*/ ListNode point = head; /*指针沿着环走*/ while (count > 0) { point = point.next; count--; } /*把哑节点的下一个节点指向指针的下一个节点*/ dumb.next = point.next; /*把指针的下一个节点置为null,当作尾节点*/ point.next = null; /*返回哑节点的下一个节点*/ return dumb.next; }