問題:
難易度:中
説明:
配列を指定して、小さいものから大きいものへの昇順ではないサブシーケンスを見つけてから、昇順のサブシーケンスではない、並べ替える必要のあるすべてのサブストリング(連続するサブシーケンス)を含む最短のサブシーケンスを計算します。
件名リンク:https://leetcode.com/problems/shortest-unsorted-continuous-subarray/
入力範囲:
1 <= nums.length <= 104
-105 <= nums[i] <= 105
ケースを入力してください:
Example 1: 比如说 6, 4, 8, 10, 9 这一大串有两个不连续的非升序子序列 [6, 4] [9, 10]
Input: nums = [2,6,4,8,10,9,15]
Output: 5
Explanation: You need to sort [6, 4, 8, 10, 9] in ascending order to make the whole array sorted in ascending order.
Example 2:
Input: nums = [1,2,3,4]
Output: 0
Example 3:
Input: nums = [1]
Output: 0
私のコード:
並べ替えは次のようになる可能性があるため:
1,3,5,4,2 很小的 2 放到非常后面,需要往前找比它小的元素的位置
1,9,5,4,2 很大的 9 放到很前面,需要往后找比它大的元素的位置。
1,3,2,2,2 很多重复的元素放到一起,可能是小很多的,可能是大很多的 如:1,9,9,9,2,2,2
したがって、最初の非上昇位置の開始と最後の非上昇位置の終了を見つけてから、すべての非上昇位置の最大最大値と最小最小値を計算し、開始から最小の位置を見つけてから、から最大を見つける必要があります。 end位置が原因で、2つの位置の減算は、ソートする必要のある長さです。
Java:
class Solution {
public int findUnsortedSubarray(int[] nums) {
boolean flag = true;
int left = 0, minL = Integer.MAX_VALUE, preR = 0, maxR = Integer.MIN_VALUE, cr = 0, right = 1, len = nums.length;
while(right != len) {
if(nums[right] < nums[preR]) {
if(flag) left = right - 1;
while(right + 1 < len && nums[right] == nums[right + 1]) right ++;
if(flag) {
maxR = nums[preR];
while(left >= 0 && nums[right] < nums[left]) left --;
left ++; flag = false;
}
cr = right;
maxR = Math.max(nums[preR], maxR);
minL = Math.min(nums[right], minL);
}
preR = right;
right ++;
}
while(cr < len && maxR > nums[cr]) cr ++;
while(left >= 0 && minL < nums[left]) left --;
return cr - left == 0 ? 0 : cr - left - 1;
}
}
C ++:
class Solution {
public:
int findUnsortedSubarray(vector<int>& nums) {
bool flag = true;
int left = 0, minL = INT_MAX, preR = 0, maxR = INT_MIN, cr = 0, right = 1, len = nums.size();
while(right != len) {
if(nums[right] < nums[preR]) {
if(flag) left = right - 1;
while(right + 1 < len && nums[right] == nums[right + 1]) right ++;
if(flag) {
maxR = nums[preR];
while(left >= 0 && nums[right] < nums[left]) left --;
left ++; flag = false;
}
cr = right;
maxR = max(nums[preR], maxR);
minL = min(nums[right], minL);
}
preR = right;
right ++;
}
while(cr < len && maxR > nums[cr]) cr ++;
while(left >= 0 && minL < nums[left]) left --;
return cr - left == 0 ? 0 : cr - left - 1;
}
};