61. Rotate List(python+cpp)
阿新 • • 發佈:2018-12-20
題目:
Given a linked list, rotate the list to the right by k places, where k is non-negative. Example 1:
Input: 1->2->3->4->5->NULL, k = 2 Output: 4->5->1->2->3->NULL Explanation: rotate 1 steps to the right: 5->1->2->3->4->NULL rotate 2 steps to the right: 4->5->1->2->3->NULL
Example 2:
Input: 0->1->2->NULL, k = 4 Output: 2->0->1->NULL Explanation: rotate 1 steps to the right: 2->0->1->NULL rotate 2 steps to the right: 1->2->0->NULL rotate 3 steps to the right: 0->1->2->NULL rotate 4 steps to the right: 2->0->1->NULL
解釋:
和rotate陣列是一樣的,所以需要用到206. Reverse Linked List(python+cpp),並且找到了關於陣列rotate的一般規律:
向左移動:先分別翻轉兩部分,再全部翻轉
向右移動:先全部翻轉,再分別翻轉兩部分
其中左半部分是nums[:k]
,右半部分是nums[k:]
由於連結串列翻轉比較複雜,所以這裡選擇使用額外空間,先把連結串列存成陣列,再對陣列完成各種翻轉操作,再把陣列轉換為連結串列。
python程式碼:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def rotateRight(self, head, k):
"""
:type head: ListNode
:type k: int
:rtype: ListNode
"""
if not head:
return head
_list=[]
p=head
while p!=None:
_list.append(p.val)
p=p.next
k=k%len(_list)
_list_reverse=_list[::-1]
result=_list_reverse[:k][::-1]+_list_reverse[k:][::-1]
new_head=ListNode(0)
pre=new_head
p=new_head.next
for i in range(len(result)):
temp=ListNode(result[i])
pre.next=temp
pre=pre.next
return new_head.next
後來發現,連結串列的rotate,根本不需要原地翻轉,也不需要轉換成陣列再翻轉,只需要操作工作指標即可,甚至比陣列rotate更簡單。注意因為cur一定要指向最後一個結點而不是None
,所以要用while(cur.next)
作為迴圈語句的判斷條件,這樣寫就要求在head
前面加一個結點,不然算出的size
會比真實的小1。
python程式碼:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def rotateRight(self, head, k):
"""
:type head: ListNode
:type k: int
:rtype: ListNode
"""
if not head or k==0:
return head
size=0;
tmp=ListNode(0)
tmp.next=head
cur=tmp
while cur.next:
size+=1
cur=cur.next
#此時cur指向最後一個結點,這裡先和head接上,變成一個環
cur.next=head
#找到新的頭結點的前一個結點,摘鏈
for i in range(size-k%size):
cur=cur.next
#此時cur指向新的頭結點的前一個結點
new_head=cur.next
#摘鏈
cur.next=None
return new_head
c++程式碼:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* rotateRight(ListNode* head, int k) {
if (!head || k==0)
return head;
ListNode* tmp=new ListNode(0);
tmp->next=head;
ListNode* cur=tmp;
int size=0;
while(cur->next)
{
size+=1;
cur=cur->next;
}
cur->next=head;
for(int i =0;i<size-k%size;i++)
{
cur=cur->next;
}
ListNode* new_head=cur->next;
cur->next=NULL;
return new_head;
}
};
總結: 事實上
while(k>n)
k-=n;
可以直接用
k%=n
代替
注意考慮head
為空和k
為0的情況。
第二種解法才是經典解法。