目录
1.摆动序列
可以两种方法解决
- 动归
设置两种状态
dp[i][0]:表示下标i作为波峰,前i个数中的最长的摆动子序列长度
dp[i][1]:表示下标i作为波谷,前i个数最长的摆动子序列长度
因为dp[0][0]和dp[0][1]本身就可以作为长度为1的摆动子序列,所以设置为1
int dp[1001][2];
int wiggleMaxLength(vector<int>& nums) {
memset(dp, 0, sizeof(dp));
dp[0][0] = dp[0][1] = 1;
for (int i = 0; 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][0] = max(dp[j][1] + 1, dp[i][0]);
}
for (int j = 0; j < i; j++)
{
if (nums[j] > nums[i])
dp[i][1] = max(dp[j][0] + 1, dp[i][1]);
}
}
return max(dp[nums.size() - 1][1], dp[nums.size() - 1][0]);
- 贪心算法
int wiggleMaxLength(vector<int>& nums) {
if (nums.size() <= 1) return nums.size();
int ans = 1;
int pregap = 0, curgap = 0;
for (int i = 0; i < nums.size() - 1; i++)
{
curgap = nums[i + 1] - nums[i];
if ((pregap <= 0 && curgap > 0) || (pregap >= 0 && curgap < 0))
{
ans++;
pregap = curgap;
}
}
return ans;
}
2.分饼干
首先把饼干和小孩的胃口排序,保证小饼干可以喂给小胃口的孩子
用for遍历饼干,保证每一个饼干都有被分出去的机会
用一个下标index遍历小孩,如果小孩的胃口g[i]和饼干s[i]保持g[i]<=s[i]的关系,那么这个饼干就可以被给
int findContentChildren(vector<int>& g, vector<int>& s) {
int index=0;
sort(s.begin(),s.end());
sort(g.begin(),g.end());
for(int i=0;i<s.size();i++)
{
if(index<g.size()&&g[index]<=s[i]) index++;
}
return index;
}
3.最大子数组和
这个题和第一题的dp状态法差不多,把 dp[i]表示下标为i处的最大子数组的和,然后用一个MAX元素把dp里面最大的元素记录下来,就是最大的子数组和,因为每个元素都精确到下标,所以dp中的每一个元素都是连续子数组和
int maxSubArray(vector<int>& nums) {
if(nums.empty()) return 0;
vector<int> dp(nums.size());
dp[0]=nums[0];
int MAX=nums[0];
for(int i=1;i<nums.size();i++)
{
dp[i]=max(dp[i-1]+nums[i],nums[i]);
if(dp[i]>MAX) MAX=dp[i];
}
return MAX;
}
4.买卖股票的最佳时机 II
因为题目规定了可以当天买卖,所以只要今天比昨天大,那就+=差值 ,相当于昨天买今天卖,如果有很多个今天比昨天大的情况
比如 [7,1,5,6] ans+=5-1 第三天卖,第二天买
ans+=6-5 第四天卖第三天买
总体来看就是第二天买,第三天卖了又买(买回来是因为明天还有红利),第四天再卖
int maxProfit(vector<int>& prices) {
int ans=0;
for(int i=1;i<prices.size();i++)
{
if(prices[i]>prices[i-1])
ans+=prices[i]-prices[i-1];
}
return ans;
}
5.跳跃游戏
首先你在第一格,往后遍历的时候每次先-1步数,如果当前下标的最远步数比你目前能跳的步数(cur)还大,那么cur=nums[i]
bool canJump(vector<int>& nums) {
int cur=nums[0];
int i=1;
for(;cur && i<nums.size();i++)
{
cur--;
if(cur<nums[i]) cur=nums[i];
}
return i==nums.size();
}
6.跳跃游戏 II
用dp[i]状态记录到达下标i需要的最少步数
如果只有一个元素,不需要跳
step数组记录每个状态所能到达的最大位置
int jump(vector<int>& nums) {
if(nums.size()==1) return 0;
vector<int> dp(nums.size());
dp[0]=0;
vector<int> step(nums.size());
step[1]=nums[0];
for(int i=1;i<nums.size();i++)
{
dp[i]=step[dp[i-1]]>=i?dp[i-1]:dp[i-1]+1;
if(dp[i]+1 < nums.size())
step[dp[i]+1]=max(step[dp[i]+1],i+nums[i]);
}
return dp[nums.size()-1];
}