要找到需要排序的最短数组长度,使得排序后整个数组变为升序,可以使用以下方法:
方法一:双指针法(高效解法)
从左到右遍历 ,记录当前遇到的最大值 `max_from_left`,如果当前元素小于 `max_from_left`,则记录该位置为右边界 `right`。从右到左遍历
,记录当前遇到的最小值 `min_from_right`,如果当前元素大于 `min_from_right`,则记录该位置为左边界 `left`。
3. 最终需要排序的子数组长度为 `right - left + 1`。
示例
对于数组 `[2, 6, 4, 8, 10, 9, 15]`:
从左到右遍历,`max_from_left` 依次为 `2, 6, 6, 10, 10, 15`,右边界 `right` 为 5(索引为 4 的位置)。
从右到左遍历,`min_from_right` 依次为 `15, 10, 9, 4, 6, 2`,左边界 `left` 为 2(索引为 1 的位置)。
需要排序的子数组为 `[6, 4, 8, 10, 9]`,长度为 5。
方法二:排序后比较法(简单直观)
1. 将原数组排序得到 `new_nums`。
2. 使用 `zip(old, new)` 比较排序前后数组元素,找到第一个和最后一个不匹配的位置索引,计算子数组长度。
示例
对于数组 `[2, 6, 4, 8, 10, 9, 15]`:
排序后数组为 `[2, 4, 6, 8, 9, 10, 15]`。
通过比较发现,索引 1 和 5 的元素不匹配,子数组为 `[6, 4, 8, 10, 9]`,长度为 5。
方法三:时间复杂度分析
双指针法: 时间复杂度为 O(n),空间复杂度为 O(1)。 排序后比较法
总结
双指针法是更高效的解决方案,适用于大多数情况。以下是双指针法的 Python 实现:
```python
def findUnsortedSubarray(nums):
n = len(nums)
if n == 0:
return 0
从左到右遍历,找到右边界
max_from_left = nums
right = 0
for i in range(1, n):
if nums[i] < max_from_left:
right = i
max_from_left = max(max_from_left, nums[i])
从右到左遍历,找到左边界
min_from_right = nums[-1]
left = n - 1
for i in range(n - 2, -1, -1):
if nums[i] > min_from_right:
left = i
min_from_right = min(min_from_right, nums[i])
需要排序的子数组长度
return right - left + 1
示例
nums = [2, 6, 4, 8, 10, 9, 15]
print(findUnsortedSubarray(nums)) 输出: 5
```
这个方法通过两次遍历数组,分别确定子数组的左右边界,从而高效地找到最短无序连续子数组的长度。