【LeetCode】数组-4(581)-给未排序数组中子数组排序使得整个数组排序 找到这个最小的子数组
这道题目感觉并不太容易,也并没有想到什么比较好的方法,看来还是积累太少。
思路一:两个指针向后遍历,分别记下造成逆序的最小和最大下标位置
优化的暴力解法(很精妙,面试的时候可以说出来)
思想:两个指针向后遍历,后面的比前面的大时,分别记录这两个元素的下标 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;
}
}
【错误输出】
【分析错误原因】
不要随意使用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)-给未排序数组中子数组排序使得整个数组排序 找到这个最小的子数组的更多相关文章
- LeetCode:长度最小的子数组【209】
LeetCode:长度最小的子数组[209] 题目描述 给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组.如果不存在符合条件的连续子数组,返回 ...
- 【LeetCode】209. 长度最小的子数组
209. 长度最小的子数组 知识点:数组:前缀和:二分法:双指针:滑动窗口 题目描述 给定一个含有 n 个正整数的数组和一个正整数 target . 找出该数组中满足其和 ≥ target 的长度最小 ...
- leetcode-209-长度最小的子数组
题目描述: 给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组.如果不存在符合条件的连续子数组,返回 0. 示例: 输入: s = 7, nums ...
- 领扣-209 长度最小的子数组 Minimum Size Subarray Sum MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- Leetcode 209.长度最小的子数组 By Python
给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组.如果不存在符合条件的连续子数组,返回 0. 示例: 输入: s = 7, nums = [2, ...
- LeetCode 209. 长度最小的子数组(Minimum Size Subarray Sum)
题目描述 给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组.如果不存在符合条件的连续子数组,返回 0. 示例: 输入: s = 7, nums ...
- Java实现 LeetCode 209 长度最小的子数组
209. 长度最小的子数组 给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组.如果不存在符合条件的连续子数组,返回 0. 示例: 输入: s = ...
- LeetCode 长度最小的子数组
题目: 给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组,并返回其长度.如果不存在符合条件的连续子数组,返回 0. 思路: 非常明显用滑动窗口处 ...
- **209. Minimum Size Subarray Sum 长度最小的子数组
1. 题目描述 给定一个含有 n 个正整数的数组和一个正整数 s ,找出该数组中满足其和 ≥ s 的长度最小的连续子数组.如果不存在符合条件的连续子数组,返回 0. 示例: 输入: s = 7, nu ...
随机推荐
- 底层码农的Stanford梦 --- 从SCPD开始 [转]
转载自知乎: https://zhuanlan.zhihu.com/p/25010074 一开始让我写这篇文章的时候,我是拒绝的.毕竟,我不是Stanford毕业的,出来写文章介绍Stanford,难 ...
- mybatis学习笔记(二)-- 使用mybatisUtil工具类体验基于xml和注解实现
项目结构 基础入门可参考:mybatis学习笔记(一)-- 简单入门(附测试Demo详细过程) 开始体验 1.新建项目,新建类MybatisUtil.java,路径:src/util/Mybatis ...
- (转载)JProfiler试用手记
JProfiler是一款Java的性能监控工具.可以查看当前应用的对象.对象引用.内存.CPU使用情况.线程.线程运行情况(阻塞.等待等),同时可以查找应用内存使用得热点,这里提供有几篇文章供参考:获 ...
- JS将文件以form表单一样提交到后台
这是很简单.. HTML <div> <input type="file" id="myfile"> <input type=&q ...
- CentOS升级Python到2.7版本
查看python的版本 1 python -V Python 2.4.3 1.先安装GCC 1 yum -y install gcc 2.下载Python-2.7.2 1 wget http://py ...
- 用户代理字符串(navigator.userAgent)检测方法
最近在看<JavaScript 高级程序设计(第三版)>,发现其中关于用户代理字符串检测技术的一些方法,觉得讲的很详细.用户代理字符串(navigator.userAgent)中包含了大量 ...
- redhat6.4配置yum
redhat6.4配置本地yum 1. 挂载(我喜欢放在/mnt下面) mount -t auto *** /mnt/redhat 或 cp *** /mnt/redhat ...
- .net ElasticSearch-Sql 扩展类
官方提供的是java sdk,并支持jdbc方式的查询结果输出;但是却没有.net sdk的支持. 开发 ElasticSearch-Sql 第三方开源项目的.net sdk,未来集成入bsf框架.( ...
- Android不编译某个模块
Android 5.1 源码,编译相关的文件一般在build目录下build/target/product 放了很多mk文件:一般不同的产品会有不同的目录 假设我不想编译OpenWnn,在build目 ...
- 再起航,我的学习笔记之JavaScript设计模式03
我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 上一 ...