算法练习Day48|198.打家劫舍 ● 213.打家劫舍II ● 337.打家劫舍III

news/2024/7/24 7:16:00 标签: 算法, leetcode, 数据结构

leetcode">LeetCode:

198. 打家劫舍 - 力扣(LeetCode)

1.思路

边界思维,只有一个元素和两个元素的初始化考虑
当元素数大于3个时,
逆向思维,是否偷最后一个元素,倒序得出递推公式dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i]);前者不偷,后者偷,两者取较大值。

2.代码实现

 1// 递推公式逆向思考可以得出
 2class Solution {
 3    public int rob(int[] nums) {
 4        int len = nums.length;
 5        if (len == 0) {
 6            return 0;
 7        } else if (len == 1) {
 8            return nums[0];
 9        }
10
11        int[] dp = new int[len];
12        dp[0] = nums[0];
13        dp[1] = Math.max(dp[0], nums[1]);
14
15        for (int i = 2; i < len; i++) {
16            dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i]);
17        }
18        return dp[len - 1];
19    }
20}
21// 滚动数组,有些小坑得踩一下
22class Solution {
23    public int rob(int[] nums) {
24        int len = nums.length;
25
26        if (len == 0) {
27            return 0;
28        } else if (len == 1) {
29            return nums[0];
30        } else if (len == 2) {
31            return Math.max(nums[0], nums[1]);
32        }
33
34        int[] result = new int[3];
35        result[0] = nums[0];
36        result[1] = Math.max(nums[0], nums[1]);
37
38        for (int i = 2; i < len; i++) {
39            result[2] = Math.max(result[0] + nums[i], result[1]);
40
41            result[0] = result[1];
42            result[1] = result[2];
43        }
44        return result[2];
45    }
46}

3.复杂度分析

时间复杂度:O(n).
空间复杂度:O(1).

leetcode-1">LeetCode:

213. 打家劫舍 II - 力扣(LeetCode)

1.思路

考虑首元素和不考虑首元素,即可将环形进行拆解为两个线性数组,取两者之间的较大值即可

2.代码实现

 1class Solution {
 2    public int rob(int[] nums) {
 3        if (nums == null || nums.length == 0) {
 4            return 0;
 5        }
 6
 7        int len = nums.length;
 8        if (len == 1) {
 9            return nums[0];
10        }
11        return Math.max(robAction(nums, 0, len - 1), robAction(nums, 1, len));
12    }
13
14    int robAction(int[] nums, int start, int end) {
15        int x = 0, y = 0, z = 0;
16        for (int i = start; i < end; i++) {
17            y = z;
18            z = Math.max(y, x + nums[i]); //
19            x = y;
20        }
21        return z;
22    }
23}

3.复杂度分析

时间复杂度:O(n).
空间复杂度:O(1).

leetcode-2">LeetCode:

337. 打家劫舍 III - 力扣(LeetCode)

1.思路

分两种情况,选择根节点和不选根节点,分别计算两种情况的较大值,并选择两者之间的较大值存入map集合中,返回结果。

2.代码实现

 1/**
 2 * Definition for a binary tree node.
 3 * public class TreeNode {
 4 *     int val;
 5 *     TreeNode left;
 6 *     TreeNode right;
 7 *     TreeNode() {}
 8 *     TreeNode(int val) { this.val = val; }
 9 *     TreeNode(int val, TreeNode left, TreeNode right) {
10 *         this.val = val;
11 *         this.left = left;
12 *         this.right = right;
13 *     }
14 * }
15 */
16class Solution {
17    public int rob(TreeNode root) {
18        // 创建一个 Map 来保存已经计算过的节点的最大金额
19        Map<TreeNode, Integer> map = new HashMap<>(); 
20        // 调用递归方法计算能够偷取的最大金额
21        return robAction(root, map);
22    }
23    // 构建递归方法,计算以 root 为根节点的子树能够偷取的最大金额
24    int robAction(TreeNode root, Map<TreeNode, Integer> map) {
25        // 如果 root 为空,返回 0
26        if (root == null) {
27            return 0;
28        } 
29        // 如果map中已经存在以 root 为根节点的子树的最大金额,直接返回该值
30        if (map.containsKey(root)) {
31            return map.get(root);
32        }
33        // money 来保存以 root 为根节点的子树能够偷取的最大金额
34        int money = root.val;
35        // 左:判断 root 的左子节点是否存在,存在则计算左子节点的左子节点和右子节点的最大金额并加到 money 中
36        if (root.left != null) {
37            money += robAction(root.left.left, map) + robAction(root.left.right, map);
38        }
39        // 右:同理
40        if (root.right != null) {
41            money += robAction(root.right.left, map) + robAction(root.right.right, map);
42        }
43        // 结果从选择根节点和不选择根节点之中选取最大值
44        int res = Math.max(money, robAction(root.left, map) + robAction(root.right, map));
45        // 将结果res 存入map中,以便下次使用
46        map.put(root, res);
47        return res;
48    }
49}

3.复杂度分析

时间复杂度:O(n).
空间复杂度:O(logn).


http://www.niftyadmin.cn/n/4950411.html

相关文章

Linux硬链接和软连接

1、硬链接 硬连接指通过索引节点来进行连接。在 Linux 的文件系统中&#xff0c;保存在磁盘分区中的文件不管是什么类型都给它分配一个编号&#xff0c;称为索引节点号(Inode Index)。在 Linux 中&#xff0c;多个文件名指向同一索引节点是存在的。比如&#xff1a;A 是 B 的硬…

动漫3D虚拟人物制作为企业数字化转型提供强大动力

一个 3D 虚拟数字人角色的制作流程&#xff0c;可以分为概念设定-3D 建模-贴图-蒙皮-动画-引擎测试六个步骤&#xff0c;涉及到的岗位有原画师、模型师、动画师等。角色概念设定、贴图绘制一般是由视觉设计师来完成;而建模、装配(骨骼绑定)、渲染动画是由三维设计师来制作完成。…

【Rust日报】2023-08-17 Pixi - 使用 Rust 编写的全新软件包管理器

PsiACE Pixi - 使用 Rust 编写的全新软件包管理器 pixi 是由 Prefix.dev 团队开发的一个跨平台、多语言的软件包管理器和工作流工具&#xff0c;在 conda 生态系统的基础上构建。 pixi 为所有开发人员提供了与 cargo 或 yarn 等软件包管理器相似的卓越体验&#xff0c;但适用于…

centos下使用jemalloc解决Mysql内存泄漏问题

参考&#xff1a; MySQL bug&#xff1a;https://bugs.mysql.com/bug.php?id83047&tdsourcetags_pcqq_aiomsg https://github.com/jemalloc/jemalloc/blob/dev/INSTALL.md &#xff08;1&#xff09;ptmalloc 是glibc的内存分配管理 &#xff08;2&#xff09;tcmalloc…

echarts 关于折线统计图常用的属性设置--超详细(附加源码)

文章目录 折线统计图设置x轴字体大小及字体颜色设置y轴字体大小及字体颜色设置背景颜色及设置折线颜色设置折线效果图显示阴影折线图位置及标签位置设置鼠标悬浮折线弹出窗口显示对应的数据设置自动横向滚动 总结 大家好&#xff01;近期我会分享几篇关于echarts方面的技术点&a…

python3 0基础学习----数据结构(基础+练习)

python 0基础学习笔记之数据结构 &#x1f4da; 几种常见数据结构列表 &#xff08;List&#xff09;1. 定义2. 实例&#xff1a;3. 列表中常用方法.append(要添加内容) 向列表末尾添加数据.extend(列表) 将可迭代对象逐个添加到列表中.insert(索引&#xff0c;插入内容) 向指定…

设计模式之适配器模式(Adapter)的C++实现

1、适配器模式的提出 在软件功能开发中&#xff0c;由于使用环境的改变&#xff0c;之前一些类的旧接口放在新环境的功能模块中不再适用。如何使旧接口能适用于新的环境&#xff1f;适配器可以解决此类问题。适配器模式&#xff1a;通过增加一个适配器类&#xff0c;在适配器接…

NVIDIA vGPU License许可服务器高可用全套部署秘籍

第1章 前言 近期遇到比较多的场景使用vGPU&#xff0c;比如Citrix 3D场景、Horizon 3D场景&#xff0c;还有AI等&#xff0c;都需要使用显卡设计研发等&#xff0c;此时许可服务器尤为重要&#xff0c;许可断掉会出现掉帧等情况&#xff0c;我们此次教大家部署HA许可服务器。 …