31. 下一个排列https://leetcode.cn/problems/next-permutation/
比如:123456 < 123465 < 123546
1、我们希望下一个数比当前的数更大。倒序遍历,找到第一个相邻的升序序列(5,6),将后面的【大数】与前面的【小数】进行交换
2、我们希望数增加的频率较低,这样才满足“下一个排列与当前排列紧邻“的要求。
(1)在 尽可能靠右的低位 进行交换,需要 从后向前 查找
(2)将一个 尽可能小的「大数」 与前面的「小数」交换。比如 123465
,下一个排列应该把 5
和 4
交换而不是把 6
和 4
交换
(3)将「大数」换到前面后,需要将「大数」后面的所有数 重置为升序,升序排列就是最小的排列。
class Solution:
def nextPermutation(self, nums: List[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
if len(nums) <= 1:
return nums
# 123465
# 倒序遍历,找到第一个相邻升序数 i以后的所有数都是倒序 nums[i]<nums[i+1] 46
i = len(nums)-2
while i>=0 and nums[i]>=nums[i+1]:
i-=1
# 倒序遍历,找到第一个小于nums[i]的值nums[j] 5
if i>=0:
j = len(nums)-1
while j>=0 and nums[j]<=nums[i]:
j-=1
# 交换nums[i]和nums[j]
nums[i],nums[j]=nums[j],nums[i]
# 将nums[i + 1:]按照升序排列
left,right = i+1,len(nums)-1
while left<right:
nums[left],nums[right]=nums[right],nums[left]
left+=1
right-=1
return nums
61. 旋转链表https://leetcode.cn/problems/rotate-list/
借助一个list集合,存放每个节点,之后求出链表分割点,将分割之后的链表取出做新表的表头,将原本表分割点之后的节点删去,组合起来就是所求链表
# 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]:
re = []
node = head
while node:
re.append(node)
node = node.next
if len(re)==0:
return head
k = k%len(re)
if k==0:
return head
result=re[-k] # 找到新的表头
re[-k-1].next=None
re[-1].next = re[0]
return result