当前位置: 首页 > news >正文

贪心算法精选30道编程题 (附有图解和源码)

贪心算法精选30道编程题


文章目录

  • 贪心算法精选30道编程题
  • 贪心算法简介
    • 1. 柠檬⽔找零(easy)
    • 2. 将数组和减半的最少操作次数(medium)
    • 3. 最⼤数(medium)
    • 4. 摆动序列(medium)
    • 5. 最⻓递增⼦序列(medium)
    • 6. 递增的三元⼦序列(medium)
    • 7. 最⻓连续递增序列(easy)
    • 8. 买卖股票的最佳时机(easy)
    • 9. 买卖股票的最佳时机 Ⅱ(medium)
    • 10. K 次取反后最⼤化的数组和(easy)
    • 11. 按⾝⾼排序(easy)
    • 12. 优势洗牌(⽥忌赛⻢)(medium)
    • 13. 最⻓回⽂串(easy)
    • 14. 增减字符串匹配(easy)
    • 15. 分发饼⼲(easy)
    • 16. 最优除法(medium)
    • 17. 跳跃游戏 Ⅱ(medium)
    • 18. 跳跃游戏(medium)
    • 19. 加油站(medium)
    • 20. 单调递增的数字(medium)
    • 21. 坏了的计算器(medium)
    • 22. 合并区间(medium)
    • 23. ⽆重叠区间(medium)
    • 24. ⽤最少数量的箭引爆⽓球(medium)
    • 25. 整数替换(medium)
    • 26. 俄罗斯套娃信封问题(hard)
    • 27. 可被三整除的最⼤和(medium)
    • 28. 距离相等的条形码(medium)
    • 29. 重构字符串(medium)
  • 整体源代码总结


贪心算法简介

在这里插入图片描述


1. 柠檬⽔找零(easy)

Leedcode链接


在这里插入图片描述
在这里插入图片描述


在这里插入图片描述
在这里插入图片描述


代码如下(示例):

class Solution {
public:bool lemonadeChange(vector<int>& bills){int five = 0, ten = 0;for (auto x : bills){if (x == 5) five++;else if (x == 10){if (five > 0) five--, ten++;else return false;}else if (x == 20){if (five && ten) five--, ten--;else if (five >= 3) five -= 3;else return false;}}return true;}
};

2. 将数组和减半的最少操作次数(medium)

Leedcode链接


在这里插入图片描述

在这里插入图片描述


在这里插入图片描述


代码如下(示例):

class Solution {
public:int halveArray(vector<int>& nums){priority_queue<double> heap;double sum = 0.0;for (auto x : nums){heap.push(x);sum += x;}sum /= 2.0;int count = 0;while (sum > 0){double ret = heap.top() / 2.0;sum -= ret;heap.pop();count++;heap.push(ret);}return count;}
};

3. 最⼤数(medium)

Leedcode链接


在这里插入图片描述

在这里插入图片描述


在这里插入图片描述


代码如下(示例):

class Solution
{
public:string largestNumber(vector<int>& nums){// 优化:把所有的数转化成字符串vector<string> strs;for (int x : nums) strs.push_back(to_string(x));// 排序sort(strs.begin(), strs.end(), [](const string& s1, const string& s2){return s1 + s2 > s2 + s1;});// 提取结果string ret;for (auto& s : strs) ret += s;if (ret[0] == '0') return "0";return ret;}
};

4. 摆动序列(medium)

Leedcode链接


在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


在这里插入图片描述


代码如下(示例):

class Solution
{
public:int wiggleMaxLength(vector<int>& nums){int n = nums.size();if (n < 2) return n;int ret = 0, left = 0;for (int i = 0; i < n - 1; i++){int right = nums[i + 1] - nums[i]; // 计算接下来的趋势if (right == 0) continue; // 如果⽔平,直接跳过if (right * left <= 0) ret++; // 累加波峰或者波⾕left = right;}return ret + 1;}
};

5. 最⻓递增⼦序列(medium)

Leedcode链接


在这里插入图片描述

在这里插入图片描述


在这里插入图片描述


代码如下(示例):

class Solution {
public:int lengthOfLIS(vector<int>& nums){int n = nums.size();vector<int> ret;ret.push_back(nums[0]);for (int i = 1; i < n; i++){if (nums[i] > ret.back()) // 如果能接在最后⼀个元素后⾯,直接放{ret.push_back(nums[i]);}else{// ⼆分插⼊位置int left = 0, right = ret.size() - 1;while (left < right){int mid = (left + right) >> 1;if (ret[mid] < nums[i]) left = mid + 1;else right = mid;}ret[left] = nums[i]; // 放在 left 位置上}}return ret.size();}
};

6. 递增的三元⼦序列(medium)

Leedcode链接


在这里插入图片描述

在这里插入图片描述


在这里插入图片描述


代码如下(示例):

class Solution {
public:bool increasingTriplet(vector<int>& nums){int n = nums.size();int a = nums[0], b = INT_MAX;for (int i = 1; i < n; i++){if (nums[i] > b) return true;else if (nums[i] > a) b = nums[i];else a = nums[i];}return false;}
};

7. 最⻓连续递增序列(easy)

Leedcode链接


在这里插入图片描述
解题思路:贪心+双指针


在这里插入图片描述


代码如下(示例):

class Solution {
public:int findLengthOfLCIS(vector<int>& nums){int ret = 0, n = nums.size();for (int i = 0; i < n; ){int j = i + 1;while (j < n && nums[j] > nums[j - 1]) j++;ret = max(ret, j - i);i = j;}return ret;}
};

8. 买卖股票的最佳时机(easy)

Leedcode链接


在这里插入图片描述

在这里插入图片描述


在这里插入图片描述


代码如下(示例):

class Solution {
public:int maxProfit(vector<int>& prices){int ret = 0;for (int i = 0, priceMin = INT_MAX; i < prices.size(); i++){ret = max(ret, prices[i] - priceMin);priceMin = min(priceMin, prices[i]);}return ret;}
};

9. 买卖股票的最佳时机 Ⅱ(medium)

Leedcode链接


在这里插入图片描述
在这里插入图片描述


在这里插入图片描述
在这里插入图片描述


代码如下(示例):

class Solution
{
public:int maxProfit(vector<int>& p){// 实现⽅式⼀:双指针int ret = 0, n = p.size();for (int i = 0; i < n; i++){int j = i;while (j + 1 < n && p[j + 1] > p[j]) j++; // 找上升的末端ret += p[j] - p[i];i = j;}return ret;}
};
class Solution
{
public:int maxProfit(vector<int>& prices){// 实现⽅式⼆:拆分成⼀天⼀天int ret = 0;for (int i = 1; i < prices.size(); i++){if (prices[i] > prices[i - 1])ret += prices[i] - prices[i - 1];}return ret;}
};

10. K 次取反后最⼤化的数组和(easy)

Leedcode链接


在这里插入图片描述

在这里插入图片描述


在这里插入图片描述
在这里插入图片描述


代码如下(示例):

class Solution
{
public:int largestSumAfterKNegations(vector<int>& nums, int k){int m = 0, minElem = INT_MAX, n = nums.size();for (auto x : nums){if (x < 0) m++;minElem = min(minElem, abs(x)); // 求绝对值最⼩的那个数}// 分类讨论int ret = 0;if (m > k){sort(nums.begin(), nums.end());for (int i = 0; i < k; i++) // 前 k ⼩个负数,变成正数{ret += -nums[i];}for (int i = k; i < n; i++) // 后⾯的数不变{ret += nums[i];}}else{// 把所有的负数变成正数for (auto x : nums) ret += abs(x);if ((k - m) % 2) // 判断是否处理最⼩的正数{ret -= minElem * 2;}}return ret;}
};

11. 按⾝⾼排序(easy)

Leedcode链接


在这里插入图片描述

在这里插入图片描述


在这里插入图片描述


代码如下(示例):

class Solution
{
public:vector<string> sortPeople(vector<string>& names, vector<int>& heights){// 1. 创建⼀个下标数组int n = names.size();vector<int> index(n);for (int i = 0; i < n; i++) index[i] = i;// 2. 对下标进⾏排序sort(index.begin(), index.end(), [&](int i, int j){return heights[i] > heights[j];});// 3. 提取结果vector<string> ret;for (int i : index){ret.push_back(names[i]);}return ret;}
};

12. 优势洗牌(⽥忌赛⻢)(medium)

Leedcode链接


在这里插入图片描述
在这里插入图片描述


在这里插入图片描述


代码如下(示例):

class Solution
{
public:vector<int> advantageCount(vector<int>& nums1, vector<int>& nums2){int n = nums1.size();// 1. 排序sort(nums1.begin(), nums1.end());vector<int> index2(n);for (int i = 0; i < n; i++) index2[i] = i;sort(index2.begin(), index2.end(), [&](int i, int j){return nums2[i] < nums2[j];});// 2. ⽥忌赛⻢vector<int> ret(n);int left = 0, right = n - 1;for (auto x : nums1){if (x > nums2[index2[left]]) ret[index2[left++]] = x;else ret[index2[right--]] = x;}return ret;}
};

13. 最⻓回⽂串(easy)

Leedcode链接


在这里插入图片描述

在这里插入图片描述


在这里插入图片描述


代码如下(示例):

class Solution
{
public:int longestPalindrome(string s){// 1. 计数 - ⽤数组模拟哈希表int hash[127] = { 0 };for (char ch : s) hash[ch]++;// 2. 统计结果int ret = 0;for (int x : hash){ret += x / 2 * 2;}return ret < s.size() ? ret + 1 : ret;}
};

14. 增减字符串匹配(easy)

Leedcode链接


在这里插入图片描述

在这里插入图片描述


在这里插入图片描述


代码如下(示例):

class Solution {
public:vector<int> diStringMatch(string s){int left = 0, right = s.size();vector<int> ret;for (auto ch : s){if (ch == 'I') ret.push_back(left++);else ret.push_back(right--);}ret.push_back(left);return ret;}
};

15. 分发饼⼲(easy)

Leedcode链接


在这里插入图片描述


在这里插入图片描述
在这里插入图片描述


代码如下(示例):

class Solution {
public:int findContentChildren(vector<int>& g, vector<int>& s){// 先排序sort(g.begin(), g.end());sort(s.begin(), s.end());// 利⽤双指针找答案int ret = 0, n = s.size();for (int i = 0, j = 0; i < g.size() && j < n; i++, j++){while (j < n && s[j] < g[i]) j++; // 找饼⼲if (j < n) ret++;}return ret;}
};

16. 最优除法(medium)

Leedcode链接


在这里插入图片描述
在这里插入图片描述
A一定在分子上,B一定在分母上!把后面所有的数都放在分子上即可~
在这里插入图片描述


在这里插入图片描述


代码如下(示例):

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;}
};

17. 跳跃游戏 Ⅱ(medium)

Leedcode链接


在这里插入图片描述

在这里插入图片描述


在这里插入图片描述


代码如下(示例):

class Solution
{
public:int jump(vector<int>& nums){int left = 0, right = 0, maxPos = 0, ret = 0, n = nums.size();while (left <= right) // 保险的写法,以防跳不到 n - 1 的位置{if (maxPos >= n - 1) // 先判断⼀下是否已经能跳到最后⼀个位置{return ret;}// 遍历当成层,更新下⼀层的最右端点for (int i = left; i <= right; i++){maxPos = max(maxPos, nums[i] + i);}left = right + 1;right = maxPos;ret++;}return -1; // 跳不到的情况}
};

18. 跳跃游戏(medium)

Leedcode链接


在这里插入图片描述


在这里插入图片描述


代码如下(示例):

class Solution
{
public:bool canJump(vector<int>& nums){int left = 0, right = 0, maxPos = 0, n = nums.size();while (left <= right){if (maxPos >= n - 1){return true;}for (int i = left; i <= right; i++){maxPos = max(maxPos, nums[i] + i);}left = right + 1;right = maxPos;}return false;}
};

19. 加油站(medium)

Leedcode链接


在这里插入图片描述


在这里插入图片描述


代码如下(示例):

class Solution
{
public:int canCompleteCircuit(vector<int>& gas, vector<int>& cost){int n = gas.size();for (int i = 0; i < n; i++) // 依次枚举所有的起点{int rest = 0; // 标记⼀下净收益int step = 0;for (; step < n; step++) // 枚举向后⾛的步数{int index = (i + step) % n; // 求出⾛ step 步之后的下标rest = rest + gas[index] - cost[index];if (rest < 0) break;}if (rest >= 0) return i;i = i + step; // 优化}return -1;}
};

20. 单调递增的数字(medium)

Leedcode链接


在这里插入图片描述

在这里插入图片描述


在这里插入图片描述


代码如下(示例):

class Solution
{
public:int monotoneIncreasingDigits(int n){string s = to_string(n); // 把数字转化成字符串int i = 0, m = s.size();// 找第⼀个递减的位置while (i + 1 < m && s[i] <= s[i + 1]) i++;if (i + 1 == m) return n; // 判断⼀下特殊情况// 回推while (i - 1 >= 0 && s[i] == s[i - 1]) i--;s[i]--;for (int j = i + 1; j < m; j++) s[j] = '9';return stoi(s);}
};

21. 坏了的计算器(medium)

Leedcode链接


在这里插入图片描述
在这里插入图片描述


在这里插入图片描述


代码如下(示例):

class Solution {
public:int brokenCalc(int startValue, int target){int ret = 0;while (startValue < target){if (target % 2 == 0) target /= 2;else target += 1;ret++;}return ret + startValue - target;}
};

22. 合并区间(medium)

Leedcode链接


在这里插入图片描述

在这里插入图片描述


在这里插入图片描述


代码如下(示例):

class Solution
{
public:vector<vector<int>> merge(vector<vector<int>>& intervals){// 1. 先按照左端点排序sort(intervals.begin(), intervals.end());// 2. 合并区间int left = intervals[0][0], right = intervals[0][1];vector<vector<int>> ret;for (int i = 1; i < intervals.size(); i++){int a = intervals[i][0], b = intervals[i][1];if (a <= right) // 有重叠部分{// 合并 - 求并集right = max(right, b);}else // 没有重叠部分{ret.push_back({ left, right }); // 加⼊到结果中left = a;right = b;}}// 别忘了最后⼀个区间ret.push_back({ left, right });return ret;}
};

23. ⽆重叠区间(medium)

Leedcode链接


在这里插入图片描述

在这里插入图片描述


在这里插入图片描述


代码如下(示例):

class Solution
{
public:int eraseOverlapIntervals(vector<vector<int>>& intervals){// 1. 按照左端点排序sort(intervals.begin(), intervals.end());// 2. 移除区间int ret = 0;int left = intervals[0][0], right = intervals[0][1];for (int i = 1; i < intervals.size(); i++){int a = intervals[i][0], b = intervals[i][1];if (a < right) // 有重叠部分{ret++; // 删掉⼀个区间right = min(right, b);}else // 没有重叠部分{right = b;}}return ret;}
};

24. ⽤最少数量的箭引爆⽓球(medium)

Leedcode链接


在这里插入图片描述

在这里插入图片描述


在这里插入图片描述


代码如下(示例):

class Solution
{
public:int findMinArrowShots(vector<vector<int>>& points){// 1. 按照左端点排序sort(points.begin(), points.end());// 2. 求互相重叠区间的数量int right = points[0][1];int ret = 1;for (int i = 1; i < points.size(); i++){int a = points[i][0], b = points[i][1];if (a <= right) // 有重叠部分{right = min(right, b);}else // ⽆重叠部分{ret++;right = b;}}return ret;}
};

25. 整数替换(medium)

Leedcode链接


在这里插入图片描述

在这里插入图片描述


在这里插入图片描述


代码如下(示例):


// 解法一:
class Solution {
public:long long integerReplacement(long long n){return dfs(n);}long long dfs(long long n){if (n == 1) return 0;if (n % 2 == 0) return 1 + dfs(n / 2);else return 1 + min(dfs(n + 1), dfs(n - 1));}
};// 解法二:
class Solution {
public:int integerReplacement(int n) {int ret = 0;while (n > 1){// 分类讨论if (n % 2 == 0){ret++;n /= 2;}else{if (n == 3){ret += 2;n = 1;}else if (n % 4 == 1){ret += 2;n /= 2;}else{ret += 2;n = n / 2 + 1;}}}return ret;}
};

26. 俄罗斯套娃信封问题(hard)

Leedcode链接


在这里插入图片描述

在这里插入图片描述


在这里插入图片描述


代码如下(示例):

class Solution
{
public:int maxEnvelopes(vector<vector<int>>& e){// 解法⼀:动态规划// 预处理sort(e.begin(), e.end());int n = e.size();vector<int> dp(n, 1);int ret = 1;for (int i = 1; i < n; i++){for (int j = 0; j < i; j++){if (e[i][0] > e[j][0] && e[i][1] > e[j][1]){dp[i] = max(dp[i], dp[j] + 1);}}ret = max(ret, dp[i]);}return ret;}
};class Solution
{
public:int maxEnvelopes(vector<vector<int>>& e){// 解法⼆:重写排序 + 贪⼼ + ⼆分sort(e.begin(), e.end(), [&](const vector<int>& v1, const vector<int>&v2){return v1[0] != v2[0] ? v1[0] < v2[0] : v1[1] > v2[1];});// 贪⼼ + ⼆分vector<int> ret;ret.push_back(e[0][1]);for (int i = 1; i < e.size(); i++){int b = e[i][1];if (b > ret.back()){ret.push_back(b);}else{int left = 0, right = ret.size() - 1;while (left < right){int mid = (left + right) / 2;if (ret[mid] >= b) right = mid;else left = mid + 1;}ret[left] = b;}}return ret.size();}
};

27. 可被三整除的最⼤和(medium)

Leedcode链接


在这里插入图片描述

在这里插入图片描述


在这里插入图片描述


代码如下(示例):

class Solution
{
public:int maxSumDivThree(vector<int>& nums){const int INF = 0x3f3f3f3f;int sum = 0, x1 = INF, x2 = INF, y1 = INF, y2 = INF;for (auto x : nums){sum += x;if (x % 3 == 1){if (x < x1) x2 = x1, x1 = x;else if (x < x2) x2 = x;}else if (x % 3 == 2){if (x < y1) y2 = y1, y1 = x;else if (x < y2) y2 = x;}}// 分类讨论if (sum % 3 == 0) return sum;else if (sum % 3 == 1) return max(sum - x1, sum - y1 - y2);else return max(sum - y1, sum - x1 - x2);}
};

28. 距离相等的条形码(medium)

Leedcode链接


在这里插入图片描述

在这里插入图片描述


代码如下(示例):

class Solution
{
public:vector<int> rearrangeBarcodes(vector<int>& b){unordered_map<int, int> hash; // 统计每个数出现的频次int maxVal = 0, maxCount = 0;for (auto x : b){if (maxCount < ++hash[x]){maxCount = hash[x];maxVal = x;}}int n = b.size();vector<int> ret(n);int index = 0;// 先处理出现次数最多的那个数for (int i = 0; i < maxCount; i++){ret[index] = maxVal;index += 2;}// 处理剩下的数hash.erase(maxVal);for (auto& [x, y] : hash){for (int i = 0; i < y; i++){if (index >= n) index = 1;ret[index] = x;index += 2;}}return ret;}
};

29. 重构字符串(medium)

Leedcode链接


在这里插入图片描述

在这里插入图片描述


代码如下(示例):

class Solution
{
public:string reorganizeString(string s) {int hash[26] = { 0 };char maxChar = ' ';int maxCount = 0;for(auto ch : s){if(maxCount < ++hash[ch - 'a']){maxChar = ch;maxCount = hash[ch - 'a'];}}// 先判断⼀下int n = s.size();if(maxCount > (n + 1) / 2) return "";string ret(n, ' ');int index = 0;// 先处理出现次数最多的那个字符for(int i = 0; i < maxCount; i++){ret[index] = maxChar;index += 2;}hash[maxChar - 'a'] = 0;for(int i = 0; i < 26; i++){for(int j = 0; j < hash[i]; j++){if(index >= n) index = 1;ret[index] = 'a' + i;index += 2;}}return ret;}
};

整体源代码总结

代码如下(示例):

#include<iostream>
using namespace std;
#include<string>
#include<vector>//class Solution {
//public:
//    bool lemonadeChange(vector<int>& bills)
//    {
//        int five = 0, ten = 0;
//        for (auto x : bills)
//        {
//            if (x == 5) five++;
//            else if (x == 10)
//            {
//                if (five > 0) five--, ten++;
//                else return false;
//            }
//            else if (x == 20)
//            {
//                if (five && ten) five--, ten--;
//                else if (five >= 3) five -= 3;
//                else return false;
//            }
//        }
//        return true;
//    }
//};#include<queue>//class Solution {
//public:
//    int halveArray(vector<int>& nums)
//    {
//        priority_queue<double> heap;
//        double sum = 0.0;
//        for (auto x : nums)
//        {
//            heap.push(x);
//            sum += x;
//        }
//        sum /= 2.0;
//        int count = 0;
//        while (sum > 0)
//        {
//            double ret = heap.top() / 2.0;
//            sum -= ret;
//            heap.pop();
//            count++;
//            heap.push(ret);
//        }
//        return count;
//    }
//};//class Solution
//{
//public:
//	string largestNumber(vector<int>& nums)
//	{
//		// 优化:把所有的数转化成字符串
//		vector<string> strs;
//		for (int x : nums) strs.push_back(to_string(x));
//		// 排序
//		sort(strs.begin(), strs.end(), [](const string& s1, const string& s2)
//			{
//				return s1 + s2 > s2 + s1;
//			});
//		// 提取结果
//		string ret;
//		for (auto& s : strs) ret += s;
//		if (ret[0] == '0') return "0";
//		return ret;
//	}
//};//class Solution
//{
//public:
//    int wiggleMaxLength(vector<int>& nums)
//    {
//        int n = nums.size();
//        if (n < 2) return n;
//        int ret = 0, left = 0;
//        for (int i = 0; i < n - 1; i++)
//        {
//            int right = nums[i + 1] - nums[i]; // 计算接下来的趋势
//            if (right == 0) continue; // 如果⽔平,直接跳过
//            if (right * left <= 0) ret++; // 累加波峰或者波⾕
//            left = right;
//        }
//        return ret + 1;
//    }
//};//class Solution {
//public:
//	int lengthOfLIS(vector<int>& nums)
//	{
//		int n = nums.size();
//		vector<int> ret;
//		ret.push_back(nums[0]);
//		for (int i = 1; i < n; i++)
//		{
//			if (nums[i] > ret.back()) // 如果能接在最后⼀个元素后⾯,直接放
//			{
//				ret.push_back(nums[i]);
//			}
//			else
//			{
//				// ⼆分插⼊位置
//				int left = 0, right = ret.size() - 1;
//				while (left < right)
//				{
//					int mid = (left + right) >> 1;
//					if (ret[mid] < nums[i]) left = mid + 1;
//					else right = mid;
//				}
//				ret[left] = nums[i]; // 放在 left 位置上
//			}
//		}
//		return ret.size();
//	}
//};//class Solution {
//public:
//    bool increasingTriplet(vector<int>& nums)
//    {
//        int n = nums.size();
//        int a = nums[0], b = INT_MAX;
//        for (int i = 1; i < n; i++)
//        {
//            if (nums[i] > b) return true;
//            else if (nums[i] > a) b = nums[i];
//            else a = nums[i];
//        }
//        return false;
//    }
//};//class Solution {
//public:
//    int findLengthOfLCIS(vector<int>& nums)
//    {
//        int ret = 0, n = nums.size();
//        for (int i = 0; i < n; )
//        {
//            int j = i + 1;
//            while (j < n && nums[j] > nums[j - 1]) j++;
//            ret = max(ret, j - i);
//            i = j;
//        }
//        return ret;
//    }
//};//class Solution {
//public:
//    int maxProfit(vector<int>& prices)
//    {
//        int ret = 0;
//        for (int i = 0, priceMin = INT_MAX; i < prices.size(); i++)
//        {
//            ret = max(ret, prices[i] - priceMin);
//            priceMin = min(priceMin, prices[i]);
//        }
//        return ret;
//    }
//};//class Solution
//{
//public:
//	int maxProfit(vector<int>& p)
//	{
//		// 实现⽅式⼀:双指针
//		int ret = 0, n = p.size();
//		for (int i = 0; i < n; i++)
//		{
//			int j = i;
//			while (j + 1 < n && p[j + 1] > p[j]) j++; // 找上升的末端
//			ret += p[j] - p[i];
//			i = j;
//		}
//		return ret;
//	}
//};
//class Solution
//{
//public:
//	int maxProfit(vector<int>& prices)
//	{
//		// 实现⽅式⼆:拆分成⼀天⼀天
//		int ret = 0;
//		for (int i = 1; i < prices.size(); i++)
//		{
//			if (prices[i] > prices[i - 1])
//				ret += prices[i] - prices[i - 1];
//		}
//		return ret;
//	}
//};//class Solution
//{
//public:
//	int largestSumAfterKNegations(vector<int>& nums, int k)
//	{
//		int m = 0, minElem = INT_MAX, n = nums.size();
//		for (auto x : nums)
//		{
//			if (x < 0) m++;
//			minElem = min(minElem, abs(x)); // 求绝对值最⼩的那个数
//		}
//		// 分类讨论
//		int ret = 0;
//		if (m > k)
//		{
//			sort(nums.begin(), nums.end());
//			for (int i = 0; i < k; i++) // 前 k ⼩个负数,变成正数
//			{
//				ret += -nums[i];
//			}
//			for (int i = k; i < n; i++) // 后⾯的数不变
//			{
//				ret += nums[i];
//			}
//		}
//		else
//		{
//			// 把所有的负数变成正数
//			for (auto x : nums) ret += abs(x);
//			if ((k - m) % 2) // 判断是否处理最⼩的正数
//			{
//				ret -= minElem * 2;
//			}
//		}
//		return ret;
//	}
//};//class Solution
//{
//public:
//	vector<string> sortPeople(vector<string>& names, vector<int>& heights)
//	{
//		// 1. 创建⼀个下标数组
//		int n = names.size();
//		vector<int> index(n);
//		for (int i = 0; i < n; i++) index[i] = i;
//		// 2. 对下标进⾏排序
//		sort(index.begin(), index.end(), [&](int i, int j)
//			{
//				return heights[i] > heights[j];
//			});
//		// 3. 提取结果
//		vector<string> ret;
//		for (int i : index)
//		{
//			ret.push_back(names[i]);
//		}
//		return ret;
//	}
//};//class Solution
//{
//public:
//	vector<int> advantageCount(vector<int>& nums1, vector<int>& nums2)
//	{
//		int n = nums1.size();
//		// 1. 排序
//		sort(nums1.begin(), nums1.end());
//		vector<int> index2(n);
//		for (int i = 0; i < n; i++) index2[i] = i;
//		sort(index2.begin(), index2.end(), [&](int i, int j)
//			{
//				return nums2[i] < nums2[j];
//			});
//		// 2. ⽥忌赛⻢
//		vector<int> ret(n);
//		int left = 0, right = n - 1;
//		for (auto x : nums1)
//		{
//			if (x > nums2[index2[left]]) ret[index2[left++]] = x;
//			else ret[index2[right--]] = x;
//		}
//		return ret;
//	}
//};// LINUX
//struct shmid_ds {
//	struct ipc_perm shm_perm; /* operation perms */
//	int shm_segsz; /* size of segment
//	(bytes) */
//	__kernel_time_t shm_atime; /* last attach time
//	*/
//	__kernel_time_t shm_dtime; /* last detach time
//	*/
//	__kernel_time_t shm_ctime; /* last change time
//	*/
//	__kernel_ipc_pid_t shm_cpid; /* pid of creator */
//	__kernel_ipc_pid_t shm_lpid; /* pid of last operator */
//	unsigned short shm_nattch; /* no. of current
//	attaches */
//	unsigned short shm_unused; /* compatibility */
//	void shm_unused2; / ditto - used by
//		DIPC * /
//		void shm_unused3; / unused * /
//};//class Solution
//{
//public:
//	int longestPalindrome(string s)
//	{
//		// 1. 计数 - ⽤数组模拟哈希表
//		int hash[127] = { 0 };
//		for (char ch : s) hash[ch]++;
//		// 2. 统计结果
//		int ret = 0;
//		for (int x : hash)
//		{
//			ret += x / 2 * 2;
//		}
//		return ret < s.size() ? ret + 1 : ret;
//	}
//};//class Solution {
//public:
//    vector<int> diStringMatch(string s)
//    {
//        int left = 0, right = s.size();
//        vector<int> ret;
//        for (auto ch : s)
//        {
//            if (ch == 'I') ret.push_back(left++);
//            else ret.push_back(right--);
//        }
//        ret.push_back(left);
//        return ret;
//    }
//};//class Solution {
//public:
//	int findContentChildren(vector<int>& g, vector<int>& s)
//	{
//		// 先排序
//		sort(g.begin(), g.end());
//		sort(s.begin(), s.end());
//		// 利⽤双指针找答案
//		int ret = 0, n = s.size();
//		for (int i = 0, j = 0; i < g.size() && j < n; i++, j++)
//		{
//			while (j < n && s[j] < g[i]) j++; // 找饼⼲
//			if (j < n) ret++;
//		}
//		return ret;
//	}
//};//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;
//    }
//};//class Solution
//{
//public:
//	int jump(vector<int>& nums)
//	{
//		int left = 0, right = 0, maxPos = 0, ret = 0, n = nums.size();
//		while (left <= right) // 保险的写法,以防跳不到 n - 1 的位置
//		{
//			if (maxPos >= n - 1) // 先判断⼀下是否已经能跳到最后⼀个位置
//			{
//				return ret;
//			}
//			// 遍历当成层,更新下⼀层的最右端点
//			for (int i = left; i <= right; i++)
//			{
//				maxPos = max(maxPos, nums[i] + i);
//			}
//			left = right + 1;
//			right = maxPos;
//			ret++;
//		}
//		return -1; // 跳不到的情况
//	}
//};//class Solution
//{
//public:
//	bool canJump(vector<int>& nums)
//	{
//		int left = 0, right = 0, maxPos = 0, n = nums.size();
//		while (left <= right)
//		{
//			if (maxPos >= n - 1)
//			{
//				return true;
//			}
//			for (int i = left; i <= right; i++)
//			{
//				maxPos = max(maxPos, nums[i] + i);
//			}
//			left = right + 1;
//			right = maxPos;
//		}
//		return false;
//	}
//};//class Solution
//{
//public:
//	int canCompleteCircuit(vector<int>& gas, vector<int>& cost)
//	{
//		int n = gas.size();
//		for (int i = 0; i < n; i++) // 依次枚举所有的起点
//		{
//			int rest = 0; // 标记⼀下净收益
//			int step = 0;
//			for (; step < n; step++) // 枚举向后⾛的步数
//			{
//				int index = (i + step) % n; // 求出⾛ step 步之后的下标
//				rest = rest + gas[index] - cost[index];
//				if (rest < 0) break;
//			}
//			if (rest >= 0) return i;
//			i = i + step; // 优化
//		}
//		return -1;
//	}
//};//class Solution
//{
//public:
//	int monotoneIncreasingDigits(int n)
//	{
//		string s = to_string(n); // 把数字转化成字符串
//		int i = 0, m = s.size();
//		// 找第⼀个递减的位置
//		while (i + 1 < m && s[i] <= s[i + 1]) i++;
//		if (i + 1 == m) return n; // 判断⼀下特殊情况
//		// 回推
//		while (i - 1 >= 0 && s[i] == s[i - 1]) i--;
//		s[i]--;
//		for (int j = i + 1; j < m; j++) s[j] = '9';
//		return stoi(s);
//	}
//};//class Solution {
//public:
//    int brokenCalc(int startValue, int target)
//    {
//        int ret = 0;
//        while (startValue < target)
//        {
//            if (target % 2 == 0) target /= 2;
//            else target += 1;
//            ret++;
//        }
//        return ret + startValue - target;
//    }
//};//class Solution
//{
//public:
//	vector<vector<int>> merge(vector<vector<int>>& intervals)
//	{
//		// 1. 先按照左端点排序
//		sort(intervals.begin(), intervals.end());
//		// 2. 合并区间
//		int left = intervals[0][0], right = intervals[0][1];
//		vector<vector<int>> ret;
//		for (int i = 1; i < intervals.size(); i++)
//		{
//			int a = intervals[i][0], b = intervals[i][1];
//			if (a <= right) // 有重叠部分
//			{
//				// 合并 - 求并集
//				right = max(right, b);
//			}
//			else // 没有重叠部分
//			{
//				ret.push_back({ left, right }); // 加⼊到结果中
//				left = a;
//				right = b;
//			}
//		}
//		// 别忘了最后⼀个区间
//		ret.push_back({ left, right });
//		return ret;
//	}
//};//class Solution
//{
//public:
//	int eraseOverlapIntervals(vector<vector<int>>& intervals)
//	{
//		// 1. 按照左端点排序
//		sort(intervals.begin(), intervals.end());
//		// 2. 移除区间
//		int ret = 0;
//		int left = intervals[0][0], right = intervals[0][1];
//		for (int i = 1; i < intervals.size(); i++)
//		{
//			int a = intervals[i][0], b = intervals[i][1];
//			if (a < right) // 有重叠部分
//			{
//				ret++; // 删掉⼀个区间
//				right = min(right, b);
//			}
//			else // 没有重叠部分
//			{
//				right = b;
//			}
//		}
//		return ret;
//	}
//};//class Solution
//{
//public:
//	int findMinArrowShots(vector<vector<int>>& points)
//	{
//		// 1. 按照左端点排序
//		sort(points.begin(), points.end());
//		// 2. 求互相重叠区间的数量
//		int right = points[0][1];
//		int ret = 1;
//		for (int i = 1; i < points.size(); i++)
//		{
//			int a = points[i][0], b = points[i][1];
//			if (a <= right) // 有重叠部分
//			{
//				right = min(right, b);
//			}
//			else // ⽆重叠部分
//			{
//				ret++;
//				right = b;
//			}
//		}
//		return ret;
//	}
//};//class Solution {
//public:
//    int integerReplacement(int n) {
//
//        int ret = 0;
//        while (n > 1)
//        {
//            // 分类讨论
//            if (n % 2 == 0)
//            {
//                ret++;
//                n /= 2;
//            }
//            else
//            {
//                if (n == 3)
//                {
//                    ret += 2;
//                    n = 1;
//                }
//                else if (n % 4 == 1)
//                {
//                    ret += 2;
//                    n /= 2;
//                }
//                else
//                {
//                    ret += 2;
//                    n = n / 2 + 1;
//                }
//            }
//        }
//        return ret;
//    }
//};//// 解法一:
//class Solution {
//public:
//    long long integerReplacement(long long n)
//    {
//        return dfs(n);
//    }
//    long long dfs(long long n)
//    {
//        if (n == 1) return 0;
//        if (n % 2 == 0) return 1 + dfs(n / 2);
//        else return 1 + min(dfs(n + 1), dfs(n - 1));
//    }
//};//class Solution
//{
//public:
//	int maxEnvelopes(vector<vector<int>>& e)
//	{
//		// 解法⼀:动态规划
//		// 预处理
//		sort(e.begin(), e.end());
//		int n = e.size();
//		vector<int> dp(n, 1);
//		int ret = 1;
//		for (int i = 1; i < n; i++)
//		{
//			for (int j = 0; j < i; j++)
//			{
//				if (e[i][0] > e[j][0] && e[i][1] > e[j][1])
//				{
//					dp[i] = max(dp[i], dp[j] + 1);
//				}
//			}
//			ret = max(ret, dp[i]);
//		}
//		return ret;
//	}
//};
//
//
//class Solution
//{
//public:
//	int maxEnvelopes(vector<vector<int>>& e)
//	{
//		// 解法⼆:重写排序 + 贪⼼ + ⼆分
//		sort(e.begin(), e.end(), [&](const vector<int>& v1, const vector<int>&
//			v2)
//			{
//				return v1[0] != v2[0] ? v1[0] < v2[0] : v1[1] > v2[1];
//			});
//		// 贪⼼ + ⼆分
//		vector<int> ret;
//		ret.push_back(e[0][1]);
//		for (int i = 1; i < e.size(); i++)
//		{
//			int b = e[i][1];
//			if (b > ret.back())
//			{
//				ret.push_back(b);
//			}
//			else
//			{
//				int left = 0, right = ret.size() - 1;
//				while (left < right)
//				{
//					int mid = (left + right) / 2;
//					if (ret[mid] >= b) right = mid;
//					else left = mid + 1;
//				}
//				ret[left] = b;
//			}
//		}
//		return ret.size();
//	}
//};//class Solution
//{
//public:
//	int maxSumDivThree(vector<int>& nums)
//	{
//		const int INF = 0x3f3f3f3f;
//		int sum = 0, x1 = INF, x2 = INF, y1 = INF, y2 = INF;
//		for (auto x : nums)
//		{
//			sum += x;
//			if (x % 3 == 1)
//			{
//				if (x < x1) x2 = x1, x1 = x;
//				else if (x < x2) x2 = x;
//			}
//			else if (x % 3 == 2)
//			{
//				if (x < y1) y2 = y1, y1 = x;
//				else if (x < y2) y2 = x;
//			}
//		}
//		// 分类讨论
//		if (sum % 3 == 0) return sum;
//		else if (sum % 3 == 1) return max(sum - x1, sum - y1 - y2);
//		else return max(sum - y1, sum - x1 - x2);
//	}
//};//class Solution
//{
//public:
//    vector<int> rearrangeBarcodes(vector<int>& b)
//    {
//        unordered_map<int, int> hash; // 统计每个数出现的频次
//        int maxVal = 0, maxCount = 0;
//        for (auto x : b)
//        {
//            if (maxCount < ++hash[x])
//            {
//                maxCount = hash[x];
//                maxVal = x;
//            }
//        }
//        int n = b.size();
//        vector<int> ret(n);
//        int index = 0;
//        // 先处理出现次数最多的那个数
//        for (int i = 0; i < maxCount; i++)
//        {
//            ret[index] = maxVal;
//            index += 2;
//        }
//        // 处理剩下的数
//        hash.erase(maxVal);
//        for (auto& [x, y] : hash)
//        {
//            for (int i = 0; i < y; i++)
//            {
//                if (index >= n) index = 1;
//                ret[index] = x;
//                index += 2;
//            }
//        }
//        return ret;
//    }
//};//class Solution
//{
//public:
//    string reorganizeString(string s)
//    {
//        int hash[26] = { 0 };
//        char maxChar = ' ';
//        int maxCount = 0;
//        for (auto ch : s)
//        {
//            if (maxCount < ++hash[ch - 'a'])
//            {
//                maxChar = ch;
//                maxCount = hash[ch - 'a'];
//            }
//        }
//        // 先判断⼀下
//        int n = s.size();
//        if (maxCount > (n + 1) / 2) return "";
//        string ret(n, ' ');
//        int index = 0;
//        // 先处理出现次数最多的那个字符
//        for (int i = 0; i < maxCount; i++)
//        {
//            ret[index] = maxChar;
//            index += 2;
//        }
//        hash[maxChar - 'a'] = 0;
//        for (int i = 0; i < 26; i++)
//        {
//            for (int j = 0; j < hash[i]; j++)
//            {
//                if (index >= n) index = 1;
//                ret[index] = 'a' + i;
//                index += 2;
//            }
//        }
//        return ret;
//    }
//};
http://www.dtcms.com/a/482768.html

相关文章:

  • 五莲县财源建设网站为什么网站建设图片显示不出来
  • 第11周中间件漏洞
  • 【MySQL】从零开始了解数据库开发 --- 复合查询
  • 解决 Git 推送冲突:使用 Rebase 整合远程更改
  • synchronized锁升级过程详解
  • mit6s081 lab8 locks
  • 建站培训企业管理考研
  • MySQL中的数据类型占用空间和范围
  • Docker部署jenkins集成全自动打包部署
  • 台州自助建站公司做好的网站怎么发布
  • 重磅更新:Claude Code 现在支持插件啦
  • 23种设计模式——访问者模式 (Visitor Pattern)
  • 卧龙区微网站开发网络管理系统怎么打开
  • java用注解优雅校验入参
  • 平台网站建设收费制作网页素材图片
  • 基于OpenCV的实时疲劳检测系统实现
  • HTML5基础——4、表格
  • Docker 通信核心:docker.sock 完全指南
  • Flutter---Button
  • 网站建设需要敲代码吗信息流推广实施策划书
  • 广元网站建设电子商务网站建设主要内容
  • 4.4-中间件之gRPC
  • 网络与通信安全课程复习汇总1——课程导入
  • Qt模型控件:QTreeViewQTreeWidget
  • 河南省城乡建设厅官网廊坊快速优化排名
  • 网站建设应该考虑哪些问题企信宝
  • 青海做网站最好的公司互联网推广引流
  • 一天一个设计模式——装饰器模式
  • 婚恋交友 APP 核心功能分析:从匹配逻辑到用户体验的全链路设计
  • 用一个 prompt 搭建带 React 界面的 Java 桌面应用