Given an integer array, you need to find one continuous subarray that if you only sort this subarray in ascending order, then the whole array will be sorted in ascending order, too.
You need to find the shortest such subarray and output its length.
Example 1:
1 | Input: [2, 6, 4, 8, 10, 9, 15] |
Note:
- Then length of the input array is in range [1, 10,000].
- The input array may contain duplicates, so ascending order here means <=.
1 憨批解法
先构造个排好序的数组sortedNums, 再从左到右对照nums和sortNums第一个不一样的元素nums[i]和最后一个不一样的元素nums[j],所以(j - i + 1)即为所求。为了防止nums已经是排好序的导致的i>j,所以 return max(j - i + 1, 0)
这算法太憨了😂😂😂, 既然已经都花时间和空间排好序了那还求排序需要的最短子数组干什么呢?
1 | class Solution { |
2 4次扫描
- 首先要确定数组中从左到右第一个不是升序的元素和最后一个不是升序的元素, 即第一个使
nums[i] < nums[i - 1]
成立的i first_desc, 和最后一个使nums[i] < nums[i - 1]
成立的i last_desc. (若找不到的话, 那就说明这个数组本来就是升序的, 返回0)那么在范围[first_desc, last_desc - 1]范围内的元素肯定不是升序排列. 需要移动的范围至少是这个区间
e.g. [0 2 3 4 1 6 7 5 8] 至少需要移动元素1到5所在的区间, 注意是至少, 因为前面的2 3 4元素虽然是升序但是位置也是不对的
(元素1要放到他们前面)
当确定first_desc和last_desc后.需要找到first_desc及之后的最小元素min_after_first_desc和last_desc之前的最大元素max_before_last_desc. first_desc及之后的最小元素min_after_first_desc的正确位置肯定在[0, first_desc]之间. last_desc之前的最大元素max_before_last_desc的正确位置肯定在[last_desc, nums.size() - 1]之间!! 因为min_after_first_desc是肯定要小于nums[first_desc]的, 排序的话肯定要排到first_desc前面的某个位置loc1, 这个loc1就是我们最终寻找的index. max_before_last_desc同理.
找到min_after_first_desc的正确位置loc1, 即从左到右遍历0到first_desc - 1的第一个大于min_after_first_desc的元素位置, 找到max_before_last_desc的正确位置loc2, 即从右到左遍历nums.size() - 1到last_desc第一个小于max_before_last_desc的元素位置, loc2 - loc1 + 1即为所求.
1 | class Solution { |