【面试题 - 最大值减去最小值小于或等于 num 的子数组数量】滑动窗口
题干:
解题报告:
我们用两个指针(i,j)分别代表窗口的左边界和右边界,窗口也就是子数组;
用两个双端队列分别维护这个窗口的最大值和最小值;
当窗口扩大时,即j向右扩展时,窗口内的最大值只会越来越大,而最小值只会越来越小(否则就会等于原来的max和min了),此时,如果max-min>num,则j不应该向右扩展了,因为max-min的范围只会越来越大;
这时,应该让窗口缩小,即i向右扩展,这样max可能会减小,min可能会增大(因为原来的max和min可能会失效,即不在窗口内),这样max-min才会有<=num的可能;
另一个题解:
1)最简单的方法,暴力搜索,如何得到全部满足条件的子数组,
left = 0, res=0;
1:我们left不变 right++直到right=arr.length结束,每次right++我们都得到left~right的最大值,最小值 符合条件res++;
2:然后left++ 重复第一步。
2)首先我们不用遍历n*n次,
当满足条件right++ 不满足时left++ 这样时间复杂度为n*2;
原因:当最大值-最小值>k时 我们right++ 如果arr[right]>最大值 或者arr[right]<最小值 差值都是增大的因此在移动right没有意义。
left++,将子数组缩小,
如果移除的数字是最大值,那么次大值-最小值 差值缩小;
如果移除的数字是最小值,那么最大值-次小值 差值缩小;
如果移除的是其他数字 差值不变;
这样的时间复杂度变为n*2。
3)以上两种方法在left和right移动的过程中都要不断进行min和max的判断,提高了时间复杂度。
在遍历过程中不断更新qmin和qmax。
其中补充两个关键点:
1)如果nums[i..j]满足条件, nums[k..j] (i<= k <= j),都满足条件;
2)如果nums[i..j]不满足条件,所有包含 nums[i..j] 的数组都不满足条件;
AC代码:
总结
以上是生活随笔为你收集整理的【面试题 - 最大值减去最小值小于或等于 num 的子数组数量】滑动窗口的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: WinCtlAdAlt.exe - Wi
- 下一篇: 【CodeForces - 731C】S