LeetCode 61:旋轉連結串列 Rotate List
給定一個連結串列,旋轉連結串列,將連結串列每個節點向右移動 k 個位置,其中 k 是非負數。
Given a linked list, rotate the list to the right by k places, where k is non-negative.
示例 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:旋轉陣列,和本篇文章旋轉連結串列除了承載資料的結構變了,其他都一樣,簡單說一下
不斷反轉特定長度陣列:
輸入:1->2->3->4->5
反轉整個陣列: 5->4->3->2->1
拆分連結串列前k位為一段:5->4 , 3->2->1
反轉前k位:4->5
反轉剩餘的: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 (即頭節點前),明顯不用做切斷節點,但是按上述操作就會出現指標溢位報錯,可以率先將首尾節點相連,組成環形連結串列。
Java:
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;
}
}
Python3:
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