滑动窗口算法
作者:互联网
给定一个整型数组和一个数字s,找到数组中的最短连续子数组,使得连续子数组的和sum>=s,返回这个最短连续子数组的长度值
如给定[2,3,1,2,4,3],s=7
答案为[4,3],返回2
第一种解法就是暴力解法,采用双循环来遍历所有的子数组,代码如下
#include<iostream> using namespace std; int GetSubArrayLen(int* Arr,int ArrLen,int Val); int main(void) { int* Array; int ArrLen; cin >> ArrLen; Array = new int[ArrLen]; for (int i = 0; i < ArrLen; ++i) cin >> Array[i]; int Val; cin >> Val; cout << GetSubArrayLen(Array, ArrLen, Val)<<endl; system("pause"); return 0; } int GetSubArrayLen(int* Arr,int ArrLen,int Val) { int Len = 0; int sum = 0; for (int t = 0; t < ArrLen; ++t) sum += Arr[t]; if (sum > Val) Len = ArrLen; else return 0; for(int i=0;i<ArrLen;++i) for (int j = ArrLen - 1; j > i; --j) { sum = 0; for (int t = i; t <= j; ++t) sum += Arr[t]; if(sum>=Val&&((j-i+1)<=ArrLen)) Len=j-i+1; } return Len; }
这种方法的时间复杂度为O(n^3),可以将数组中每个元素的值替换为前面所有数组的和,比如将arr[3]的值变为arr[0]+arr[1]+arr[2]+arr[3],这样求解一段子数组的和时,比如求2~4的子数组之和,就用修改后的arr[4]-arr[2]就可以了,这样可以省去双循环中循环求和步骤门将时间复杂度降到O(n^2)
还有一种滑动窗口方法
连个指针L和R,L表示滑窗的左边框,R表示滑窗的右边框
左边框向右滑动使窗口变小,右边框向右滑动使窗口变大,开始左右边框是重合在一起的,窗口的和就是重合点所在的数
1,先将R向右滑动,当和恰好>=s时,记录下滑窗的子数组长度,如果这个长度小于原来的长度,就更新子数组长度
2,L向右滑动,判断是否仍然>=s,如果满足条件就继续向右滑动
3,如果<s则将R向右滑动,重复1
代码如下
#include<iostream> using namespace std; int GetSubArrayLen(int* Arr,int ArrLen,int Val); int WindowValue(int* Arr, int L, int R); int main(void) { int* Array; int ArrLen; cin >> ArrLen; Array = new int[ArrLen]; for (int i = 0; i < ArrLen; ++i) cin >> Array[i]; int Val; cin >> Val; cout << GetSubArrayLen(Array, ArrLen, Val)<<endl; system("pause"); return 0; } int GetSubArrayLen(int* Arr,int ArrLen,int Val) { int Len = 0; int sum = 0; for (int t = 0; t < ArrLen; ++t) sum += Arr[t]; if (sum > Val) Len = ArrLen; else return 0; int TempLen = 0; int L = 0, R = 0; while (R < ArrLen) { while ((WindowValue(Arr, L, R) < Val)&&(R<ArrLen)) R++; while ((WindowValue(Arr, L, R) >= Val)&&(L<=R)) { TempLen = R - L + 1; if (TempLen <= Len) Len = TempLen; L++; } } return Len; } int WindowValue(int* Arr, int L, int R) { int Sum = 0; for (int i = L; i < R + 1; ++i) Sum += Arr[i]; return Sum; }
标签:arr,窗口,Val,int,cin,ArrLen,算法,数组,滑动 来源: https://blog.51cto.com/u_12870633/2812933