思路:状态的定义很重要。
状态定义1: dp[i]表示 到第 i 个房子的最大金额
class Solution { /** * dp[n]表示 到第n个房子的最大金额 * 1.如果偷第n个房子,由于不能相邻,dp[n]= dp[n-2] + nums[n] * 2.如果不偷第n个房子,那么dp[n] = dp[n-1] (即等于到第n-1个房子的最大金额) */ public int rob(int[] nums) { int n = nums.length; if (n == 0) return 0; if (n == 1) return nums[0]; int[] dp = new int[n]; dp[0] = nums[0]; // 只有一间房子,直接偷 dp[1] = Math.max(nums[0], nums[1]); // 只有两间房子,偷金额高的那个 for (int i = 2; i < n; i++) { dp[i] = Math.max(nums[i] + dp[i-2], dp[i-1]); } return dp[n-1]; /** * 优化空间复杂度为 O(1)。 由于 i 只依赖 i-1 和 i-2 两个状态 */ /* int a = nums[0]; // a 表示 i-2 int b = Math.max(nums[0], nums[1]); // b 表示 i-1 for (int i = 2; i < n; i++) { int temp = Math.max(nums[i] + a, b); a = b; b = temp; } return b; */ } }
状态定义2: dp[i] 表示 从前 i 个房子能偷到的最大金额
class Solution { public int rob(int[] nums) { int n = nums.length; if (n == 0) return 0; if (n == 1) return nums[0]; // dp[i] 表示 从前 i 个房子能偷到的最大金额 int[] dp = new int[n + 1]; dp[0] = 0; dp[1] = nums[0]; for (int i = 2; i <= n; i++) { dp[i] = Math.max(nums[i-1] + dp[i-2], dp[i-1]); } return dp[n]; } }