61. 旋转链表
题目:给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置。
链接 https://leetcode.cn/problems/rotate-list/
个人思路
- 这题不算难,一种思路是先循环一遍,把每个结点和位置储存在字典中,然后看要旋转几次,把新的尾结点的next重置为None,然后把原来的尾结点与头结点相连(对于旋转次数大于链表长度的情况,我们可以进行取余)
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def rotateRight(self, head: Optional[ListNode], k: int) -> Optional[ListNode]:
collection = {}
cur = head
i = 1
while cur:
collection[i] = cur
cur = cur.next
i += 1
# 去除完整循环的旋转步骤
# 只需旋转r次
length = len(collection)
# 对于链表长度为0或者为1或者旋转次数为0的链表可直接返回头结点
if length == 0 or length == 1 or k== 0:
return head
r = k % length
if r == 0:
return head
# 旋转后,最后一个结点
node1 = collection[length - r]
newHead = node1.next # 新的头结点
node1.next = None
# 原来的尾结点与原来的头结点连接
node2 = collection[length]
node2.next = head
return newHead
但因为要储存结点,内存消耗较大
- 可以循环两次,这样就不用消耗多余的内存来储存了
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def rotateRight(self, head: Optional[ListNode], k: int) -> Optional[ListNode]:
cur = head
length = 0
while cur:
cur = cur.next
length += 1
# 去除完整循环的旋转步骤
# 只需旋转r次
# 对于链表长度为0或者为1或者旋转次数为0的链表可直接返回头结点
if length == 0 or length == 1:
return head
r = k % length
if r == 0:
return head
cur = head
i = 0
while i < length-1:
if i == length - r - 1:
# 旋转后,新的头结点和尾结点
newTail = cur
newHead = cur.next
cur = cur.next
i += 1
# 把原来的尾结点与原来的头结点相连
cur.next = head
# 新的尾结点的下一个结点置为空
newTail.next = None
return newHead
官方思路
- 闭合为环
class Solution:
def rotateRight(self, head: ListNode, k: int) -> ListNode:
if k == 0 or not head or not head.next:
return head
n = 1
cur = head
while cur.next:
cur = cur.next
n += 1
if (add := n - k % n) == n:
return head
cur.next = head
while add:
cur = cur.next
add -= 1
ret = cur.next
cur.next = None
return ret
作者:LeetCode-Solution
链接:https://leetcode.cn/problems/rotate-list/solution/xuan-zhuan-lian-biao-by-leetcode-solutio-woq1/