1.找钱问题
本题的贪心策略在于我们希望就可能的保留作用大的5元
class Solution {
public:
bool lemonadeChange(vector<int>& bills) {
std::map<int ,int> _map;
for(auto ch:bills)
{
if(ch == 5) _map[ch]++;
else if(ch == 10)
{
if(_map[5] == 0) return false;
else{
_map[5]--;
_map[ch]++;
}
}
else if(ch == 20){
//这里的判断_map [5]!= 0 && _map[10] != 0其实是贪心我用10元代替两张5
if(_map [5]!= 0 && _map[10] != 0)
{
_map[5]--;_map[10]--;
_map[ch]++;
}
else if(_map[5] >= 3)
{
_map[5] -= 3;
_map[ch]++;
}
else return false;
}
}
return true;
}
};
题目链接:860. 柠檬水找零 - 力扣(LeetCode)
2.最大数
这道题涉及一个知识点:一个数比另一个数大那么转换为字符串以后对应的大小关系并不会改变
那么对于 string A = "12" string B = "23" string C = "14".如果进行排序由于BA大于AB故B位于A的前面由于CA大于AC所以C位于A的前面 故顺序为:B C A那么BCA是不是他们组成的最大数呢这里显然是,但是要以此类推就能知道这题我们只需要重载排序规则就能完成,当然这题还存在一些便捷条件比如如个排序数组的开头是“0”说明这些数着的最大值就是0
class Solution {
public:
static bool compare(int a,int b)
{
std::string A = std::to_string(a);
std::string B = std::to_string(b);
std::string AB = A+B;
std::string BA = B+A;
return AB>BA;
}
string largestNumber(vector<int>& nums) {
sort(nums.begin(),nums.end(),compare);
string ret;
for(auto ch:nums) ret+=std::to_string(ch);
return ret[0] == '0'?"0":ret;
}
};
题目链接:179. 最大数 - 力扣(LeetCode)
3.摆动序列
这个题目可以理解为找到一个子序列,满足子序列内的元素时先增在减或者先减在增的,就类似正弦函数。
我们怎么才能找到最长的满足条件的子序列呢,我先做了一个我就找极大值和极小值来组成这个子序列,然后就过了,很神奇,然后看了看题解才明白为什么
看这张图,我们发现其实有三条可选择的路径但是其实本质上都是一样的,都是上升区间取一个值然后在相邻的下降区间取一个比自己小的数
那么我们的贪心策略就是直接去上升区间和下降区间的端点也就是极大值和极小值。
class Solution {
public:
int wiggleMaxLength(vector<int>& nums) {
int left = 0,right = 0;int ret = 0;
for(int i = 0;i<nums.size()-1;i++)
{
right = nums[i+1]-nums[i];
if(right == 0) continue;
else if(right*left<=0)
{
left = right;
ret++;
}
else continue;
}
return ret+1;
}
};