【LeetCode】581. 最短无序连续子数组

524 阅读2分钟

最短无序连续子数组

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

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

示例1

输入:nums = [2,6,4,8,10,9,15]
输出:5
解释:你只需要对 [6, 4, 8, 10, 9] 进行升序排序,那么整个表都会变为升序排序。

示例2

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

思路

  • 这个题目,首先想到的就是暴力解决,如解法一。
    • 将数组排序,然后将排序后的数组和原数组进行比较。
    • 从前面遍历,第一个对应位置上不同的元素,则可确定为最左边不匹配的元素。
    • 从后面遍历,第一个对应位置上不同的元素,则可确定为最右边不匹配的元素。
    • 最后根据左右索引,即可求出长度。
  • 继续对上面的方法进行优化。一次遍历数组即可获取最左边不匹配的元素和最右边不匹配的元素,如解法二。
    • 定义两个变量分别存放位置相同但是元素不同的最左边和最右边的索引。

解法一

func findUnsortedSubarray(nums []int) int {
    temp:=[]int{}
    for i:=0;i<len(nums);i++{ // 定义temp数组,存放原数组的数据
        temp=append(temp,nums[i])
    } 
    sort.Ints(temp) // 获取排序后的数组
    left,right:=0,0
    for i:=0;i<len(nums);i++{ // 从前面遍历,第一个对应位置不同的元素,则可确定为最左边不匹配的元素
        if nums[i]!=temp[i]{
            left=i
            break
        }
    }
    for i:=len(nums)-1;i>=0;i--{ // 从后面遍历,第一个对应位置不同的元素,则可确定为最右边不匹配的元素
        if nums[i]!=temp[i]{
            right=i
            break
        }
    }
    if left==0&&right==0{ // 如果左右指针全部指向0处,则表示当前的原数组就是有序数组
        return 0
    }
    return right-left+1 // 根据左右索引,即可求出长度
}

解法二

func findUnsortedSubarray(nums []int) int {
    temp:=[]int{}
    for _,v:=range nums{
        temp=append(temp,v)
    }
    sort.Ints(temp)
    left:=len(nums)-1
    right:=0
    for i:=0;i<len(nums);i++{
        if nums[i]!=temp[i]{
            left=min(left,i)
            right=max(right,i)
        }
    }
    if left==len(nums)-1&&right==0{
        return 0
    }
    return right-left+1
}

func max(a,b int)int{
    if a>b{
        return a
    }
    return b
}

func min(a,b int)int{
    if a<b{
        return a
    }
    return b
}