zoukankan      html  css  js  c++  java
  • [LeetCode] Shortest Unsorted Continuous Subarray

    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:

    Input: [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.
    

    Note:

    1. Then length of the input array is in range [1, 10,000].
    2. The input array may contain duplicates, so ascending order here means <=.

    找出最短的连续乱序子数组,返回乱序子数组的长度。

    给定一个数组,找出数组中最短的连续乱序子数组,也就是说如果这个子数组排序后,整个数组都是排序后的。

    思路1:最终结果是要求整个数组是排序好的。用整个数组都是排序好的数组对比原先未排序的数组,即可找出这个最小子数组。代码如下

    class Solution {
    public:
        int findUnsortedSubarray(vector<int>& nums) {
            vector<int> tmp(nums.begin(), nums.end());
            sort(tmp.begin(), tmp.end());
            int lo = 0, hi = 0;
            for (int i = 0; i < nums.size(); i++) {
                if (nums[i] != tmp[i]) {
                    lo = i;
                    break;
                }
            }
            for (int i = nums.size() - 1; i >= 0; i--) {
                if (nums[i] != tmp[i]) {
                    hi = i;
                    break;
                }
            }
            if (lo == hi)
                return 0;
            else
                return hi - lo + 1;
        }
    };
    // 48 ms

    思路2:假定给定一个数组[2, 6, 4, 8, 10, 9, 15]。

    第一步:要找出数组中非顺序元素的首尾。也就是说找出6和9这两个数。这时还不能确定这6-9这个子数组是最短乱序子数组,因为如果6-9之间存在某个数比6左边的数小,那么这个子数组将向左扩大。同理,如果6-9之间存在某个数比9右边的数大,那么这个子数组将向右扩大。

    第二步:找出第一步子数组范围内比子数组首(尾)元素大的小(大)的数的个数,并向左(右)移动这个数。这样就找到了最终乱序子数组的范围。

    第三步:返回子数组大小即可。

    class Solution {
    public:
        int findUnsortedSubarray(vector<int>& nums) {
            int res = 0;
            if (nums.empty())
                return res;
            int left = 0, right = nums.size() - 1;
            while (left < right && nums[left] <= nums[left + 1]) 
                left++;
            while (right > 0 && nums[right] >= nums[right - 1])
                right--;
            if (left < right) {
                int minValue = INT_MAX, maxValue = INT_MIN;
                for (int i = left; i <= right; i++) {
                    maxValue = max(maxValue, nums[i]);
                    minValue = min(minValue, nums[i]);
                }
                
                while (left >= 0 && nums[left] > minValue)
                    left--;
                while (right < nums.size() && nums[right] < maxValue)
                    right++;
                
                res = right - left - 1;
            }
            return res;
        }
    };
    // 35 ms
  • 相关阅读:
    大假期第二次测试总结
    大假期第一次测试
    拦截导弹简单版——线性dp
    我的vim配置
    2E Bank Hacking——思维题
    2D poj Cow Relays——folyd+矩阵快速幂
    2C Numerical Sequence (hard version)
    2A Subset——折半枚举+二分
    2B 米特运输
    偷天换日——树状DP
  • 原文地址:https://www.cnblogs.com/immjc/p/8004809.html
Copyright © 2011-2022 走看看