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

文章目录

一. 力扣 397. 整数替换

1. 题目解析

要注意 n 的取值范围很大, 为int类型的极限

2. 算法原理

记忆化搜索解法👇

贪心解法👇

3. 代码

java 复制代码
解法一代码👇
class Solution {
    Map<Long, Integer> hash = new HashMap<>();
    public int integerReplacement(int n) {
        hash.put(1L, 0);
        return dfs(n * 1L);
    }
    int dfs(long n) {
        if (hash.containsKey(n)) {
            return hash.get(n);
        }
        if (n % 2 == 0) {
            int ret = dfs(n / 2) + 1;
            hash.put(n, ret);
            return ret;
        }else {
            int ret = Math.min(dfs(n + 1), dfs(n - 1)) + 1;
            hash.put(n, ret);
            return ret;
        }
    }
}
java 复制代码
解法二代码👇
class Solution {
    public int integerReplacement(int n) {
        int ret = 0;
        while (n > 1) {
            if (n % 2 == 0) {
                n /= 2;
                ret++;
            } else {
                if (n == 3) {
                    n = 1;
                    ret += 2;
                } else if (n % 4 == 1) {
                    n /= 2; // 在计算机中, 奇数-1后再/2的操作, 与直接/2的结果一样
                    ret += 2;
                } else {
                    n = n / 2 + 1; // 在计算机中, 奇数+1后再/2的操作, 与/2后再+1的结果一样, 这里主要是为了防止n+1溢出
                    ret += 2;
                }
            }
        }
        return ret;
    }
}

二. 力扣 354. 俄罗斯套娃信封问题

1. 题目解析

题意很好理解, 但是里面用到的算法思想有三个, 相当于区间题目+最长递增子序列的题目版本

2. 算法原理

动态规划(超时), 这个算法虽然超时, 但是可以从中发现规律

排序 + 贪心 + 二分:
我们换一种排序方式, 就可以发现新大陆


3. 代码

java 复制代码
class Solution {
    public int maxEnvelopes(int[][] envelopes) {
        Arrays.sort(envelopes, (a, b) -> {
            if (a[0] != b[0]) {
                return a[0] - b[0];
            } else {
                return b[1] - a[1];
            }
        });
        int n = envelopes.length;
        List<Integer> ret = new ArrayList<>();
        ret.add(envelopes[0][1]);
        for (int i = 1; i < n; i++) {
            int x = envelopes[i][1];
            int right = ret.size() - 1;
            if (x > ret.get(right)) {
                ret.add(x);
            } else {
                int left = 0;
                while (left < right) {
                    int mid = left + (right - left) / 2;
                    if (ret.get(mid) < x) {
                        left = mid + 1;
                    } else {
                        right = mid;
                    }
                }
                ret.set(left, x);
            }
        }
        return ret.size();
    }
}
相关推荐
楚山之石8 小时前
【Nat Biomed Eng】Connectome 2.0 超高梯度扫描仪:500 mT/m 与 600 T/m/s 把活体人脑微观结构分辨推进到亚微米级
图像处理·学习·数据分析·mri
坤坤子吖10 小时前
Linux网络编程:TCP 粘包与半包问题,如何正确处理 TCP 流式数据?
linux·服务器·网络·笔记·网络协议·学习
Code_Solitude12 小时前
C语言动态内存 + 柔性数组 + 数组名退化
c语言·算法·柔性数组
上海潭龙东海科技有限公司12 小时前
客运站管控之动态孪生技术方案(新增一屏管控模块
数据仓库·人工智能·算法·重构·动态规划
YLCHUP14 小时前
【思维&图论建模】题解:债权(debt)_图论_建模_思路转化_思维题目_C++算法竞赛
c++·笔记·算法·数学建模·贪心算法·深度优先·图论
LGL6030A14 小时前
Java学习历程31——初识Spring Boot
java·spring boot·学习
思麟呀15 小时前
背包DP(01背包+完全背包)
c++·算法
阿达和自己16 小时前
springboot学习-springboot引入MyBatis-Plus
spring boot·学习·mybatis
笑容掩饰我的失落16 小时前
区块链从小白到精通(七):Solidity 语法精讲——数据类型、函数、修饰器与事件
算法·区块链·php·智能合约·哈希算法