給定一個鏈表,旋轉鏈表,將鏈表每一個節點向右移動 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