581. 最短无序连续子数组(Shortest Unsorted Continuous Subarray)

581. 最短无序连续子数组(Shortest Unsorted Continuous Subarray)

题解

两次遍历

第一次简历:
从前向后遍历,使用 m a x _ n u m max\_num max_num,保存到当前位置为止的最大值,若下个数大于等于 m a x _ n u m max\_num max_num,则更新 m a x _ n u m max\_num max_num。否则,更新需要排序数组的右界 r i g h t right right

  1. 初始化 r i g h t = 0 right=0 right=0 m a x _ n u m = n u m s [ 0 ] max\_num=nums[0] max_num=nums[0]
  2. 遍历数组,遍历区间 [ 0 , n ) [0,n) [0,n)
    • n u m s [ i ] > = m a x _ n u m nums[i]>=max\_num nums[i]>=max_num,更新 m a x _ n u m = n u m s [ i ] max\_num=nums[i] max_num=nums[i]
    • 否则,更新右界 r i g h t = i right=i right=i

第二次简历:
从后向前遍历,使用 m i n _ n u m min\_num min_num,保存到当前位置为止的最小值,若下个数小于等于 m i n _ n u m min\_num min_num,则更新 m i n _ n u m min\_num min_num。否则,更新需要排序数组的左界 l e f t left left

  1. 初始化 l e f t = n left=n left=n m i n _ n u m = n u m s [ − 1 ] min\_num=nums[-1] min_num=nums[1]
  2. 遍历数组,遍历区间 ( n , 0 ] (n,0] (n,0]
    • n u m s [ i ] < = m i n _ n u m nums[i]<=min\_num nums[i]<=min_num,更新 m i n _ n u m = n u m s [ i ] min\_num=nums[i] min_num=nums[i]
    • 否则,更新左界 r i g h t = i right=i right=i

r i g h t − l e f t + 1 > 0 right-left+1>0 rightleft+1>0,返回 r i g h t − l e f t + 1 right-left+1 rightleft+1,否则,返回 0 0 0

复杂度分析

  • 时间复杂度: O ( n ) O\left(n\right) O(n)
  • 空间复杂度: O ( 1 ) O(1) O(1)

Python

class Solution:
    def findUnsortedSubarray(self, nums: List[int]) -> int:
        n=len(nums)
        max_num=nums[0]
        right=0
        for i in range(n):
            if(nums[i]>=max_num):
                max_num=nums[i]
            else:
                right=i
        left=n
        min_num=nums[-1]
        for i in range(n-1,-1,-1):
            if(nums[i]<=min_num):
                min_num=nums[i]
            else:
                left=i
        return right-left+1 if(right-left+1 >0) else 0

Java(待完成)

排序比对

很自然的想法,将原数组copy并排序,和原数组比对。

复杂度分析

  • 时间复杂度: O ( n l o g ( n ) ) O\left(nlog(n)\right) O(nlog(n))
  • 空间复杂度: O ( n ) O(n) O(n)

Python

class Solution:
    def findUnsortedSubarray(self, nums: List[int]) -> int:
        nums_copy=nums[:]
        nums_copy.sort()
        left=float("inf")
        right=0
        for i in range(len(nums)):
            if(nums_copy[i]!=nums[i]):
                left=min(left,i)
                right=max(right,i)
        return right-left+1 if(right-left+1 > 0) else 0

Java(待完成)

1. 先来先服务调度算法(FCFS,First Come First Served):这是最简单的调度算法。在这种算法中,任务按照它们到达的顺序进行调度。这种算法的缺点是它不能保证任务在任何时候都以最有效的方式执行,因为它不考虑任务的优先级或等待时间。 2. 最短寻道优先调度算法(SSTF,Shortest Seek Time First):这种算法根据任务的寻道时间来确定任务的执行顺序。寻道时间是指从当前位置到目标位置所需的时间。这种算法的目标是最小化总的寻道时间,但可能会导致长时间的空闲等待。 3. 扫描(电梯调度)算法:这种算法将建筑物划分为多个区域,然后电梯从一个区域移动到另一个区域,直到所有区域都被访问过。这种算法的目标是最小化电梯的运行时间和乘客的等待时间。然而,由于电梯需要不断地在不同的楼层之间移动,因此这种算法的效率较低。 4. 循环扫描调度算法:这种算法结合了电梯调度和最短寻道优先调度算法的特点。电梯在一个区域内部以最短寻道优先的方式运行,而在区域之间则以循环扫描的方式运行。这种算法试图在效率和公平性之间找到一个平衡点。 实验结果结论: 1. 先来先服务调度算法适用于简单的场景,但在有优先级和等待时间限制的任务时可能不是最佳选择。 2. 最短寻道优先调度算法可以有效地减少寻道时间,但可能导致长时间的空闲等待。 3. 扫描(电梯调度)算法在某些情况下可以提高效率,但由于电梯需要不断地在不同的楼层之间移动,因此效率较低。 4. 循环扫描调度算法试图在效率和公平性之间找到一个平衡点,但可能需要根据实际情况进行调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值