算法奇妙屋(四十四)-贪心算法学习之路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);
    }
}
相关推荐
周末也要写八哥1 分钟前
C++变参模板之空参包的特殊情况
java·开发语言·c++
sakiko_3 分钟前
Swift学习笔记29-数据库SQlite
数据库·学习·sqlite·swift
知识分享小能手4 分钟前
Flask入门学习教程,从入门到精通, 认识Flask —— 知识点详解 (1)
python·学习·flask
书语时5 分钟前
看了 Comparator 源码,我重写了所有业务排序逻辑
java
温九味闻醉6 分钟前
关于腾讯广告算法大赛2025项目面试要点
人工智能·算法·机器学习
xwz小王子10 分钟前
SkiP:让模仿学习学会“快进“——动作重标记如何在不改架构的情况下削减机器人 15-40% 的执行步数
学习·架构·机器人
likerhood12 分钟前
Java final 关键字:从“不能改”到“安全发布”的深入理解
java·windows·安全
sheeta199813 分钟前
LeetCode 每日一题笔记 日期:2026.05.15 题目:153. 寻找旋转排序数组中的最小值
笔记·算法·leetcode
GEO从入门到精通14 分钟前
GEO学习与传统SEO学习有什么区别?
人工智能·学习·microsoft