环形房屋如何 “安全劫舍”?动态规划解题逻辑与技巧

环形房屋如何 “安全劫舍”?动态规划解题逻辑与技巧

环形房屋如何 “安全劫舍”?动态规划解题逻辑与技巧

🌺The Begin🌺点点关注,收藏不迷路🌺

1、问题描述

你是一个专业的小偷,计划偷窃环形排列的房屋。每间房屋都有一定金额,但如果偷窃相邻的两间房屋就会触发警报。计算在不触发警报的情况下能够偷窃到的最高金额。

2、解题思路

这个问题是经典打家劫舍问题的变种,房屋排列成环形。我们可以将其分解为两个子问题:

  1. 不偷第一间房屋
  2. 不偷最后一间房屋
    然后取这两个子问题的最大值作为最终结果。

3、动态规划解法

3.1 辅助函数

首先实现一个标准的打家劫舍函数,处理线性排列的房屋:

introbLinear(int* nums,int start,int end){int prev =0, curr =0;for(int i = start; i < end; i++){int temp = curr; curr =(prev + nums[i]> curr)? prev + nums[i]: curr; prev = temp;}return curr;}

3.2 主函数

处理环形排列的情况:

introb(int* nums,int numsSize){if(numsSize ==0)return0;if(numsSize ==1)return nums[0];// 两种情况:不偷第一间或不偷最后一间int option1 =robLinear(nums,0, numsSize -1);int option2 =robLinear(nums,1, numsSize);return(option1 > option2)? option1 : option2;}

4、代码解析

  1. 边界条件处理
    • 空数组返回0
    • 只有一间房屋直接返回该房屋金额
  2. 分解问题
    • option1:不偷最后一间房屋(即考虑从第1间到倒数第2间)
    • option2:不偷第一间房屋(即考虑从第2间到最后1间)
  3. 动态规划核心
    • prevcurr分别记录前一步和当前的最大金额
    • 对于每间房屋,选择偷或不偷的最大值

5、复杂度分析

  • 时间复杂度:O(n),只需两次线性遍历
  • 空间复杂度:O(1),只使用常数空间

6、测试用例

intmain(){int nums1[]={2,3,2};printf("%d\n",rob(nums1,3));// 输出3int nums2[]={1,2,3,1};printf("%d\n",rob(nums2,4));// 输出4int nums3[]={1,2,3};printf("%d\n",rob(nums3,3));// 输出3return0;}

7、关键点总结

  1. 问题分解:将环形问题分解为两个线性问题
  2. 动态规划:使用标准打家劫舍的解法处理线性情况
  3. 空间优化:只用两个变量存储中间结果,无需完整DP数组
  4. 边界处理:正确处理空数组和单元素数组的情况

8、常见问题解答

Q: 为什么分解为两个子问题?
A: 因为第一间和最后一间不能同时偷,所以要么不偷第一间,要么不偷最后一间。

Q: 如何保证不偷相邻房屋?
A: 动态规划中总是比较偷当前房屋和不偷当前房屋的较大值。

Q: 这个方法能处理所有情况吗?
A: 是的,这种方法能正确处理所有可能的环形排列情况。

Q: 为什么空间复杂度是O(1)?
A: 因为我们只使用了固定数量的变量,没有使用与输入规模相关的额外空间。

面试提示:解释清楚如何将环形问题转化为线性问题,并说明动态规划的状态转移过程,这能展示你对问题的深入理解。
在这里插入图片描述

🌺The End🌺点点关注,收藏不迷路🌺

Read more

C++ 多线程同步之互斥锁(mutex)实战

C++ 多线程同步之互斥锁(mutex)实战

C++ 多线程同步之互斥锁(mutex)实战 💡 学习目标:掌握 C++ 标准库中互斥锁的基本用法,理解多线程同步的核心原理,能够解决多线程环境下的资源竞争问题。 💡 学习重点:std::mutex 与 std::lock_guard 的使用、死锁的产生原因及规避方法、实际场景中的同步案例实现。 48.1 多线程同步的必要性 在多线程编程中,当多个线程同时访问共享资源时,会出现资源竞争问题。 例如两个线程同时对同一个变量进行读写操作,会导致最终结果与预期不符。 这种问题被称为线程安全问题,而解决该问题的核心就是线程同步。 ⚠️ 注意事项:线程不同步会引发数据竞争,造成程序运行结果不可预测,甚至导致程序崩溃。 举个简单的反例,两个线程同时对全局变量 count 进行自增操作: #include<iostream>#include<thread>usingnamespace std;int count

By Ne0inhk
手把手实现 STL Set/Map:从零编写一棵红黑树到完整容器封装

手把手实现 STL Set/Map:从零编写一棵红黑树到完整容器封装

🔥草莓熊Lotso:个人主页 ❄️个人专栏: 《C++知识分享》《Linux 入门到实践:零基础也能懂》 ✨生活是默默的坚持,毅力是永久的享受! 🎬 博主简介: 文章目录 * 前言: * 一. 架构与实现:总览设计框架,深入源码细节 * 二. 核心设计思路:红黑树的泛型复用 * 2.1 红黑树的模板参数设计 * 2.2 仿函数 KeyOfT:统一 key 提取逻辑 * 2.3 核心约束:key 不可修改 * 三. 基础组件实现:红黑树与仿函数 * 3.1 红黑树节点结构 * 3.2 仿函数实现(map/set 层) * 3.2.1

By Ne0inhk
SkyWalking - .NET / C++ / Lua 探针现状与社区支持

SkyWalking - .NET / C++ / Lua 探针现状与社区支持

👋 大家好,欢迎来到我的技术博客! 📚 在这里,我会分享学习笔记、实战经验与技术思考,力求用简单的方式讲清楚复杂的问题。 🎯 本文将围绕SkyWalking这个话题展开,希望能为你带来一些启发或实用的参考。 🌱 无论你是刚入门的新手,还是正在进阶的开发者,希望你都能有所收获! 文章目录 * SkyWalking - .NET / C++ / Lua 探针现状与社区支持 🌐 * 一、SkyWalking 多语言探针架构概览 🧩 * 二、Java 探针:成熟稳定,功能最全 ☕️ * 示例:Spring Boot 应用接入 SkyWalking * Java 探针高级特性 * 三、.NET 探针现状:渐趋成熟,生产可用 🖥️ * 技术原理 * 使用方式 * 当前支持的功能 * 局限性 * 四、C++ 探针现状:SDK 形式,适合嵌入式场景 ⚙️ * cpp2sky SDK

By Ne0inhk
【C++】哈希扩展——位图和布隆过滤器的介绍与实现

【C++】哈希扩展——位图和布隆过滤器的介绍与实现

各位读者大佬好,我是落羽!一个坚持不断学习进步的学生。 如果您觉得我的文章还不错,欢迎多多互三分享交流,一起学习进步! 也欢迎关注我的blog主页:落羽的落羽 文章目录 * 一、位图 * 1. 概念与实现 * 2. std::bitset * 二、布隆过滤器 * 1. 概念 * 2. 布隆过滤器误判率数学推导 * 3. 实现 一、位图 1. 概念与实现 在许多公司的面试题中会考到这样的场景:给40亿个不重复无符号整数,如何快速判断一个数是否在这40亿数中。 如果使用常规思路,每次查询暴力遍历O(N)太慢,排序+二分查找O(NlogN)+O(logN),内存不足以放下这些数据。 数据是否在给定的整型数据中,结果是在或不在,正好是两种状态,那么可以用一个二进制比特位来代表数据是否存在的信息,比特位为1代表存在,比特位为0代表不在。那么,我们可以设计一个用比特位表示数据是否存在的数据结构——位图!

By Ne0inhk