返回介绍

solution / 0500-0599 / 0581.Shortest Unsorted Continuous Subarray / README

发布于 2024-06-17 01:03:59 字数 6444 浏览 0 评论 0 收藏 0

581. 最短无序连续子数组

English Version

题目描述

给你一个整数数组 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) 的解决方案吗?

解法

方法一:排序

我们可以先对数组进行排序,然后比较排序后的数组和原数组,找到最左边和最右边不相等的位置,它们之间的长度就是我们要找的最短无序连续子数组的长度。

时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 是数组的长度。

class Solution:
  def findUnsortedSubarray(self, nums: List[int]) -> int:
    arr = sorted(nums)
    l, r = 0, len(nums) - 1
    while l <= r and nums[l] == arr[l]:
      l += 1
    while l <= r and nums[r] == arr[r]:
      r -= 1
    return r - l + 1
class Solution {
  public int findUnsortedSubarray(int[] nums) {
    int[] arr = nums.clone();
    Arrays.sort(arr);
    int l = 0, r = arr.length - 1;
    while (l <= r && nums[l] == arr[l]) {
      l++;
    }
    while (l <= r && nums[r] == arr[r]) {
      r--;
    }
    return r - l + 1;
  }
}
class Solution {
public:
  int findUnsortedSubarray(vector<int>& nums) {
    vector<int> arr = nums;
    sort(arr.begin(), arr.end());
    int l = 0, r = arr.size() - 1;
    while (l <= r && arr[l] == nums[l]) {
      l++;
    }
    while (l <= r && arr[r] == nums[r]) {
      r--;
    }
    return r - l + 1;
  }
};
func findUnsortedSubarray(nums []int) int {
  arr := make([]int, len(nums))
  copy(arr, nums)
  sort.Ints(arr)
  l, r := 0, len(arr)-1
  for l <= r && nums[l] == arr[l] {
    l++
  }
  for l <= r && nums[r] == arr[r] {
    r--
  }
  return r - l + 1
}
function findUnsortedSubarray(nums: number[]): number {
  const arr = [...nums];
  arr.sort((a, b) => a - b);
  let [l, r] = [0, arr.length - 1];
  while (l <= r && arr[l] === nums[l]) {
    ++l;
  }
  while (l <= r && arr[r] === nums[r]) {
    --r;
  }
  return r - l + 1;
}
impl Solution {
  pub fn find_unsorted_subarray(nums: Vec<i32>) -> i32 {
    let inf = 1 << 30;
    let n = nums.len();
    let mut l = -1;
    let mut r = -1;
    let mut mi = inf;
    let mut mx = -inf;

    for i in 0..n {
      if mx > nums[i] {
        r = i as i32;
      } else {
        mx = nums[i];
      }

      if mi < nums[n - i - 1] {
        l = (n - i - 1) as i32;
      } else {
        mi = nums[n - i - 1];
      }
    }

    if r == -1 {
      0
    } else {
      r - l + 1
    }
  }
}

方法二:维护左侧最大值和右侧最小值

我们可以从左到右遍历数组,维护一个最大值 $mx$,如果当前值小于 $mx$,说明当前值不在正确的位置上,我们更新右边界 $r$ 为当前位置。同理,我们可以从右到左遍历数组,维护一个最小值 $mi$,如果当前值大于 $mi$,说明当前值不在正确的位置上,我们更新左边界 $l$ 为当前位置。在初始化时,我们将 $l$ 和 $r$ 都初始化为 $-1$,如果 $l$ 和 $r$ 都没有被更新,说明数组已经有序,返回 $0$,否则返回 $r - l + 1$。

时间复杂度 $O(n)$,其中 $n$ 是数组的长度。空间复杂度 $O(1)$。

class Solution:
  def findUnsortedSubarray(self, nums: List[int]) -> int:
    mi, mx = inf, -inf
    l = r = -1
    n = len(nums)
    for i, x in enumerate(nums):
      if mx > x:
        r = i
      else:
        mx = x
      if mi < nums[n - i - 1]:
        l = n - i - 1
      else:
        mi = nums[n - i - 1]
    return 0 if r == -1 else r - l + 1
class Solution {
  public int findUnsortedSubarray(int[] nums) {
    final int inf = 1 << 30;
    int n = nums.length;
    int l = -1, r = -1;
    int mi = inf, mx = -inf;
    for (int i = 0; i < n; ++i) {
      if (mx > nums[i]) {
        r = i;
      } else {
        mx = nums[i];
      }
      if (mi < nums[n - i - 1]) {
        l = n - i - 1;
      } else {
        mi = nums[n - i - 1];
      }
    }
    return r == -1 ? 0 : r - l + 1;
  }
}
class Solution {
public:
  int findUnsortedSubarray(vector<int>& nums) {
    const int inf = 1e9;
    int n = nums.size();
    int l = -1, r = -1;
    int mi = inf, mx = -inf;
    for (int i = 0; i < n; ++i) {
      if (mx > nums[i]) {
        r = i;
      } else {
        mx = nums[i];
      }
      if (mi < nums[n - i - 1]) {
        l = n - i - 1;
      } else {
        mi = nums[n - i - 1];
      }
    }
    return r == -1 ? 0 : r - l + 1;
  }
};
func findUnsortedSubarray(nums []int) int {
  const inf = 1 << 30
  n := len(nums)
  l, r := -1, -1
  mi, mx := inf, -inf
  for i, x := range nums {
    if mx > x {
      r = i
    } else {
      mx = x
    }
    if mi < nums[n-i-1] {
      l = n - i - 1
    } else {
      mi = nums[n-i-1]
    }
  }
  if r == -1 {
    return 0
  }
  return r - l + 1
}
function findUnsortedSubarray(nums: number[]): number {
  let [l, r] = [-1, -1];
  let [mi, mx] = [Infinity, -Infinity];
  const n = nums.length;
  for (let i = 0; i < n; ++i) {
    if (mx > nums[i]) {
      r = i;
    } else {
      mx = nums[i];
    }
    if (mi < nums[n - i - 1]) {
      l = n - i - 1;
    } else {
      mi = nums[n - i - 1];
    }
  }
  return r === -1 ? 0 : r - l + 1;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文