给定一个链表,旋转链表,将链表每一个节点向右移动 k 个位置,其中 k 是非负数。java
Given a linked list, rotate the list to the right by k places, where k is non-negative.python
示例 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
若是你看过上周的文章:LeetCode 189:旋转数组,和本篇文章旋转链表除了承载数据的结构变了,其余都同样,简单说一下指针
不断反转特定长度数组:code
输入:1->2->3->4->5递归
反转整个数组: 5->4->3->2->1get
拆分链表前k位为一段:5->4 , 3->2->1io
反转前k位:4->5class
反转剩余的:1->2->3
链接并输出: 4->5->1->2->3
按照这个思路,只需三次反转链表便可,而反转链表咱们已经在文章 LeetCode 206:反转链表 中已经详细的介绍过了,用了迭代、递归两种方法,因此按照上述解该题的方法也能够用两种方法实现。
按上述思路解,与旋转数组那道题大同小异,来介绍另外一种很简单高效的方法。
观察输入输出:
输入:1->2->3->4->5,k=2 输出:4->5->1->2->3
在节点3后切断链表:1->2->3,4->5
将头节点链接到尾节点:4->5->1->2->3
输出:4->5->1->2->3
得益于链表的特性,明显这种方式更简单,而节点3的位置恰好就是 len-k
(len为链表长度)。只需在第 len-k
个节点以后切断,首尾链接便可。
另外 k 可能大于链表长度,应当作求余运算 k=k%len
。考虑到切断的节点位置多是最后一个节点,或者是位置 0 (即头节点前),明显不用作切断节点,可是按上述操做就会出现指针溢出报错,能够率先将首尾节点相连,组成环形链表。
class Solution { public ListNode rotateRight(ListNode head, int k) { if (head == null || head.next == null || k == 0) return head; int len = 1; ListNode cur = head; while (cur.next != null) {//计算链表长度 cur = cur.next; len++; } cur.next = head; int mod = len - k % len;//切断节点的位置 cur = head; while (--mod > 0) cur = cur.next;//找到切断节点 ListNode newHead = cur.next;//新链表头节点 cur.next = null;//切断 return newHead; } }
class Solution: def rotateRight(self, head: ListNode, k: int) -> ListNode: if not head or not head.next or not k: return head cur = head len = 1 while cur.next: len += 1 cur = cur.next cur.next = head cur = head mod = len - k % len while mod - 1 > 0: cur = cur.next mod -= 1 newHead = cur.next cur.next = None return newHead
欢迎关注 公&众号一块儿学习:爱写Bug