一、题目打卡
1.1 分发饼干
题目链接:. - 力扣(LeetCode)
// class Solution {
// public:
// int findContentChildren(vector<int>& g, vector<int>& s) {
// if(s.empty()) return 0;
// sort(g.begin(),g.end());
// sort(s.begin(),s.end());
// if(s.back() < g[0]) return 0;
// int i = 0, j = 0;
// while(s[j] < g[0]) j++; // 找到第一个满足胃口的地方
// // if(j == s.size()) return 0;
// int res = 0;
// // while(i < g.size() && j < s.size()){
// // if(g[i] <= s[j]) res++;
// // i++;
// // j++;
// // }
// while(i < g.size() && j < s.size()){
// if(g[i] <= s[j]){
// res++;
// i++;
// j++;
// }else j++;
// }
// return res;
// // int i = 0;
// // // cout << min(g.size(),s.size());
// // while(i < min(g.size(),s.size()) && s[i] < g[0]) i++;
// // // if(i == min(g.size(),s.size())) return 0;
// // int j = i;
// // for(; j < min(g.size(),s.size()); j++){
// // if(s[j] < g[j]) return j;
// // }
// // return j - i;
// }
// };
class Solution {
public:
int findContentChildren(vector<int>& g, vector<int>& s) {
sort(g.begin(),g.end());
sort(s.begin(),s.end());
int res = 0;
for(int i = 0, j = 0; i < g.size() && j < s.size();){
if(g[i] > s[j]) j++;
else{
res++;
i++;
j++;
}
}
return res;
}
};
题目本事不难,我考虑的时候复杂了,但是思路是没有太大问题。
1.2 摆动序列
题目链接:. - 力扣(LeetCode)
class Solution {
public:
int wiggleMaxLength(vector<int>& nums) {
// if(nums.size() == 1 || (nums.size() == 2 && nums[0] != nums[1])) return nums.size();
if(nums.size() == 1) return nums.size();
// if(nums.size() == 2) return 1;
int i = 0 , j = 1;
int diff = nums[j] - nums[i];
// 处理开头全一样的情况
while(j < nums.size() && diff == 0){
i++;
j++;
if(j == nums.size()) break;
diff = nums[j] - nums[i];
}
int res = 0;
while(j < nums.size()){
i++;
j++;
if(j == nums.size()){
res++;
break;
}
if((nums[j] - nums[i]) * diff >= 0) continue;
else{
diff = nums[j] - nums[i];
res++;
}
}
return res + 1;
}
};
相比较答案我这个更像是用测试用例不断改进出来的一个版本,非常冗余,不过既然贪心没有固定的解法,那也就当做是这个题目的非最优解吧,答案贴在下面:
class Solution {
public:
int wiggleMaxLength(vector<int>& nums) {
if (nums.size() <= 1) return nums.size();
int curDiff = 0; // 当前一对差值
int preDiff = 0; // 前一对差值
int result = 1; // 记录峰值个数,序列默认序列最右边有一个峰值
for (int i = 0; i < nums.size() - 1; i++) {
curDiff = nums[i + 1] - nums[i];
// 出现峰值
if ((preDiff <= 0 && curDiff > 0) || (preDiff >= 0 && curDiff < 0)) {
result++;
preDiff = curDiff; // 注意这里,只在摆动变化的时候更新prediff
}
}
return result;
}
};
1.3 最大子数组和(答案思路)
题目链接:. - 力扣(LeetCode)
// class Solution {
// public:
// int maxSubArray(vector<int>& nums) {
// if(nums.size() == 1) return nums[0];
// int i = 0, last_max = INT_MIN, max_tmp = nums[0];
// for(;i<nums.size() - 1 ; i++){
// if(nums[i + 1] + nums[i] >= 0){
// if(max_tmp < 0)
// max_tmp += nums[i+1];
// }
// else{
// last_max = max(last_max,max_tmp);
// // max_tmp = 0;
// max_tmp = nums[i + 1];
// }
// }
// if(last_max == INT_MIN) return max_tmp;
// return last_max;
// }
// };
class Solution {
public:
int maxSubArray(vector<int>& nums) {
int sum = 0;
int res = INT_MIN;
for(int i = 0 ; i < nums.size();i++){
sum += nums[i];
if(sum > res) res = sum; // 这个必须要放前面,不然只有一个数字的时候就会返回0,而且初始化res一定要是最小的int
if(sum <= 0) sum = 0;
}
return res;
}
};
这个题目借助了答案的思路,所以也没什么好讲的,我发现我的思路就是贪心的不够贪?或者是我的一个局部最优的选择不太正确,我选择的是步长为正数的不断累加,但是这样会出现一个问题就是,在遇到步长为负数的时候,我的一个 tmp_max 值的更新是一个问题,而且计算步长会存在一个重复计算值的问题,反正没解决,我也不想浪费太多时间,这个题目应该以动态规划的思想可以理解的更好,先放下吧。