198. 打家劫舍
题目来源:https://leetcode-cn.com/problems/house-robber/
剑指 Offer 46. 把数字翻译成字符串 LCOF
题目来源:https://leetcode-cn.com/problems/ba-shu-zi-fan-yi-cheng-zi-fu-chuan-lcof/
两题的做法和思路一致故放在一起
198. 打家劫舍
题目描述
你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。
给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。
示例 1:
输入:[1,2,3,1]
输出:4
解释:偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。
偷窃到的最高金额 = 1 + 3 = 4 。
示例 2:
输入:[2,7,9,3,1]
输出:12
解释:偷窃 1 号房屋 (金额 = 2), 偷窃 3 号房屋 (金额 = 9),接着偷窃 5 号房屋 (金额 = 1)。
偷窃到的最高金额 = 2 + 9 + 1 = 12 。
提示:
0 <= nums.length <= 100
0 <= nums[i] <= 400
题目大意
- 偷取序号为n的房屋之前,他可以从f(n-2)状态+偷当前房屋的钱财,也可以是f(n-1)的状态不偷当前房屋钱财,两者取大,就是当前序号为n之前所有偷窃手段,所能获得最大钱财
动态规划
class Solution {
public:
int rob(vector<int>& nums) {
int len = nums.size();
if (len == 0) return 0;
else if (len == 1) return nums[0];
vector<int> dp(len + 1, 0);
dp[0] = nums[0];
dp[1] = max(nums[0], nums[1]);
for (int i = 2 ; i < len ; ++i){
dp[i] = max(dp[i - 1], dp[i - 2] + nums[i]);
}
return dp[len - 1];
}
};
复杂度分析
- 时间复杂度:O(n)。n为数组的长度
- 空间复杂度:O(n)。n为数组的长度。(此处可用滚动数组优化为O(1))
剑指 Offer 46. 把数字翻译成字符串 LCOF
题目描述
给定一个数字,我们按照如下规则把它翻译为字符串:0 翻译成 “a” ,1 翻译成 “b”,……,11 翻译成 “l”,……,25 翻译成 “z”。一个数字可能有多个翻译。请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法。
动态规划
- dp[n]含义为以xn为结尾的字符串又几种转换形式,一开始先初始化前两个都是1种转换方式
- 更新dp数组从下标为2更新,本质上是str下标为1开始更新,故前一个就是str[i-2]
class Solution {
public:
int translateNum(int num) {
string str = to_string(num);
int len = str.size();
vector<int> dp(len + 1, 0);
dp[0] = 1; dp[1] = 1;
for (int i = 2 ; i <= len ; ++i){
int front = str[i - 2] - '0';
int back = str[i - 1] - '0';
if (front != 0 && front * 10 + back <= 25){
dp[i] = dp[i - 1] + dp[i - 2];
}else{
dp[i] = dp[i - 1];
}
}
return dp[len];
}
};
复杂度分析
- 时间复杂度:O(n)。n为数组的长度
- 空间复杂度:O(n)。n为数组的长度。(此处可用滚动数组优化为O(1))