共享ip服务器做网站,自己做网站要学什么,WORDPRESS 手机版 底部电话,深圳福田住房和建设局网站官网目录#xff1a;
解题及思路学习
455. 分发饼干
假设你是一位很棒的家长#xff0c;想要给你的孩子们一些小饼干。但是#xff0c;每个孩子最多只能给一块饼干。
对每个孩子 i#xff0c;都有一个胃口值 g[i]#xff0c;这是能让孩子们满足胃口的饼干的最小尺寸#…目录
解题及思路学习
455. 分发饼干
假设你是一位很棒的家长想要给你的孩子们一些小饼干。但是每个孩子最多只能给一块饼干。
对每个孩子 i都有一个胃口值 g[i]这是能让孩子们满足胃口的饼干的最小尺寸并且每块饼干 j都有一个尺寸 s[j] 。如果 s[j] g[i]我们可以将这个饼干 j 分配给孩子 i 这个孩子会得到满足。你的目标是尽可能满足越多数量的孩子并输出这个最大数值。
示例 1:
输入: g [1,2,3], s [1,1]
输出: 1思考看到这个题目首先想到的是给两个数组排序。然后遍历饼干双指针找到满足最小胃口的孩子并且。 或者先从最大的孩子找找满足条件的饼干。
根据孩子的胃口来匹配的。
class Solution {
public:int findContentChildren(vectorint g, vectorint s) {sort(g.begin(), g.end());sort(s.begin(), s.end());int index s.size() - 1; // 饼干数组的下标int result 0;for (int i g.size() - 1; i 0; i--) { // 遍历胃口if (index 0 s[index] g[i]) { // 遍历饼干result;index--;}}return result;}
};根据饼干去匹配孩子的。
class Solution {
public:int findContentChildren(vectorint g, vectorint s) {sort(g.begin(),g.end());sort(s.begin(),s.end());int index 0;for(int i 0; i s.size(); i) { // 饼干if(index g.size() g[index] s[i]){ // 胃口index;}}return index;}
};时间复杂度O(nlogn)空间复杂度O(1)
想清楚局部最优想清楚全局最优感觉局部最优是可以推出全局最优并想不出反例那么就试一试贪心。
376. 摆动序列
如果连续数字之间的差严格地在正数和负数之间交替则数字序列称为 **摆动序列 。**第一个差如果存在的话可能是正数或负数。仅有一个元素或者含两个不等元素的序列也视作摆动序列。
例如 [1, 7, 4, 9, 2, 5] 是一个 摆动序列 因为差值 (6, -3, 5, -7, 3) 是正负交替出现的。相反[1, 4, 7, 2, 5] 和 [1, 7, 4, 5, 5] 不是摆动序列第一个序列是因为它的前两个差值都是正数第二个序列是因为它的最后一个差值为零。
子序列 可以通过从原始序列中删除一些也可以不删除元素来获得剩下的元素保持其原始顺序。
给你一个整数数组 nums 返回 nums 中作为 摆动序列 的 最长子序列的长度 。
示例 1
输入nums [1,7,4,9,2,5]
输出6思考只需要统计数组的峰值就可以了。
局部最优删除单调坡度上的节点不包括单调坡度两端的节点那么这个坡度就可以有两个局部峰值。
整体最优整个序列有最多的局部峰值从而达到最长摆动序列。
class Solution {
public:int wiggleMaxLength(vectorint 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;}
};只需要在 这个坡度 摆动变化的时候更新 prediff 就行这样 prediff 在 单调区间有平坡的时候 就不会发生变化造成我们的误判。
动态规划方法
memset(dp,0,sizeof(dp));能将数组的每个元素初始化为0
设 dp 状态dp[i][0]表示考虑前 i 个数第 i 个数作为山峰的摆动子序列的最长长度设 dp 状态dp[i][1]表示考虑前 i 个数第 i 个数作为山谷的摆动子序列的最长长度
则转移方程为
dp[i][0] max(dp[i][0], dp[j][1] 1)其中0 j i且nums[j] nums[i]表示将 nums[i]接到前面某个山谷后面作为山峰。dp[i][1] max(dp[i][1], dp[j][0] 1)其中0 j i且nums[j] nums[i]表示将 nums[i]接到前面某个山峰后面作为山谷。
初始状态
由于一个数可以接到前面的某个数后面也可以以自身为子序列的起点所以初始状态为dp[0][0] dp[0][1] 1。
class Solution {
public:int dp[1005][2];int wiggleMaxLength(vectorint nums) {memset(dp, 0, sizeof dp);dp[0][0] dp[0][1] 1;for (int i 1; i nums.size(); i) {dp[i][0] dp[i][1] 1;for (int j 0; j i; j) {if (nums[j] nums[i]) dp[i][1] max(dp[i][1], dp[j][0] 1);}for (int j 0; j i; j) {if (nums[j] nums[i]) dp[i][0] max(dp[i][0], dp[j][1] 1);}}return max(dp[nums.size() - 1][0], dp[nums.size() - 1][1]);}
};时间复杂度O(n^2)空间复杂度O(n)
53. 最大子数组和
给你一个整数数组 nums 请你找出一个具有最大和的连续子数组子数组最少包含一个元素返回其最大和。
子数组 是数组中的一个连续部分。
示例 1
输入nums [-2,1,-3,4,-1,2,1,-5,4]
输出6思考用一个数记录最大和。for循环遍历如果当前子序列的和小于0则重新开始计数。
class Solution {
public:int maxSubArray(vectorint nums) {int result INT32_MIN;int count 0;for (int i 0; i nums.size(); i) {count nums[i];if (count result) { // 取区间累计的最大值相当于不断确定最大子序终止位置result count;}if (count 0) count 0; // 相当于重置最大子序起始位置因为遇到负数一定是拉低总和}return result;}
};时间复杂度O(n)空间复杂度O(1)
动态规划方法
class Solution {
public:int maxSubArray(vectorint nums) {if (nums.size() 0) return 0;vectorint dp(nums.size(), 0);dp[0] nums[0];int result dp[0];for (int i 1; i nums.size(); i) {dp[i] max(dp[i - 1] nums[i], nums[i]);if (dp[i] result) result dp[i];}return result;}
};时间复杂度O(n)空间复杂度O(n)
复盘总结
个人反思
1、贪心算法确实比较看能不能想到思路。
2、好像很多都能转成动态规划去做。