算法奇妙屋(四十四)-贪心算法学习之路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);
    }
}
相关推荐
子琦啊2 小时前
【算法复习】数组与双指针篇
javascript·算法
ambition202422 小时前
斐波那契取模问题的深入分析:为什么提前取模是关键的
c语言·数据结构·c++·算法·图论
艾莉丝努力练剑2 小时前
C++ 核心编程练习:从基础语法到递归、重载与宏定义
linux·运维·服务器·c语言·c++·学习
鱼鳞_2 小时前
Java学习笔记_Day24(HashMAap)
java·笔记·学习
Flittly2 小时前
【SpringAIAlibaba新手村系列】(14)MCP 本地服务与工具集成
java·spring boot·笔记·spring·ai
ZhiqianXia2 小时前
PyTorch 笔记学习(15) : aot_autograd.py 解析
pytorch·笔记·学习
范什么特西2 小时前
web练习
java·前端·javascript
逆境不可逃2 小时前
LeetCode 热题 100 之 230. 二叉搜索树中第 K 小的元素 199. 二叉树的右视图 114. 二叉树展开为链表
算法·leetcode·职场和发展
阿捞22 小时前
JVM排查工具单
java·jvm·python