LeetCode0581.最短无序连续子数组 Go语言AC笔记

时间复杂度:O(n)

解题思路

令[left,right]表示无序区间,那么[0,left)和(right,n]一定有序,且前者所有元素均小于无序区间元素,后者所有元素均大于无序区间元素。

那么我们要想求right,就一定要找到第一个大于无序区间最大元素且右侧均有序的元素,该元素位置的左侧就是我们要求的right。

同理要想求left,就一定要找到第一个小于无序区间最小元素且左侧均有序的元素,该元素位置右侧就是我们要求的left。

从思路上看我们需要两遍遍历,但是其实我们一遍遍历就能完成,可以看做是一个头指针和一个尾指针同时向中间移动,头指针负责求right,尾指针负责求left。

对于有序的数组我们需要特判,那就是right为初始值没有发生改变,否则返回right-left+1就是无序区间长度。

AC代码

func findUnsortedSubarray(nums []int) int {
    left,right:=-1,-1
    rightMax,leftMin:=math.MinInt64,math.MaxInt64
    n:=len(nums)
    for i,num:=range nums{
        if rightMax>num{
            right=i
        }else{
            rightMax=num
        }
        if leftMin<nums[n-1-i]{
            left=n-1-i
        }else{
            leftMin=nums[n-1-i]
        }
    }
    if right==-1{
        return 0
    }
    return right-left+1
}

感悟

自己其实写了一个AC代码,思路和官方题解思路基本一致,不过我想的稍稍有些复杂了,并且没有想到两遍遍历可以用n-i-1实现一遍遍历。

自己写的AC代码如下,就当看个笑话了。

func findUnsortedSubarray(nums []int) int {
    left,right:=1,0
    meetBig,meetSmall:=true,true
    for i:=1;i<len(nums);i++{
        if meetBig&&nums[i]<nums[i-1]{
            right=i
            meetBig=false
        }else if !meetBig&&nums[i]>=nums[right-1]{
            right=i-1
            meetBig=true
        }
    }
    if !meetBig{
        right=len(nums)-1
    }
    for i:=len(nums)-2;i>=0;i--{
        if meetSmall&&nums[i]>nums[i+1]{
            left=i
            meetSmall=false
        }else if !meetSmall&&nums[i]<=nums[left+1]{
            left=i+1
            meetSmall=true
        }
    }
    if !meetSmall{
        left=0
    }
    return right-left+1
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SwithunH

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值