
2026-06-12:打家劫舍 V。用go语言,你现在要处理一个“相邻房屋不能同色同时偷”的求最大收益问题:
1 <= n == nums.length == colors.length <= 100000。
1 <= nums[i], colors[i] <= 100000。
输入: nums = [10,1,3,9], colors = [1,1,1,2]。
输出: 22。
解释:
选择第 i = 0 间房屋(金额为 10)、第 i = 2 间房屋(金额为 3)和第 i = 3 间房屋(金额为 9)。
此选择是合法的,因为第 i = 0 和 i = 2 间房屋不相邻,且第 i = 2 和 i = 3 间房屋颜色不同。
因此,偷窃的总金额为 10 + 3 + 9 = 22。
题目来自力扣3840。
房屋0:金额10,颜色1
对比相邻颜色:colors[1]=1,colors[0]=1,相邻同色,触发同色分支逻辑。 规则:i和i-1同色,不能同时偷i和i-1,因此偷当前i的方案只能来自「不偷i-1的收益f1 + 当前房屋金额」,再和「不偷当前i,保留偷i-1的收益f2」取更大值作为money。
对比相邻颜色:colors[2]=1,colors[1]=1,相邻同色,再次进入同色分支。
对比相邻颜色:colors[3]=2,colors[2]=1,相邻异色,进入异色分支逻辑。 规则:i和i-1颜色不同,无偷窃冲突,可以同时偷i-1和i,因此偷当前i的收益 = 偷i-1的最大收益f2 + 当前房屋金额,直接赋值给money。
循环遍历完所有4间房屋,最终f2存储遍历到最后一间房屋、偷最后一间时的全局最大收益,返回22,和题目输出一致。
如果房屋总数n=0,不存在可偷窃房屋,直接返回总收益0。
每一次循环执行固定三步:
分支A:colors[i] != colors[i-1](相邻异色) 相邻异色无偷窃冲突,可以同时偷前一间和当前间。 当前房屋偷窃最优收益money = 偷前一间的最大收益f2 + 当前房屋金额nums[i]
分支B:colors[i] == colors[i-1](相邻同色) 相邻同色不能两间都偷,有两种选择:
完成money计算后,刷新两个状态变量,为下一间房屋遍历做准备:
循环结束后,f2保存的是遍历到最后一间房屋、包含偷最后一间方案的全局最大总金额,直接返回f2作为答案。
n为房屋总数,算法仅执行一次单层for循环,循环执行次数恰好n-1次; 循环内部仅包含颜色比较、简单四则运算、大小比较,所有操作都是常数时间O(1); 无嵌套循环、无排序、无递归,整体时间复杂度线性O(n),可以满足题目n≤100000的数据规模。
输入的nums、colors属于题目给定输入数组,不计入算法额外空间; 算法内部仅永久开辟3个固定变量:f1、f2、money,变量数量不随房屋数量n变化; 没有创建DP数组、切片、哈希表等随n扩容的数据结构; 仅使用常数级临时存储空间,额外空间复杂度为O(1)。
.
package main
import (
"fmt"
)
func rob(nums []int, colors []int)int64 {
iflen(nums) == 0 {
return0
}
f1 := int64(0)
f2 := int64(nums[0])
n := len(nums)
for i := 1; i < n; i++ {
var money int64
if colors[i] != colors[i-1] {
money = f2 + int64(nums[i])
} else {
if f1+int64(nums[i]) > f2 {
money = f1 + int64(nums[i])
} else {
money = f2
}
}
f1 = f2
f2 = money
}
return f2
}
func main() {
nums := []int{10, 1, 3, 9}
colors := []int{1, 1, 1, 2}
result := rob(nums, colors)
fmt.Println(result)
}

.
# -*-coding:utf-8-*-
from typing import List
class Solution:
def rob(self, nums: List[int], colors: List[int]) -> int:
iflen(nums) == 0:
return0
f1 = 0
f2 = nums[0]
n = len(nums)
for i in range(1, n):
if colors[i] != colors[i-1]:
money = f2 + nums[i]
else:
money = max(f1 + nums[i], f2)
f1 = f2
f2 = money
return f2
if __name__ == "__main__":
nums = [10, 1, 3, 9]
colors = [1, 1, 1, 2]
result = Solution().rob(nums, colors)
print(result)
.
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
long long rob(vector<int>& nums, vector<int>& colors) {
if (nums.empty()) {
return0;
}
long long f1 = 0;
long long f2 = nums[0];
int n = nums.size();
for (int i = 1; i < n; i++) {
long long money;
if (colors[i] != colors[i-1]) {
money = f2 + nums[i];
} else {
money = max(f1 + nums[i], f2);
}
f1 = f2;
f2 = money;
}
return f2;
}
int main() {
vector<int> nums = {10, 1, 3, 9};
vector<int> colors = {1, 1, 1, 2};
long long result = rob(nums, colors);
cout << result << endl;
return0;
}

·
我们相信人工智能为普通人提供了一种“增强工具”,并致力于分享全方位的AI知识。在这里,您可以找到最新的AI科普文章、工具评测、提升效率的秘籍以及行业洞察。