贪心算法为一门玄学
地址: 55. 跳跃游戏 - 力扣(LeetCode) (leetcode-cn.com)
该题当时的思路为找到能跳到最长的位置是否能跳的最后,但没有考虑中间有零间断与后半部分隔开,但即使想到,当时也没有想到好的解决办法
正确思路:循环求出改点之前能跳到的最大位置,用该位置比较,如果改为大于能跳到的最大位置,返回FALSE,如果无返回FALSE则返回TRUE
代码:
class Solution {
public:
bool canJump(vector<int>& nums) {
int x = 0;
if(nums.size() == 1) return true;
if(nums[0] == 0 && nums.size() > 1) return false;
for(int i = 0 ; i < nums.size(); i++){
if(i > x) return false; //若大于则说明,该位置之前的所有点能到达的最远位置都跳不过该位置
x = max(x,nums[i]+i);
}
return true;
}
};
地址:134. 加油站 - 力扣(LeetCode) (leetcode-cn.com)
解法1:暴力解法,模拟,没什么好说的上代码
class Solution {
public:
int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
int x = gas.size() , y;
for(int i = 0 ; i < x ; i++){
gas.push_back(gas[i]);
cost.push_back(cost[i]);
}
for(int i = 0 ; i < x ; i++){
y = 0;
for(int j = i ; j < i + x ; j++){
y+=gas[j];
y-=cost[j];
if(y >= 0 && j == i + x - 1) return i;
if(y <= 0) break;
}
}
return -1;
}
};
该解法还可以节省空间,就是用取余的方法模拟环,但这样看着更直观
解法2:从全局进行贪心选择
1.如果gas的总和小于cost的总和,那么哪里都到不了,直接返回-1
2.从前往后计算gas[i] - cost[i]的和的最小值min,如果最小值大于等于零,那么从初始位置哪都可以到达
3.如果min小于零,那么从后往前看,哪个节点能这个负数填平,能把这个负数填平的节点就是出发节点。
class Solution {
public:
int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
int sum = 0 , mn = INT_MAX;
for(int i = 0 ; i < gas.size() ; i++){
int rest = gas[i] - cost[i];
sum += rest;
mn = min(mn,sum);
}
if(sum < 0) return -1;
if(mn == 0) return 0;
for(int i = gas.size() - 1 ; i >= 0 ; i--){
int rest = gas[i] - cost[i];
mn += rest;
if(mn >= 0) return i;
}
return -1;
}
};
地址:179. 最大数 - 力扣(LeetCode) (leetcode-cn.com)
C++精髓: str_a > str_b
class Solution {
public:
static bool cmp(int a ,int b){ //比较方法是以sa和sb的最高位,从大到小排列的
string sa = to_string(a);
string sb = to_string(b);
return sa + sb > sb + sa;
}
string largestNumber(vector<int>& nums) {
sort(nums.begin() , nums.end() , cmp);
string str;
//该if语句为防止出现“000~”,若该数组中均未0的话,能保证只输出一个0
for(auto num : nums) if(!(num == 0 && str[0] == '0')) str += to_string(num);
return str;
}
};