LeetCode 198. House Robber

xiaoxiao2021-02-28  55

问题描述

地址

问题分析

这道题不难,本质相当于在一列数组中取出一个或多个不相邻数,使其和最大。最优化问题。很明显用动态规划求解。但是有一点比较有意思,如果对状态定义的不同,算法时间复杂度不同如果 dp[i] 表示 [i ~ n-1] 中的最大和,那么状态转移条件为 dp[i] = Math.max(nums[j] + nums[j + 2]) 其中i <= j < n - 1,因为需要枚举j,是一个O(N^2)的时间复杂度。如果 dp[i] 表示 [0 ~ i] 中的最大和,那么状态转移条件为 dp[i] = Math.max(dp[i - 1], nums[i] + dp[i - 2]),这是一个 O(N) 的时间复杂度,并且如果对空间优化,是一个 O(1) 的空间复杂度

经验教训

动态规划中状态定义的意义不同,有可能会造成算法复杂度的不同

代码实现

状态定义1 public int rob(int[] nums) { if (nums == null || nums.length == 0) { return 0; } int[] dp = new int[nums.length]; dp[nums.length - 1] = nums[nums.length - 1]; for (int i = nums.length - 2; i >= 0; --i) { int max = 0; for (int j = i; j < nums.length; ++j) { max = Math.max(max, nums[j] + (j + 2 < nums.length ? dp[j + 2] : 0)); } dp[i] = max; } return dp[0]; } 状态定义2 public int rob(int[] nums) { if (nums == null || nums.length == 0) { return 0; } if (nums.length == 1) { return nums[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], nums[i] + dp[i - 2]); } return dp[nums.length - 1]; } 状态定义2空间优化 public int rob(int[] nums) { if (nums == null || nums.length == 0) { return 0; } if (nums.length == 1) { return nums[0]; } int pre = nums[0]; int cur = Math.max(nums[0], nums[1]); for (int i = 2; i < nums.length; ++i) { int temp = cur; cur = Math.max(cur, nums[i] + pre); pre = temp; } return cur; }
转载请注明原文地址: https://www.6miu.com/read-2619674.html

最新回复(0)