算法奇妙屋(四十四)-贪心算法学习之路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);
    }
}
相关推荐
斯维赤7 分钟前
微信步数的10点定时推送,看似简单,实则暗藏玄机
java·后端
David猪大卫13 分钟前
【C++修炼】STL容器—stack与queue
c语言·开发语言·数据结构·c++·经验分享·笔记·学习
瑶池酒剑仙14 分钟前
C++变量初始化五法完全指南:默认/拷贝/直接/列表/值初始化与窄化转换陷阱(青云之志)
c语言·开发语言·数据结构·c++·算法·visual studio
Linux_cy14 分钟前
服务器管理方案选型:面板 / SSH 客户端 / 桌面型客户端怎么选
java·linux·运维·服务器·ssh·可视化·gmssh
用户2380030994517 分钟前
从零开始实现扫雷游戏(C 语言控制台版)
算法
fengci.38 分钟前
CTF2刷题记录(困难部分)
android·开发语言·前端·学习·php
可乐_不渴39 分钟前
【Linux】 进程虚拟地址空间
java·linux·javascript
SimonKing41 分钟前
号外号外,Stream-Nexus推送项目支持集群部署了
java·后端·程序员
国科安芯43 分钟前
星上计算的第一道防线:低轨遥感卫星载荷处理链中的AS32S601型抗辐射MCU—— 面向高分辨率成像与在轨智能处理的场景化综述
大数据·网络·人工智能·单片机·算法·低轨卫星·抗辐射
vipxieliang1 小时前
ValidX vs 正则表达式:可读性与维护性对比
java·spring boot