LeetCode:61. 旋转链表(python)
给定一个链表,旋转链表,将链表每个节点向右移动 k 个位置,其中 k 是非负数。
示例 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
思路:
- 计算链表长度,优化旋转次数
- 链接首尾节点,寻找根据旋转次数和链表长度寻找断点
附代码(Python3):
class ListNode:
def __init__(self, x):
self.val = x
self.next = None
class Solution:
def rotateRight(self, head, k):
if not head: # 链表空,则返回空
return None
if not head.next or k==0:
return head # 链表只有一个节点或旋转次数为0,则返回链表
# 计算链表长度并寻找尾节点
length = 1
tail = head
while tail.next:
tail = tail.next
length += 1
new_k = k%length # 根据链表长度计算真实需要旋转的次数
if new_k == 0: # 若为 0,则返回链表
return head
# 寻找旋转后的断点,该断点为新链表的尾节点,断点下一处节点为新链表的头结点
tail.next = head # 连接首尾节点
for _ in range(length-new_k): # 尾节点移动 length-new_k 步
tail = tail.next
new_head = tail.next # 断点处下一节点为新链表的头结点
tail.next = None # 断点为新链表的尾节点
return new_head # 返回新链表头结点
def build_link(nums):
'''构建链表'''
res = cur = ListNode(None)
for i in nums:
cur.next = ListNode(i)
cur = cur.next
return res.next
test = Solution()
# 示例1
head1, k1 = build_link([1, 2, 3, 4, 5]), 2
res1 = test.rotateRight(head1, k1) # 旋转链表
while res1: # 打印
print(res1.val, end=' ')
res1 = res1.next
print()
# 示例2
head2, k2 = build_link([0, 1, 2]), 4
res2 = test.rotateRight(head2, k2) # 旋转链表
while res2: # 打印
print(res2.val, end=' ')
res2 = res2.next
print()
4 5 1 2 3
2 0 1