返回
高手窃金无须碰:高超Go&Java算法之打家劫舍
后端
2024-02-02 05:50:50
Go语言实现
func rob(nums []int) int {
if len(nums) == 0 {
return 0
}
dp := make([]int, len(nums))
dp[0] = nums[0]
dp[1] = max(nums[0], nums[1])
for i := 2; i < len(nums); i++ {
dp[i] = max(dp[i-1], dp[i-2]+nums[i])
}
return dp[len(nums)-1]
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
Java语言实现
public class HouseRobber {
public int rob(int[] nums) {
if (nums.length == 0) {
return 0;
}
int[] dp = new int[nums.length];
dp[0] = nums[0];
dp[1] = Math.max(nums[0], nums[1]);
for (int i = 2; i < nums.length; i++) {
dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i]);
}
return dp[nums.length - 1];
}
public static void main(String[] args) {
HouseRobber hr = new HouseRobber();
int[] nums = {1, 2, 3, 1};
System.out.println(hr.rob(nums)); // 4
}
}
算法原理
打家劫舍算法的核心思想是动态规划。动态规划是一种用于解决最优子结构和无后效性问题的算法。在打家劫舍问题中,子结构是指一个子问题的最优解,而无后效性是指子问题的最优解不依赖于其后面的子问题的解。
在打家劫舍问题中,我们可以定义一个状态dp[i],表示抢劫到第i间房子时,偷到的最大金额。我们可以利用以下递推关系来计算dp[i]:
- dp[0] = nums[0]
- dp[1] = max(nums[0], nums[1])
- dp[i] = max(dp[i-1], dp[i-2] + nums[i])
复杂度分析
打家劫舍算法的时间复杂度为O(n),其中n是房子的数量。空间复杂度为O(n),因为我们需要存储每个子问题的最优解。
总结
打家劫舍算法是一个经典的动态规划问题。它可以用来解决许多其他问题,例如最大子数组和、最长公共子序列等。希望本文对您理解打家劫舍算法有所帮助。