目录
一、分发饼干
贪心策略:
1、首先,对 g 数组和 s 数组进行排序。
2、对两个数组从前往后同时进行遍历:
~ 如果 g[p1] <= s[p2],说明相应位置的饼干能够满足对应位置的孩子的胃口,满足的孩子数加1。那么我们就去找下一个饼干能否满足下一个孩子。
~ 如果 g[p1] > s[p2],说明相应位置的饼干不能够满足对应位置的孩子的胃口。那么该饼干更不可能满足该孩子之后的孩子了,所以直接忽略掉这块饼干,去看下一块饼干能否满足这个孩子。
解题代码:
cpp
class Solution
{
public:
int findContentChildren(vector<int>& g, vector<int>& s)
{
sort(g.begin(), g.end());
sort(s.begin(), s.end());
int p1 = 0, p2 = 0;
int ret = 0;
while(p1 < g.size() && p2 < s.size())
{
if(g[p1] <= s[p2])
{
ret++;
p1++;
p2++;
}
else
p2++;
}
return ret;
}
};
二、最优除法
贪心策略:
这道题的贪心策略很简单。直接在第一个 ' / ' 后面加 ' ( ',然后在最后添加 ' ) ',就完成了括号的添加。此时得到的结果就是最大值。
解题代码:
cpp
class Solution
{
public:
string optimalDivision(vector<int>& nums)
{
int n = nums.size();
if(n == 1)
return to_string(nums[0]);
if(n == 2)
return to_string(nums[0]) + '/' + to_string(nums[1]);
string ret = to_string(nums[0]) + '/' + '(' + to_string(nums[1]);
for(int i = 2; i < n; i++)
ret += '/' + to_string(nums[i]);
ret += ')';
return ret;
}
};
三、跳跃游戏II
贪心策略:
根据上图,我们可以分析:从棕色方框位置起跳,可以到达红色方框中的某一个数;从红色方框位置的某一个数起跳,可以到达黄色方框的某一个数; 从黄色方框位置的某一个数起跳,可以到达绿色方框的某一个数。
从棕色方框起跳到红色方框,再从红色方框跳到黄色方框,最后从黄色方框跳动绿色方框。一共跳了3次。所以说只需要三次我们就可以跳到数组末尾。
其实,这个方法有点像树的层序遍历,也就是一层一层地向后扩展。
解题代码:
cpp
class Solution
{
public:
int jump(vector<int>& nums)
{
int m = nums.size();
int left = 0, right = 0, maxpos = 0;
int ret = 0;
while(left <= right)
{
if(maxpos >= m-1)
return ret;
for(int i = left; i <= right; i++)
maxpos = max(maxpos, nums[i]+i);
left = right+1;
right = maxpos;
ret++;
}
return -1;
}
};
四、跳跃游戏
贪心策略:
这道题的贪心策略和上一道题,跳跃游戏II 的贪心策略一模一样,只是题目要求的返回结果不一样。
解题代码:
cpp
class Solution
{
public:
bool canJump(vector<int>& nums)
{
int left = 0, right = 0, maxpos = INT_MIN;
while(left <= right)
{
for(int i = left; i <= right; i++)
maxpos = max(maxpos, nums[i]+i);
if(maxpos >= nums.size()-1)
return true;
left = right + 1;
right = maxpos;
}
return false;
}
};
五、加油站
暴力解法:依次枚举数组的每一个起点,看看能不能从该起点出发,然后回到起点。
于是,我们写出了如下的代码,提交后超出了时间限制。
贪心策略:
因为暴力解法超出了时间限制,所以我们必须要想出一个优化方法。
解题代码:
cpp
class Solution
{
public:
int canCompleteCircuit(vector<int>& gas, vector<int>& cost)
{
int n = gas.size();
for(int i = 0; i < n; i++) // 枚举某一个起点
{
int ret = 0;
int step = 0;
for( ; step < n; step++)
{
int index = (i + step) % n;
ret += gas[index] - cost[index];
if(ret < 0)
break;
}
if(ret >= 0)
return i;
i = i + step;
}
return -1;
}
};