第八章 贪心算法part03

2026.03.19 03.02 第三十四天

134 加油站

有多种做法, 其中贪心算法通过累计当前起点到当前位置的剩余油量来判断当前起点是否符合要求,不符合则更新起点。

class Solution {
public:
    int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
        int curSum = 0;
        int start = 0;
        int totalSum = 0;
        for(int i = 0; i < gas.size(); i++) {
            curSum += gas[i] - cost[i];
            totalSum += gas[i] - cost[i];
            if(curSum < 0) {
                start = i + 1;
                curSum = 0;
            }
        }
        if(totalSum < 0) return -1;
        return start;
    }
};

135 分发糖果

较难一题,看了正确思路之后就能很快做出来。

解题思想是先从一边找起,之后再从另一边找,最后取最大值。

class Solution {
public:
    int candy(vector<int>& ratings) {
        vector<int> candyVec(ratings.size(), 1);
        for(int i = 1; i < ratings.size(); i++) {
            if(ratings[i] > ratings[i - 1]) candyVec[i] = candyVec[i - 1] + 1;
        }
        for(int i = ratings.size() - 2; i >= 0; i--) {
            if(ratings[i] > ratings[i + 1]) candyVec[i] = max(candyVec[i], candyVec[i + 1] + 1);
        }
        int sum = 0;
        for(const int& c : candyVec) sum += c;
        return sum;
    }
};

860 柠檬水找零

很简单一道题,大一刚学C的时候就写过,不过当时没有注意这么多逻辑上的问题,写出来就完事了~

贪心的关键是小钱更万能,因此找零的时候优先找大钱,也就是优先找10刀,没有10再用5刀面额。

class Solution {
public:
    bool lemonadeChange(vector<int>& bills) {
        vector<int> money(3, 0);
        for(int i = 0; i < bills.size(); i++) {
            if(bills[i] == 5) {
                money[0]++;
                continue;
            }
            else if(bills[i] == 10) {
                if(money[0] > 0) {
                    money[0]--;
                    money[1]++;
                    continue;
                }
                return false;
            }
            else {
                if(money[1] > 0 && money[0] > 0) {
                    money[2]++;
                    money[1]--;
                    money[0]--;
                    continue;
                }
                else if(money[1] == 0 && money[0] > 2) {
                    money[2]++;
                    money[0] -= 3;
                    continue;
                }
                return false;
            }
        }
        return true;
    }
};
## 406 根据身高重建队列

与分配糖果类似,首先根据身高进行排序,由大到小排列之后,会发现,根据当前已经排好序的数组,从前往后,按照k的值插入队列就得到了要求的结果。非常巧妙的思想。

class Solution {
private:
static bool cmp(const vector& a, const vector& b) {
if(a[0] == b[0]) return a[1] < b[1];
return a[0] > b[0];
}

public:
vector<vector> reconstructQueue(vector<vector>& people) {
sort(people.begin(), people.end(), cmp);
list<vector> queue;
for(int i = 0; i < people.size(); i++) {
int position = people[i][1];
auto iter = queue.begin();
while(position--) {
iter++;
}
queue.insert(iter, people[i]);
}
return vector<vector>(queue.begin(), queue.end());
}
};

posted @ 2026-03-19 17:48  遠くの君  阅读(1)  评论(0)    收藏  举报