61. Rotate List(python+cpp)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_21275321/article/details/83831790

题目:

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

猜你喜欢

转载自blog.csdn.net/qq_21275321/article/details/83831790