算法奇妙屋(四十四)-贪心算法学习之路11

文章目录

一. 力扣 1262. 可被三整除的最大和

1. 题目解析

2. 算法原理

主要思想是正难则反, 先求总和sum, 再根据情况讨论, 本题有贪心和动态规划两种解法, 这里只给出贪心

3. 代码

java 复制代码
class Solution {
    public int maxSumDivThree(int[] nums) {
        int sum = 0;
        for (int x : nums) {
            sum += x;
        }
        if (sum % 3 == 0) {
            return sum;
        } else if (sum % 3 == 1) {
            int min1 = 0x3f3f3f3f, min2 = 0x3f3f3f3f, min = 0x3f3f3f3f;
            for (int x : nums) {
                if (x % 3 == 1 && x < min) {
                    min = x;
                }
                if (x % 3 == 2) {
                    if (x <= min1) {
                        min2 = min1;
                        min1 = x;
                    } else if (min1 < x && x < min2) {
                        min2 = x;
                    }
                }
            }
            return Math.max(sum - min, sum - min1 - min2);
        }else {
            int min1 = 0x3f3f3f3f, min2 = 0x3f3f3f3f, min = 0x3f3f3f3f;
            for (int x : nums) {
                if (x % 3 == 2 && x < min) {
                    min = x;
                }
                if (x % 3 == 1) {
                    if (x <= min1) {
                        min2 = min1;
                        min1 = x;
                    } else if (min1 < x && x < min2) {
                        min2 = x;
                    }
                }
            }
            return Math.max(sum - min, sum - min1 - min2);
        }
    }
}

二. 力扣 1054. 距离相等的条形码

1. 题目解析

有多个相同元素的数组, 重新排列使其相邻元素不相同

2. 算法原理

这道题的算法原理很简单, 模拟一遍, 间隔填写

3. 代码

java 复制代码
class Solution {
    Map<Integer, Integer> hash;

    public int[] rearrangeBarcodes(int[] barcodes) {
        hash = new HashMap<>();
        int val = 0, count = 0;
        int n = barcodes.length;
        // 把元素与个数丢入哈希表, 同时找出最多的相同元素
        for (int x : barcodes) {
            hash.put(x, hash.getOrDefault(x, 0) + 1);
            if (count < hash.get(x)) {
                count = hash.get(x);
                val = x;
            }
        }
        int[] ret = new int[n];
        // 图中第一个位置对应的就是0号位置
        int index = 0;
        for (int i = 0; i < count; i++) {
            ret[index] = val;
            index += 2;
        }
        // 删除val
        hash.remove(val);
        // 添加其他元素, 遍历key, 再在内循环遍历出现的次数
        for (int x : hash.keySet()) {
            for (int i = 0; i < hash.get(x); i++) {
                // 当index大于数组长度时, 说明偶数位置(图中的奇数位置)已经遍历完, 这里将index从1开始, 因为元素个数和ret长度一致, 因此仅会修改一次
                if (index > n - 1) index = 1; 
                ret[index] = x;
                index += 2;
            }
        }
        return ret;
    }
}

三. 力扣 767. 重构字符串

1. 题目解析

和上道题很相似, 这里无非换成了字符, 同时要注意, 可能存在无法排列的情况

2. 算法原理

当单一字符的个数超过了(n + 1) / 2时, 无论怎么排序都无法满足题目要求

3. 代码

java 复制代码
class Solution {
    public String reorganizeString(String s) {
        char[] c = s.toCharArray();
        int n = c.length;
        // 因为这里全是小写字符, 用数组代替哈希表
        int[] hash = new int[26];
        char val = '0';
        int count = 0;
        for (char ch : c) {
            hash[ch - 'a']++;
            if (count < hash[ch - 'a']) {
                val = ch;
                count = hash[ch - 'a'];
            }
        }
        if (count > (n + 1) / 2) return "";
        char[] ret = new char[n];
        int index = 0;
        for (int i = 0; i < count; i++) {
            ret[index] = val;
            index += 2;
        }
        hash[val - 'a'] = 0;
        for (int i = 0; i < 26; i++) {
            for (int j = 0; j < hash[i]; j++) {
                if (index > n - 1) index = 1;
                ret[index] = (char)(i + 'a');
                index += 2;
            }
        }
        return new String(ret);
    }
}
相关推荐
重生之后端学习8 分钟前
239. 滑动窗口最大值[困难]✅
java·数据结构·算法·leetcode·职场和发展
JavaPub-rodert20 分钟前
具身智能行业技术全景:从感知、规划、控制到 VLA 与机器人学习
学习·机器人
脉动数据行情123 分钟前
Java SpringBoot 对接知名台股 TWSE|批量采集上市股票行情实践
java·开发语言·spring boot
她的男孩28 分钟前
我把管理系统接给AI,它改条数据都要先问我
java·后端·架构
toolsmith28 分钟前
我用AI拆解了Charles的授权机制,发现密钥被写死在了代码里
java·人工智能
fpcc33 分钟前
算法和数据结构—动态规划法
数据结构·算法·动态规划
IKUN家族1 小时前
SpringBoot日志
java·开发语言
DianSan_ERP1 小时前
WMS接入电商平台自动化履约实战:一张订单从平台到出库的接口时序设计
java·前端·网络·数据库·安全·架构·自动化
liangsheng_g2 小时前
微服务本地开发零配置隔离方案
java·微服务·架构
知识分享小能手2 小时前
概理论与数理统计学习教程,从入门到精通,在数理统计中应用R软件(22)
开发语言·学习·r语言