• 七月集训(4)贪心


    1.LeetCode:2078. 两栋颜色不同且距离最远的房子

    原题链接


            街上有 n 栋房子整齐地排成一列,每栋房子都粉刷上了漂亮的颜色。给你一个下标从 0 开始且长度为 n 的整数数组 colors ,其中 colors[i] 表示第 i 栋房子的颜色。

            返回 两栋 颜色 不同 房子之间的 最大 距离。

            第 i 栋房子和第 j 栋房子之间的距离是 abs(i - j) ,其中 abs(x) 是 x 的绝对值。

            示例 1:

            输入:colors = [1,1,1,6,1,1,1]

            输出:3

            示例 2:

            输入:colors = [1,8,3,8,3]

            输出:4

            示例 3:

            输入:colors = [0,1]

            输出:1

            提示:

            n == colors.length

            2 <= n <= 100

            0 <= colors[i] <= 100

            生成的测试数据满足 至少 存在 2 栋颜色不同的房子


            看数据量n只有100,那么就不需要什么复杂的算法了,直接枚举所有位置的房子,去数组中向右边找与他颜色不同的房子并且维护ans。(为什么不像前找是因为距离是相互的,如果该位置与之前的房子距离为答案,那么在之前就已经找过了,不用再判断了。)

    class Solution {
    public:
        int maxDistance(vector<int>& colors) {
            int ans=-0x3f3f3f3f;
            for(int i=0;i<colors.size();++i){
                for(int j=i+1;j<colors.size();++j){
                    if(colors[j]!=colors[i])
                    ans=max(ans,abs(j-i));
                }
            }
            return ans;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    2.LeetCode:561. 数组拆分 I

    原题链接


            给定长度为 2n 的整数数组 nums ,你的任务是将这些数分成 n 对, 例如 (a1, b1), (a2, b2), …, (an, bn) ,使得从 1 到 n 的 min(ai, bi) 总和最大。
    返回该 最大总和 。

            示例 1:

            输入:nums = [1,4,3,2]

            输出:4

            示例 2:

            输入:nums = [6,2,6,5,1,2]

            输出:9

            提示:

            1 <= n <= 1e4

            nums.length == 2 * n

            -1e4 <= nums[i] <= 1e4


            这个就是典型的贪心题目了,按照题目要求,数组中最小的元素一定会被加入到答案中,而最大的元素一定不会被加入,所以我们先把数组排序,那么我们会发现,每次加入数组的第一小和第二大并将这第一小第二小,第一大第二大(尽量删除最小和最大的那组)从数组中删去后,新加入的数就是剩余元素的第一小和第二大。

            这样我们就发现了我们每次加入到答案中的数字是数组中每两个数字的前一个,那么按照这个发现遍历数组即可。

    class Solution {
    public:
        int arrayPairSum(vector<int>& nums) {
            sort(nums.begin(),nums.end());
            int n=nums.size();
            int ans=0;
            for(int i=0;i<n;i+=2){
                ans+=nums[i];
            }
            return ans;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    3.LeetCode:1323. 6 和 9 组成的最大数字

    原题链接


            给你一个仅由数字 6 和 9 组成的正整数 num。

            你最多只能翻转一位数字,将 6 变成 9,或者把 9 变成 6 。

            请返回你可以得到的最大数字。

            示例 1:

            输入:num = 9669

            输出:9969 。

            示例 2:

            输入:num = 9996

            输出:9999

            示例 3:

            输入:num = 9999

            输出:9999

            提示:

            1 <= num <= 10^4

            num 每一位上的数字都是 6 或者 9 。


            没什么好说的,吧最高位的6变成9即可

    class Solution {
    public:
        int maximum69Number (int num) {
            vector<int> tmp;
            while(num){
                tmp.push_back(num%10);
                num/=10;
            }
            for(int i=tmp.size()-1;i>=0;--i){
                if(tmp[i]==6){
                    tmp[i]=9;
                    break;
                }
            }
            int ans=0;
            for(int i=tmp.size()-1;i>=0;--i ){
                ans=ans*10+tmp[i];
            }
            return ans;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    4.LeetCode:942. 增减字符串匹配

    原题链接


            由范围 [0,n] 内所有整数组成的 n + 1 个整数的排列序列可以表示为长度为 n 的字符串 s ,其中:

            如果 perm[i] < perm[i + 1] ,那么 s[i] == ‘I’

            如果 perm[i] > perm[i + 1] ,那么 s[i] == ‘D’

            给定一个字符串 s ,重构排列 perm 并返回它。如果有多个有效排列perm,则返回其中 任何一个 。

            示例 1:

            输入:s = “IDID”

            输出:[0,4,1,3,2]

            示例 2:

            输入:s = “III”

            输出:[0,1,2,3]

            示例 3:
            输入:s = “DDI”

            输出:[3,2,0,1]

            提示:

            1 <= s.length <= 1e5

            s 只包含字符 “I” 或 “D”


            先定义max=perm.size(),min=0,然后遍历字符串,如果是"I"就在答案中加入min++,如果是"D"就加入max–,最后判断字符串最后一位,如果是"I"就加入min否则加入max。

            这样做是因为如果是"I"的话我们尽量让当前位置的数最小即可,如果是"D"的话我们尽量让当前位置最大即可。但是这样数组最后只有n个数字。不过这个时候随便加入min或者max即可,因为min和max在构造的过程中是不断逼近的,最后一定是相等的。

            具体论证的话我们设字符串中有x个"I",y个"D"我们有如下条件:
    { x + y = n ( 1 ) m i n = x ( 2 ) m a x = n − y ( 3 )

    {x+y=n(1)min=x(2)max=ny(3)
    x+y=nmin=xmax=ny(1)(2)(3)

            由(1)可以得到x=n-y
            由(2)可知x=min
            由(1),(3)得x=max,由此可以得到最终得max和min是相等的加入哪一个都无所谓

    class Solution {
    public:
        vector<int> diStringMatch(string s) {
            vector<int> ans;
            int min=0,max=s.size();
            for(int i=0;i<s.size();++i){
                ans.push_back(s[i]=='I'?min++:max--);
            }
            ans.push_back(min);
            return ans;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
  • 相关阅读:
    Pytorch多GPU并行训练: DistributedDataParallel
    Unity Shader顶点数据疑问
    np中的normalize/histogram/cumsum/interp函数
    Makefile——Linux下C/C++编译方法
    【Error: error:0308010C:digital envelope routines::unsupported】
    【博客448】OVN (Open Virtual Network)
    Vue--keep-alive--使用/实例
    122. 买卖股票的最佳时机 II
    程序员健康防猝指南3:健康保健
    前端uniapp生成海报绘制canvas画布并且保存到相册【实战/带源码/最新】
  • 原文地址:https://blog.csdn.net/m0_67739923/article/details/125592488