部分排序
难度:
标签:
题目描述
Given an array of integers, write a method to find indices m and n such that if you sorted elements m through n, the entire array would be sorted. Minimize n - m
(that is, find the smallest such sequence).
Return [m,n]
. If there are no such m and n (e.g. the array is already sorted), return [-1, -1].
Example:
Input: [1,2,4,7,10,11,7,12,6,7,16,18,19] Output: [3,9]
Note:
0 <= len(array) <= 1000000
代码结果
运行时间: 42 ms, 内存: 35.1 MB
/*
* Problem: Given an integer array, write a function to find the indices m and n such that if you sort the elements from index m to n, the entire array becomes sorted. The function should return [m, n], and if no such m and n exist (i.e., the array is already sorted), return [-1, -1].
* Example: Input: [1, 2, 4, 7, 10, 11, 7, 12, 6, 7, 16, 18, 19]
* Output: [3, 9]
*/
import java.util.*;
import java.util.stream.*;
public class SolutionStream {
public int[] findUnsortedSubarray(int[] nums) {
if (nums == null || nums.length <= 1) return new int[]{-1, -1};
int n = nums.length;
int[] sorted = Arrays.stream(nums).sorted().toArray();
int start = IntStream.range(0, n).filter(i -> nums[i] != sorted[i]).findFirst().orElse(-1);
if (start == -1) return new int[]{-1, -1}; // Array is already sorted
int end = IntStream.range(0, n).map(i -> n - 1 - i).filter(i -> nums[i] != sorted[i]).findFirst().orElse(-1);
return new int[]{start, end};
}
}
解释
方法:
题解采用了一种扫描数组的方式,首先从左到右扫描,记录最大值,如果当前元素小于已记录的最大值,则更新结束位置end。这样可以找到右侧第一个需要排序的位置。然后从右到左扫描,记录最小值,如果当前元素大于已记录的最小值,则更新开始位置start。这样可以找到左侧第一个需要排序的位置。这两次扫描共同确定了最短需要排序的子数组。
时间复杂度:
O(n)
空间复杂度:
O(1)
代码细节讲解
🦆
在算法中,为什么选择使用连续扫描数组两次(先从左到右再从右到左)的方式来确定m和n的位置?
▷🦆
这种方法中,当数组已完全排序时,返回值为`[-1,-1]`的逻辑是如何通过代码实现的?
▷🦆
算法在更新`end`索引时使用了`if array[i] < max_val`条件,请问这里的比较逻辑是基于什么考虑?
▷