题目:
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的情况。
第二种解法才是经典解法。