题目定位
它本质上是一个边界和后缀有序问题:从右往左找第一个下降点,交换后再反转后缀。
关键观察
pivot 右侧后缀天然是降序,这也是为什么我们能高效找到下一个更大元素并通过反转得到最小更大排列。
目标复杂度
O(n) / O(1)
这题的解法思路怎么拆
1
它本质上是一个边界和后缀有序问题:从右往左找第一个下降点,交换后再反转后缀。
2
pivot 右侧后缀天然是降序,这也是为什么我们能高效找到下一个更大元素并通过反转得到最小更大排列。
3
先定义两个指针各自代表什么,再考虑怎么移动。
4
用当前比较结果证明哪一侧可以被安全丢弃。
参考实现
Python# Generic pattern template
# Opposite-direction pointers on a sorted array
left, right = 0, len(nums) - 1
while left < right:
if good(nums[left], nums[right]):
return answer
if should_move_left(nums[left], nums[right]):
left += 1
else:
right -= 1
# Fast/slow pointers
slow = 0
for fast in range(len(nums)):
if keep(nums[fast]):
nums[slow] = nums[fast]
slow += 1
常见坑点
warning
没有处理整个数组完全降序的情况。
warning
明明后缀已经降序,却又去排序而不是直接反转。
高频追问
交换之后为什么只反转就够了?
如果要求上一个排列,该怎么改?
继续刷相关题
先把 双指针 这个模式刷成体系,再去做更难变体。