【leetcode】Rotate List

好久没做题了,这个题做错好几回


首先,如果旋转次数k超过链的长度L,那么旋转k%L次是一样的。

 

从这个想法出发,怎么做是O(L)的复杂度,怎么才能尽量减少操作的次数并且尽量少使用额外的空间呢?

 

  1. 不要模拟旋转,而是将k次旋转等价为一次划分加一次移动
  2. 当K + 1 < L时,扫描整个链得到链的长度的时候,顺便找到划分链的地方

具体还是要细分一下

 

如果k = 0,直接返回head

所以假设k > 0

由于k >= L的话,可以等价于旋转k % L次,所以我们可以进一步假设0 < k < L

如12345,L=5, k=2

1 2 3 | 4 5

     p     q

k = 2

指针p和q相隔k=2,p到q(p, q包含)一共是k+1个节点,k+1<=L,

保证了p,q不同,而且是一前一后在整个链里面

划分的地方在指针p的后面

 

# 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 head is None or k == 0:
            return head
        p = head
        q = head
        d = 1
        while q.next:
            if d > k:
                p = p.next
            d += 1
            q = q.next   
        if k >= d:
            return self.rotateRight(head, k % d)
        t = p.next
        p.next = None
        q.next = head
        return t

 

posted @ 2018-11-14 09:58  syb3181  阅读(162)  评论(0编辑  收藏  举报