贪心算法专题练习

1. K次取反后最大化的数组和

这个题目的贪心就体现在最小的负数取反之后对整个数组和的贡献是最大的,直接上思路:

直接上代码:

cpp 复制代码
class Solution {
public:
    int largestSumAfterKNegations(vector<int>& nums, int k) {
        int m = 0;
        int n = nums.size();
        int minNum = INT_MAX;
        int ret = 0;
        for(auto& e : nums)
        {
            if(e < 0) m++;
            minNum = min(minNum, abs(e)); // 求绝对值最小元素
        }
        // 分类讨论
        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 != 0) // 判断是否处理最⼩的正数
            {
                ret -= minNum * 2;
            }
        }
        return ret;  
    }
};

2. 按身高排序

这个题目比较简单,按照贪心的思想我们只需要按照身高的最大值排序即可,但是仍有一些细节问题,我们不能直接按照i位置对应的heights来排序,因为排序过程是会移动元素的,但是names内的元素是不会移动的。由题意可知,names 数组和heights数组的下标是一一对应的, 因此我们可以重新创建出来一个下标数组,将这个下标数组按照heights[i]的大小排序。那么,当下标数组排完序之后,里面的顺序就相当于heights这个数组排完序之后的下标。之后通过排序后的下标,依次找到原来的name,完成对名字的排序。

直接上代码:

cpp 复制代码
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;
    }
};

3.优势洗牌(田忌赛马)

此时我们有了这个概念,我们就来模拟一遍流程

直接上代码:

cpp 复制代码
class Solution {
public:
    vector<int> advantageCount(vector<int>& nums1, vector<int>& nums2) {
        vector<int> index(nums1.size());
        // 1.排序
        for(int i = 0; i < nums1.size(); i++)
            index[i] = i;
        sort(nums1.begin(), nums1.end());
        sort(index.begin(), index.end(), [&](int x, int y)
        {
            return nums2[x] < nums2[y];
        });

        // 田忌赛马
        int left = 0;
        int right = nums1.size() - 1;
        vector<int> ret(nums1.size());
        for(auto e : nums1)
        {
            // index[left] 代表最小值的下标
            // nums2[index[left]] 代表nums2中的最小值
            if(e > nums2[index[left]]) ret[index[left++]] = e;
            // index[right] 代表最大值的下标
            // ret[index[right]] 代表nums2中的最大值
            else ret[index[right--]] = e;
        }
        return ret;
    }
};

4.最长回文串

这个题目比较简单,根据回文串的特点,我们只需要统计字符出现的次数,再判断奇数和偶数的情况即可,直接上思路:

直接上代码:

cpp 复制代码
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;
	}
};

5. 增减字符串匹配

贪心策略算法思路:

  • a. 当遇到 "I" 的时候,为了让下⼀个上升的数可选择的「范围更多」,当前选择「最小」的那 个数;
  • b. 当遇到 "D" 的时候,为了让下⼀个下降的数可选择的「范围更多」,选择当前「最大」的那 个数。

直接上代码:

cpp 复制代码
class Solution
{
public:
	vector<int> diStringMatch(string s)
	{
		int left = 0, right = s.size(); // 用left,right标记最小值和最⼤值
		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;
	}
};
相关推荐
一个不知名程序员www5 小时前
算法学习入门 --- 哈希表和unordered_map、unordered_set(C++)
c++·算法
Sarvartha6 小时前
C++ STL 栈的便捷使用
c++·算法
夏鹏今天学习了吗7 小时前
【LeetCode热题100(92/100)】多数元素
算法·leetcode·职场和发展
飞Link7 小时前
深度解析 MSER 最大稳定极值区域算法
人工智能·opencv·算法·计算机视觉
bubiyoushang8887 小时前
基于CLEAN算法的杂波抑制Matlab仿真实现
数据结构·算法·matlab
2401_894828128 小时前
从原理到实战:随机森林算法全解析(附 Python 完整代码)
开发语言·python·算法·随机森林
Remember_9938 小时前
【LeetCode精选算法】前缀和专题二
算法·哈希算法·散列表
源代码•宸8 小时前
Leetcode—509. 斐波那契数【简单】
经验分享·算法·leetcode·面试·golang·记忆化搜索·动规
博大世界9 小时前
matlab结构体数组定义
数据结构·算法
Loo国昌9 小时前
【LangChain1.0】第九阶段:文档处理工程 (LlamaIndex)
人工智能·后端·python·算法·langchain