【C++刷题】优选算法——贪心第二辑

  1. 按身高排序
    在这里插入图片描述
// 解法一
class Solution {
    map<int, string, greater<int>> person;
    vector<string> ret;
public:
    vector<string> sortPeople(vector<string>& names, vector<int>& heights) {
        int n = names.size();
        for (int i = 0; i < n; ++i) {
            person[heights[i]] = names[i];
        }
        for (auto& e : person) {
            ret.push_back(e.second);
        }
        return ret;
    }
};

// 解法二
class Solution {
public:
    vector<string> sortPeople(vector<string>& names, vector<int>& heights) {
        int n = names.size();
        vector<int> index(n);
        for (int i = 0; i < n; ++i) index[i] = i;
        ranges::sort(index, [&heights](int left, int right){
            return heights[left] > heights[right];
        });
        vector<string> ret;
        for (int i : index) {
            ret.push_back(names[i]);
        }
        return ret;
    }
};
  1. 优势洗牌
    在这里插入图片描述
    先排序
    如果比不过,就去拖累最强的哪一个
    如果能比过,那就直接比
class Solution {
public:
    vector<int> advantageCount(vector<int>& nums1, vector<int>& nums2) {
        vector<int> index(nums2.size());
        for (int i = 0; i < index.size(); ++i) index[i] = i;
        ranges::sort(index, [&nums2](int left, int right){
            return nums2[left] < nums2[right];
        });

        ranges::sort(nums1);
        ranges::sort(nums2);

        vector<int> ret(nums1.size());
        int start = 0, end = nums1.size() - 1;
        for (int e : nums1) {
            if (e > nums2[start]) {
                ret[index[start++]] = e;
            } else {
                ret[index[end--]] = e;
            }
        }

        return ret;
    }
};
  1. 最长回文串
    在这里插入图片描述
class Solution {
public:
    int longestPalindrome(string s) {
        vector<int> v(256);
        for (char c : s) {
            if (v[c] == 0) v[c] = 1;
            else v[c] = 0;
        }
        int count = 0;
        for (int e : v) count += e;

        if (count > 0) return s.size() - count + 1;
        else return s.size();
    }
};
  1. 增减字符串匹配
    在这里插入图片描述
class Solution {
public:
    vector<int> diStringMatch(string s) {
        vector<int> ret;
        int start = 0, end = s.size();;
        for (char c : s) {
            if (c == 'I') {
                ret.push_back(start++);
            } else {
                ret.push_back(end--);
            }
        }
        ret.push_back(start);
        return ret;
    }
};
  1. 分发饼干
    在这里插入图片描述
class Solution {
public:
    int findContentChildren(vector<int>& g, vector<int>& s) {
        ranges::sort(g);
        ranges::sort(s);

        int count = 0, i = 0;
        for (int e : g) {
            while (i < s.size() && s[i] < e) ++i;
            if (i < s.size()) {
                ++count;
                ++i;
            } else break;
        }
        return count;
    }
};
  1. 最优除法
    在这里插入图片描述
class Solution {
public:
    string optimalDivision(vector<int>& nums) {
        if (nums.size() == 1) return to_string(nums[0]);
        else if (nums.size() == 2) return to_string(nums[0]) + "/" + to_string(nums[1]);
        string ret;
        ret += to_string(nums[0]);
        ret += "/(";
        for (int i = 1; i < nums.size() - 1; ++i) {
            ret += to_string(nums[i]);
            ret += "/";
        }
        ret += to_string(nums.back());
        ret += ")";
        return ret;
    }
};
  1. 跳跃游戏 II
    在这里插入图片描述
// 解法一
int jump(vector<int>& nums) {
    if (0 >= nums.size() - 1) return 0;
    if (0 + nums[0] >= nums.size() - 1) return 1;

    int i = 0, count = 0;
    while (i < nums.size()) {
        int start = i, len = nums[i];
        for (int j = 1; j <= nums[i]; ++j) {
            if (i + j < nums.size() && i + j + nums[i + j] > start + len) {
                start = i + j;
                len = nums[i + j];
            }
        }
        ++count;
        i = start;
        if (start + len >= nums.size() - 1) {
            break;
        }
    }
    return count + 1;
}

// 解法二
int jump(vector<int>& nums) {
    int count = 0;
    int left = 0, right = 0;
    while (right < nums.size() - 1) {
        int max_right = right + 1;
        while (left <= right) {
            max_right = max(max_right, left + nums[left]);
            ++left;
        }
        left = right + 1;
        right = max_right;
        ++count;
    }
    return count;
}
  1. 跳跃游戏
    在这里插入图片描述
class Solution {
public:
    bool canJump(vector<int>& nums) {
        int left = 0, int right = 0;
        int max_right = 0;
        while (left <= right) {
            if (max_right >= nums.size() - 1) return true;
            for (int i = left; i <= right; ++i) {
                max_right = max(max_right, i + nums[i]);
            }
            left = right + 1;
            right = max_right;
        }
        return false;
    }
};
  1. 加油站
    在这里插入图片描述
int canCompleteCircuit(vector<int>& gas, vector<int>& cost) {
    int n = gas.size();
    vector<int> diff(n);
    for (int i = 0; i < n; ++i) {
        diff[i] = gas[i] - cost[i];
    }

    for (int i = 0; i < n;) {
        if (diff[i] >= 0) {
            int cur = diff[i];
            for (int j = i + 1; j < n; ++j) {
                cur += diff[j];
                if (cur < 0) {
                    i = j + 1;
                    break;
                }
            }
            if (cur < 0) {
                continue;
            }
            for (int j = 0; j < i; ++j) {
                cur += diff[j];
                if (cur < 0) {
                    return -1;
                }
            }
            return i;
        } else {
            ++i;
        }
    }
    return -1;
}
  1. 单调递增的数字
    在这里插入图片描述
    如果高位递增,就不去修改
    从左向右,找到第一个递减的位置
    从这个位置向前推,找到相同区域的最左端,使其减小 1,后面的数修改成 9
int monotoneIncreasingDigits(int n) {
    string s = to_string(n);
    int i = 1;
    for (; i < s.size(); ++i) {
        if (s[i] < s[i-1]) break;
    }
    if (i == s.size()) return stoi(s);
    
    int j = i - 1;
    for (; j > 0; --j) {
        if (s[j] != s[j-1]) {
            s[j] -= 1;
            break;
        }
    }
    if (j == 0) {
        if (s[j] != '1') {
            s[j] -= 1;
        } else {
            s.erase(s.begin());
            j -= 1;
        }
    }
    for (j += 1; j < s.size(); ++j) {
        s[j] = '9';
    }
    return stoi(s);
}
  • 12
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿阿阿顺Yaya

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值