题目描述:
给你一个由 n 个元素组成的整数数组 nums 和一个整数 k 。
请你找出平均数最大且 长度为 k 的连续子数组,并输出该最大平均数。
任何误差小于 10-5 的答案都将被视为正确答案。
思路:
典型双指针题目,注意两点:
1、最大值的初值要设的小一点
2、注意类型转换 int -> double
class Solution {
public:
double findMaxAverage(vector<int>& nums, int k) {
int sumv = 0;
int maxv = -10000000001;
int l = 0, r = -1;
while (r < (int)nums.size() - 1) {
++r;
sumv += nums[r];
while (r- l + 1 > k) {
sumv -= nums[l];
++l;
}
if (r- l+1 == k) {
maxv = max(maxv, sumv);
}
}
return maxv*1.0/k;
}
};
题目描述:
给两个整数数组 nums1
和 nums2
,返回 两个数组中 公共的 、长度最长的子数组的长度 。
思路:
dp更好做,
定义一个dp数组,dp[i][j] 表示以nums1[i]和nums2[j]结尾的最长公共子串的长度
根据nums1[i]和nums2[j]的实际情况和dp[i-1][j-1]的值进行递推求解;
dp[i][j]是由dp[i-1][j-1]推来的
class Solution {
int dp[1010][1010]; //dp[i][j] = 1时表示nums1[i]和nums2[j]相等,否则不相等
public:
int findLength(vector<int>& nums1, vector<int>& nums2) {
int maxv = -1;
for (int i = 0; i < nums1.size(); ++i) {
for (int j = 0; j < nums2.size(); ++j) {
if (!i || !j) {
dp[i][j] = nums1[i] == nums2[j] ? 1 : 0;
} else {
dp[i][j] = nums1[i] == nums2[j] ? dp[i-1][j-1]+1 : 0;
}
maxv = max(maxv, dp[i][j]);
}
}
return maxv;
}
};
题目描述:
给定一个整数数组 arr ,返回 arr 的 最大湍流子数组的长度 。
如果比较符号在子数组中的每个相邻元素对之间翻转,则该子数组是 湍流子数组 。
更正式地来说,当 arr 的子数组 A[i], A[i+1], ..., A[j] 满足仅满足下列条件时,我们称其为湍流子数组:
若 i <= k < j :
当 k 为奇数时, A[k] > A[k+1],且
当 k 为偶数时,A[k] < A[k+1];
或 若 i <= k < j :
当 k 为偶数时,A[k] > A[k+1] ,且
当 k 为奇数时, A[k] < A[k+1]。
思路:
题目的意思是,数据大小交替出现;
定义两个数组,acd代表序列最后一个元素是递增的最长序列长度,des代表序列最后一个元素是递减的最长序列长度,一次枚举即可;
class Solution {
public:
int maxTurbulenceSize(vector<int>& arr) {
int acd[40010], des[40010];
int ans = 0;
for (int i = 1; i < arr.size(); ++i) {
acd[i] = 1;
des[i] = 1;
if (i) {
if (arr[i-1] < arr[i]) {
acd[i] = des[i-1]+1;
} else if (arr[i-1] > arr[i]){
des[i] = acd[i-1]+1;
}
}
ans = max(ans, max(acd[i], des[i]));
}
return ans;
}
};
题目描述:
有一个书店老板,他的书店开了 n 分钟。每分钟都有一些顾客进入这家商店。给定一个长度为 n 的整数数组 customers ,其中 customers[i] 是在第 i 分钟开始时进入商店的顾客数量,所有这些顾客在第 i 分钟结束后离开。
在某些时候,书店老板会生气。 如果书店老板在第 i 分钟生气,那么 grumpy[i] = 1,否则 grumpy[i] = 0。
当书店老板生气时,那一分钟的顾客就会不满意,若老板不生气则顾客是满意的。
书店老板知道一个秘密技巧,能抑制自己的情绪,可以让自己连续 minutes 分钟不生气,但却只能使用一次。
请你返回 这一天营业下来,最多有多少客户能够感到满意。
思路:
1、记录两个前缀和,一个表示不管生不生气的前缀和,一个表示生气的情况下的前缀和;
2、定义一个滑动窗口进行操作,点那个窗口正好为minutes时,则进行判定;
令考虑生气的情况下的人数为x,当窗口[i,j]的人数,考虑生气的情况下为y,不考虑生气的情况下的人数为z,结果就是x-y+z,计算最大值。其中y和z剋通过前缀差分和求得。
class Solution {
#define maxn 20010
public:
int maxSatisfied(vector<int>& customers, vector<int>& grumpy, int minutes) {
int custSum[maxn];
int custGru[maxn];
int n = customers.size();
//计算前缀和
for (int i = 1; i <= n; ++i) {
custSum[i] = custSum[i-1] + customers[i-1];
custGru[i] = custGru[i-1] + customers[i-1]*(!grumpy[i-1]);
}
int i = 1, j = 0, ans = 0;
while (j < n) {
++j;
while(j - i + 1 > minutes) {
++i;
}
if (j - i + 1 == minutes) {
int val = custGru[n] - (custGru[j] - custGru[i-1]) + custSum[j] - custSum[i-1];
ans = max(ans, val);
}
}
return ans;
}
};