LeetCode581-最短无序子数组(滑动窗口)
JS做题爽就爽在不用开编辑器
这个题目比较难,毕竟最后是用了On级别的算法
做了下去看来大体上是对的,但是很多地方的小细节出了很多差错,因为是在很困的情况下做的题目
主要就是找到一个窗口,里面最小的数字往左挪动,右边最大的数字往右挪。
不需要真实的交换,只是简单的比较即可。
1、窗口里面的重复数字怎么办? 不用管,因为窗口里面有他们的位置,只需要找一个代表出去即可。
2、数组里的重复数字怎么办?如果是降序的,就把它放到窗口里面。 比如3,2,2,2,2,2 这些2要全部进去。
3、往左往右挪,会不会导致把更小或更大的数组弄进窗口?
不会。
往左移动可能会有比窗口里面更大的数字,因为是降序找到这个最小数字的。
往右移动不会有小于最小值的数字,假如右边有小于最小值的数字,那么窗口里面的数字全都比它大,它也是降序,也会被拉到窗口里面的。
反证法很重要。
/** * @param {number[]} nums * @return {number} */ var findUnsortedSubarray = function(nums) { if(nums.length == 1){ return 0; } if(nums.length == 2){ if(nums[0]>nums[1]){ return 2; }else{ return 0; } } // 滑动窗口,找到不合理的数字的范围吧,顺便记录里面的最大最小值,以及下标,因为最大最小值关系着子数组的大小 // 最小的一直往左交换位置,最大的一直往右交换位置,最后这个位置之差就是了 // 最大的数往右边交换,不会把小于最小的数换进来,因为如果右边存在小于最小的数,那么这个数当初肯定也会被纳入到滑动窗口里面去的 // 倒是最左边可能换入比最大还大的数,所以先弄好最小的数字开始 // 还可能有重复元素,比如题目的9<10,不过10会一直换到最后,应该还好 // 但是最小和最大的数字可能会有多个,不过好像这些重复数字会在滑动窗口里有他们的位置,所以不用管 let low = -1,high = -1; // 如果当前值是降序,就是ture,用来记录重复的数字[1,3,2,2,2] 4 let flag = false; let last = nums[0]; for(let i=1;i<nums.length;i++){ if(nums[i]<last){ if(low===-1){ // 应该把前一个也算进来 low=i-1; // 第一次就要给high赋值 high = i; }else{ //high很有可能不会被赋值 如果中途只有一个降序[1,3,2,4,5] high=i; } flag = true; }else if(nums[i]===last){ if(flag){ high=i; } }else{ flag=false; } last = nums[i]; } // console.log(low,high); // 找到最小和最大的数字 // 数组的内容可以使正负数 let min = nums[low]; let max = nums[low]; for(let i=low;i<=high;i++){ if(nums[i]<min){ min=nums[i]; } if(nums[i]>max){ max=nums[i]; } } // console.log(min,max); // 一直挪左边的 // 直接和窗口外面的比即可 //窗口外面要么是重复数字,要么是升序排好的,如果遇到比自己还小或相等的,就是应该退出了 for(let i =low-1;i>=0;i--){ if(min<nums[i]){ low--; if(nums[i]>max){ max=nums[i]; } }else{ break; } } // 挪右边的 for(let i=high+1;i<nums.length;i++){ if(max>nums[i]){ high++; }else{ break; } } // console.log(low,high); if(high===low){ return 0; }else{ return high-low+1; } //[2,1] 2 0 // 如果整个数组是逆序的,这个方法不行啊 // [3,2,1]应该可以,2是low,1是high // [-1,-1,-1,-1] };
时间还行
百度了一下,有一种简单的做法。
先用一个辅助数组保存,然后将辅助数组排序,辅助数组里面,肯定会有一部分数字和原来的不一样。
1,2,3【】,8,9
那么这个【】其实就是子数组的大小....因为,确实,按照我的方式,往左往右挪了之后的数组,也是这样
然后从左找到第一个不同的数字
从右找到第一个。
【】就是源数组里面,乱序的数字再正确排序下,应该在的范围。
好难啊,转不过弯