T1:leetcode643.子数组的最大平均数
class Solution {
public:
double findMaxAverage(vector<int>& nums, int k) {
int sum = 0;
int result = -1000000;
for(int i = 0; i < k; i++) {
sum += nums[i];
}
result = sum;
for(int i = k; i < nums.size(); i++) {
sum = sum - nums[i - k] + nums[i];
if(sum > result) {
result = sum;
}
}
return (double)result/k;
}
};
/*
1.滑动窗口的总和,只需要确定窗口长度后,算初始总和,然后每次去掉初始元素nums[i-k]加上最后的元素nums[i]
2.最后再算double类型,用类型强转(double)
*/
T2:leetcode.718 最长重复子数组
解析一:动态规划
第一步:确定dp [i] [j]的概念 以下标i - 1结尾的nums1和以下标j - 1结尾的nums2,最长重复子数组为dp[i] [j]
第二部:确定递推公式 dp [i] [j] = dp [i] [j] + 1
第三步:确定dp数组如何初始化 dp[0] [0] = 0 vector<vector> dp (nums1.size() + 1, vector (nums2.size() + 1, 0))
第四步:确定遍历顺序
第五步:举例推导dp数组
class Solution {
public:
int findLength(vector<int>& nums1, vector<int>& nums2) {
vector<vector<int>> dp(nums1.size() + 1, vector<int> (nums2.size() + 1, 0));
int result = 0;
for(int i = 1; i <= nums1.size(); i++) {
for (int j = 1; j <= nums2.size(); j++) {
if(nums1[i - 1] == nums2[j - 1]) {
dp[i][j] = dp[i -1][j -1] + 1;
}
if (dp[i][j] > result) result = dp[i][j];
}
}
return result;
}
};
解析二:滑动窗口
class Solution {
public:
int findLength(vector<int>& A, vector<int>& B) {
return A.size()<=B.size()?helper(A,B):helper(B,A);
}
//窗口滑动的重叠过程可以分为三个过程:
//1、下面子串进入,开始重叠的过程
//2、上下两子串完全重叠,中间过程
//3、下面的子串开始离开,重叠区域减少,离开过程
int helper(vector<int>& A,vector<int>& B){
int na=A.size();
int nb=B.size();
int ret=0;
//进入时候的处理
for(int len=1;len<=na;len++){
int tmplen=maxlen(A,0,B,nb-len,len);
ret=max(ret,tmplen);
}
//中间过程的处理
for(int indexb=nb;indexb-na>=0;indexb--){
int tmplen=maxlen(A,0,B,indexb-na,na);
ret=max(ret,tmplen);
}
//出去时的处理
for(int len=na;len>0;len--){
int tmplen=maxlen(A,na-len,B,0,len);
ret=max(ret,tmplen);
}
return ret;
}
int maxlen(vector<int>& A,int indexa,vector<int>& B,int indexb,int len){
int ret=0;
int countnum=0;
for(int i=0;i<len;i++){
if(A[indexa+i]==B[indexb+i]){
countnum++;
}
else if(countnum>0){
ret=max(ret,countnum);
countnum=0;
}
}
return max(ret,countnum);
}
};