写点什么

算法攻关 - 最短无序连续子数组 (O(n))_581

发布于: 2021 年 03 月 04 日
算法攻关 - 最短无序连续子数组 (O(n))_581

一、题目描述

给你一个整数数组 nums ,你需要找出一个 连续子数组 ,如果对这个子数组进行升序排序,那么整个数组都会变为升序排序。


请你找出符合题意的 最短 子数组,并输出它的长度。


 


示例 1:


输入:nums = [2,6,4,8,10,9,15]

输出:5

解释:你只需要对 [6, 4, 8, 10, 9] 进行升序排序,那么整个表都会变为升序排序。

示例 2:


输入:nums = [1,2,3,4]

输出:0

示例 3:


输入:nums = [1]

输出:0

 


提示:


1 <= nums.length <= 104

-105 <= nums[i] <= 105

 


进阶:你可以设计一个时间复杂度为 O(n) 的解决方案吗?


来源:力扣(LeetCode)

链接:https://leetcode-cn.com/problems/shortest-unsorted-continuous-subarray

著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

二、思考

根据题目描述,我获取到的有效信息为从一段数组中找到不规则的子数组并返回子数组的长度即为 OK。从我们最近几天来做的题看,这个也非常像滑动窗口的题目,所以我们依然用双指针的思想来解决。

寻找右边界

我们从左移动指针,我们假设左指针为最大值,移动左指针,如果当前 i 的下标对应的值大于 max,则为正确的,进而不断更新 max 值向右移动到结束,否则将当前的下标赋值给右指针作为右边界。

if (max > nums[i]){                right=i;            }else{                max=nums[i];            }
复制代码


寻找左边界

理想的情况下,我们假设右指针为最大值,减小右指针,如果当前的 I 的下标对应的值小于当前最小值,则继续,否则将当前最小值进行赋值当前下标的值。

三、代码实现

public int findUnsortedSubarray(int[] nums) {        int left=0,right=-1;        //假设初始默认值        int max=nums[0],min=nums[nums.length-1];        for(int i =0;i<nums.length;i++){            if (max > nums[i]){                right=i;            }else{                max=nums[i];            }            if (min < nums[nums.length-1-i]){                left = nums.length-1-i;            }else{                min = nums[nums.length-1-i];            }        }        return right- left+1;    }
复制代码

四、小结

这块实际上是进行了初始化,因为我们并不知道谁的值大,所以一开始初始化为我们已经能知道的值,然后进行寻找左右边界。

那么你是否还有其他解法呢?

发布于: 2021 年 03 月 04 日阅读数: 15
用户头像

小胜靠智,大胜靠德 2019.06.27 加入

历经创业、京东、腾讯、滴滴公司,希望能够有些东西一起分享。公众号:小诚信驿站,微信/CSDN搜索:wolf_love666

评论

发布
暂无评论
算法攻关 - 最短无序连续子数组 (O(n))_581