这道题目感觉并不太容易,也并没有想到什么比较好的方法,看来还是积累太少。

思路一:两个指针向后遍历,分别记下造成逆序的最小和最大下标位置

优化的暴力解法(很精妙,面试的时候可以说出来)

思想:两个指针向后遍历,后面的比前面的大时,分别记录这两个元素的下标 lo 和 hi,前面的下标是造成逆序的第一个元素所以我们记录它,它也一直是后面逆序出现位置的最小值。二而后面的元素更新一直都表示构成元素逆序的最大下标位置。

最后 hi-lo+1就是 最小的那个子数组。

【正确代码】

 public class Solution {
public int findUnsortedSubarray(int[] nums) {
int lo = Integer.MAX_VALUE, hi = Integer.MIN_VALUE;
for (int i = 0; i < nums.length; i++) {
for (int j = i; j < nums.length; j++) {
if (nums[j] < nums[i]) {
lo = Math.min(lo, i);
hi = Math.max(hi, j);
}
}
}
return hi - lo < 0 ? 0 : hi - lo + 1;
}
}

复杂度分析

时间复杂度:O(n^2)

空间复杂度:o(1)

思路二:和排序后的比较,找出前后第一个不相等的数字,计算下标差

【正确代码】

 public class Solution {
public int findUnsortedSubarray(int[] nums) {
int[] sortNums = new int[nums.length];
System.arraycopy(nums, 0, sortNums, 0, nums.length);
Arrays.sort(sortNums);
int lo = nums.length - 1, hi = 0;
int i = 0, j = nums.length - 1;
while (i < nums.length - 1) {
if (sortNums[i] != nums[i]) {
lo = i;
break;
}
i++;
}
while (j > 0) {
if (sortNums[j] != nums[j]) {
hi = j;
break;
}
j--;
}
return hi - lo <= 0 ? 0 : hi - lo + 1;
}
}

复杂度分析

时间复杂度:O(n*logn) 主要消耗在排序

空间复杂度:O(n) 申请了空间

思路三:使用stack,从前向后压栈,找到第一个下降的元素,并记录下标。同理,从后向前,找到第一个上升元素,并记录下标,最后计算下标差即可。

第一次写时出现错误,没有考虑到等于的情况。

【错误代码】

 public class Solution {
public int findUnsortedSubarray(int[] nums) {
Stack<Integer> stack = new Stack<>();
int lo = 0, hi = 0;
one: {
for (int i = 0; i < nums.length; i++) {
while (!stack.isEmpty() && nums[stack.peek()] > nums[i]) { //stack 中元素大于新添加元素
lo = stack.peek();
break one;
}
stack.push(i);
}
}
stack.clear();
two: {
for (int i = nums.length - 1; i >= 0; i--) {
while (!stack.isEmpty() && nums[stack.peek()] < nums[i]) {
hi = stack.peek();
break two;
}
stack.push(i);
}
} return hi - lo <= 0 ? 0 : hi - lo + 1;
}
}

【错误输出】

Input:[1,3,2,2,2]
Output:2
Expected:4

【分析错误原因】

不要随意使用break,蓝色处很重要只要比栈顶大就一只向外弹出。改正代码如下:

【正确代码】

 class Solution {
public int findUnsortedSubarray(int[] nums) {
Stack<Integer> stack = new Stack<>();
int lo = nums.length - 1;
int hi = 0;
for (int i = 0; i < nums.length; i++) {
while (!stack.isEmpty() && nums[i] < nums[stack.peek()]) {
lo = Math.min(lo, stack.pop());
}
stack.push(i);
}
stack.clear();
for (int j = nums.length -1; j >= 0; j--) {
while (!stack.isEmpty() && nums[j] > nums[stack.peek()]) {
hi = Math.max(hi, stack.pop());
}
stack.push(j);
}
return hi - lo > 0 ? hi - lo + 1 : 0;
}
}

复杂度分析

时间复杂度:O(n)

空间复杂度:O(n) stack的深度

思路四:从前往后找,从前面比后面小的数中,找到并保存其中最小的数,之后再从前向后找,找出第一个大于这个数的下标即为所求。后面同理。

【LeetCode】数组-4(581)-给未排序数组中子数组排序使得整个数组排序 找到这个最小的子数组的更多相关文章

  1. LeetCode:长度最小的子数组【209】

    LeetCode:长度最小的子数组[209] 题目描述 给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组.如果不存在符合条件的连续子数组,返回 ...

  2. 【LeetCode】209. 长度最小的子数组

    209. 长度最小的子数组 知识点:数组:前缀和:二分法:双指针:滑动窗口 题目描述 给定一个含有 n 个正整数的数组和一个正整数 target . 找出该数组中满足其和 ≥ target 的长度最小 ...

  3. leetcode-209-长度最小的子数组

    题目描述: 给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组.如果不存在符合条件的连续子数组,返回 0. 示例: 输入: s = 7, nums ...

  4. 领扣-209 长度最小的子数组 Minimum Size Subarray Sum MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  5. Leetcode 209.长度最小的子数组 By Python

    给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组.如果不存在符合条件的连续子数组,返回 0. 示例: 输入: s = 7, nums = [2, ...

  6. LeetCode 209. 长度最小的子数组(Minimum Size Subarray Sum)

    题目描述 给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组.如果不存在符合条件的连续子数组,返回 0. 示例: 输入: s = 7, nums ...

  7. Java实现 LeetCode 209 长度最小的子数组

    209. 长度最小的子数组 给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组.如果不存在符合条件的连续子数组,返回 0. 示例: 输入: s = ...

  8. LeetCode 长度最小的子数组

    题目: 给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组,并返回其长度.如果不存在符合条件的连续子数组,返回 0. 思路: 非常明显用滑动窗口处 ...

  9. **209. Minimum Size Subarray Sum 长度最小的子数组

    1. 题目描述 给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组.如果不存在符合条件的连续子数组,返回 0. 示例: 输入: s = 7, nu ...

随机推荐

  1. 2017寒假零基础学习Python系列之函数之 返回多个值

    Python也和C语言一样有自己的标准库,不过在Python中叫做模块(module),这个和C语言中的头文件以及Java中的包类似,其中math就是其中之一,math模块中提供了sin()和cos( ...

  2. iOS 微信消息拦截插件系列教程-附录(服务端成果展示)

    微信iOS消息拦截插件教程 标签: 越狱开发 背景介绍 本教程所有内容免费 本教程来源于一次知识分享,如果有需要了解更多的 请联系QQ:480071411 iOS逆向高级开发群:375024882 服 ...

  3. 动态数组ArrayList的使用

    1.定义类 package com.realhope.rmeal.bean; /** * * @author Wucy * 菜谱类 */ public class Menu{ private Inte ...

  4. 交叉编译 tesseract

      官方参考资料说明: tesseract 依赖库: (https://github.com/tesseract-ocr/tesseract/wiki/Compiling#linux) leptoni ...

  5. 为Dynamics 365写一个简单程序实现解决方案一键迁移

    关注本人微信和易信公众号: 微软动态CRM专家罗勇 ,回复258或者20170627可方便获取本文,同时可以在第一间得到我发布的最新的博文信息,follow me!我的网站是 www.luoyong. ...

  6. 微信小程序的登陆流程详解

    由于小程序的登陆和登陆状态维护流程比较复杂,需要客户端和服务器的数次交互以及服务器端的相应处理,很多同学都觉得比较麻烦,所以特别写下这篇博客为大家梳理一下微信的登陆流程,同时加深对微信小程序与登陆状态 ...

  7. JS封闭函数、闭包、内置对象

    一.变量作用域 变量作用域指的是变量的作用范围,javascript中的变量分为全局变量和局部变量 1.全局变量:在函数之外定义的变量,为整个页面公用,函数的内部外部都可以访问. 2.局部变量:在函数 ...

  8. C# Web.config配置

    使用 <!--M002 バッチを起動のPath配置--> <add key="BM0002_START_PATH" value="D:\BM0002\B ...

  9. Linux基础(四)

    一.系统监控 1.用top命令实时监测CPU.内存.硬盘状态 效果类似Windows的任务管理器,默认每5秒刷新一下屏幕上的显示结果. [root@localhost /]# top top - 17 ...

  10. Python爬虫从入门到放弃(十九)之 Scrapy爬取所有知乎用户信息(下)

    在上一篇文章中主要写了关于爬虫过程的分析,下面是代码的实现,完整代码在:https://github.com/pythonsite/spider items中的代码主要是我们要爬取的字段的定义 cla ...