题解 | #最短无序连续子数组#

最短无序连续子数组

http://www.nowcoder.com/practice/d17f4abd1d114617b51e951027be312e

题意整理

  • 给定一个整数数组,找出一个连续子数组,将这个子数组升序排列后整个数组都变为升序数组。
  • 求满足条件的最短的连续子数组的长度。

方法一(排序)

1.解题思路

  • 首先定义一个新数组arr,将原数组的值复制到新数组。
  • 对原数组nums进行排序。
  • 从前往后,找到第一个不相等的元素位置,记为子数组的起点。从后往前,找到第一个不相等的元素位置,记为子数组的终点。计算起点、终点距离,即可知道对应子数组的长度。

图解展示: alt

2.代码实现

import java.util.*;

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param nums int整型一维数组 
     * @return int整型
     */
    public int findUnsortedSubarray (int[] nums) {
        //数组长度
        int n=nums.length;
        //复制原数组到arr数组
        int[] arr=Arrays.copyOf(nums,n);
        //对应原数组nums进行排序
        Arrays.sort(nums);
        //start记录最短无序连续子数组的起点。end记录对应的终点
        int start=-1,end=-1;
        for(int i=0;i<n;i++){
            //如果不相等,将i标记为起点,并结束循环
            if(arr[i]!=nums[i]){
                start=i;
                break;
            }
        }
        for(int i=n-1;i>=0;i--){
            //如果不相等,将i标记为终点,并结束循环
            if(arr[i]!=nums[i]){
                end=i;
                break;
            }
        }
        //如果所有元素都相等,直接返回0,否则返回对应长度
        return (start==-1&&end==-1)?0:end-start+1;
    }
}

3.复杂度分析

  • 时间复杂度:需要对数组进行排序,以及遍历整个数组,排序的时间复杂度为O(nlog2n)O(nlog_2n),遍历的时间复杂度为O(n)O(n),所以时间复杂度是O(nlog2n)O(nlog_2n)
  • 空间复杂度:需要额外大小为n的arr数组,所以空间复杂度为O(n)O(n)

方法二(贪心)

1.解题思路

首先找到使得数组无序的对应位置最小值,以及使得数组无序的对应位置最大值,然后找第一个大于最小值的位置,必定是子数组的起点,而前面的数都小于这个最小值,接着从后往前找第一个小于最大值的位置,必定是子数组的终点,而后面的数都大于这个最大值。所以起点、终点之间一定是最短无序的连续子数组。

2.代码实现

import java.util.*;

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param nums int整型一维数组 
     * @return int整型
     */
    public int findUnsortedSubarray (int[] nums) {
        //数组长度
        int n=nums.length;
        //startNum记录最短无序连续子数组的最小值,endNum记录对应的最大值
        int startNum=100001,endNum=-1;
        //start记录最短无序连续子数组的起点。end记录对应的终点
        int start=-1,end=-1;
        for(int i=1;i<n;i++){
            if(nums[i]<nums[i-1]){
                startNum=Math.min(startNum,nums[i]);
            }
        }
        for(int i=0;i<n;i++){
            //如果大于startNum,说明是子数组的起点
            if(nums[i]>startNum){
                start=i;
                break;
            }
        }
        for(int i=n-2;i>=0;i--){
            if(nums[i]>nums[i+1]){
                endNum=Math.max(endNum,nums[i]);
            }
        }
        for(int i=n-1;i>=0;i--){
            //如果小于endNum,说明是子数组的终点
            if(nums[i]<endNum){
                end=i;
                break;
            }
        }
        //如果所有元素都相等,直接返回0,否则返回对应长度
        return (start==-1&&end==-1)?0:end-start+1;
    }
}

3.复杂度分析

  • 时间复杂度:需要对原数组进行4次遍历,每次都只有一层循环,所以时间复杂度是O(n)O(n)
  • 空间复杂度:需要额外常数级别的内存空间,所以空间复杂度为O(1)O(1)
xqxls的题解 文章被收录于专栏

牛客题解

全部评论
你这求的是最长子数组吧?
点赞 回复 分享
发布于 2023-08-03 22:04 广东

相关推荐

鼠鼠没有找到暑期实习,简历太空了,感觉直接去秋招会完蛋,这个时间点找个日常实习混个简历,边实习边准备秋招有没有搞头啊
梦想是成为七海千秋:可以的完全可以的,找不到暑期就找日常,秋招之前还是有很多时间可以实习的,哪怕只实习了一个月都可以写在简历上
点赞 评论 收藏
分享
Ncsbbss:又想干活又想要工资,怎么什么好事都让你占了
点赞 评论 收藏
分享
05-30 18:54
武汉商学院 Java
湫湫湫不会java:先投着吧,大概率找不到实习,没实习的时候再加个项目,然后把个人评价和荣誉奖项删了,赶紧成为八股战神吧,没实习没学历,秋招机会估计不多,把握机会。或者说秋招时间去冲实习,春招冲offer,但是压力会比较大
点赞 评论 收藏
分享
点赞 评论 收藏
分享
评论
点赞
1
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务