leetcode-pp / 91alg-5-daily-check

91 天学算法第五期打卡
55 stars 14 forks source link

【Day 55 】2021-11-03 - 198. 打家劫舍 #74

Open azl397985856 opened 3 years ago

azl397985856 commented 3 years ago

198. 打家劫舍

入选理由

暂无

题目地址

https://leetcode-cn.com/problems/house-robber/

前置知识

暂无

题目描述

你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。

给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。

 

示例 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
cecilialmw commented 3 years ago
class Solution {
    public int rob(int[] nums) {
        if (nums == null | nums.length == 0) {
            return 0;
        }

        if (nums.length == 1) {
            return nums[0];
        }

        int prev = nums[0];
        int cur = Math.max(prev, nums[1]);

        for (int i = 2; i < nums.length; i++) {
            // stole the current house or not
            cur = Math.max(prev + nums[i], cur);
            prev = cur;
        }

        return cur;
    }
}

Complexity

time: O(n)

space: O(1)

L-SUI commented 3 years ago

var rob = function(nums) { const len = nums.length; if(len == 0) return 0; const dp = new Array(len + 1); dp[0] = 0; dp[1] = nums[0]; for(let i = 2; i <= len; i++) { dp[i] = Math.max(dp[i-1], dp[i-2] + nums[i-1]); } return dp[len]; };

yj9676 commented 3 years ago
class Solution {
    public int rob(int[] nums) {
        if (nums == null || nums.length == 0) {
            return 0;
        }
        int length = nums.length;
        if (length == 1) {
            return nums[0];
        }
        int[] dp = new int[length];
        dp[0] = nums[0];
        dp[1] = Math.max(nums[0], nums[1]);
        for (int i = 2; i < length; i++) {
            dp[i] = Math.max(dp[i - 2] + nums[i], dp[i - 1]);
        }
        return dp[length - 1];
    }
}
fzzfgbw commented 3 years ago

思路

dp

代码

 public int rob(int[] nums) {
        int n = nums.length+1;
         int[] dp = new int[n];
        dp[1] = nums[0];
        for(int i = 2;i<n;i++){
            dp[i] = Math.max(dp[i-1],dp[i-2]+nums[i-1]);
        }
        return dp[n-1];
    }

复杂度分析

guangsizhongbin commented 3 years ago

func rob(nums []int) int { // 没有房子可以偷 if len(nums) == 0 { return 0 }

// 只有一间房间可以偷
if len(nums) == 1 {
    return nums[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-2]+nums[i], dp[i-1])
}

return dp[len(nums)-1]

}

func max(a, b int) int { if a > b { return a } return b }

BreezePython commented 3 years ago

思路

由于这道题nums.length<=0,所以我们需要从0开始考虑。

当length为0时,直接返回0,当length为1时,由于只有一间房,果断下手返回nums[0]。

当length为2时,由于我们不能同时偷两间房子,那么我们需要选择max(nums[0],nums[1]).

相信以上内容大家都是很好理解的,但是当length大于2时,就需要我们考虑递推公式了!

当length为3时,我们可以考虑是否要偷第三间房子,如果偷第三间房子,就不能偷第二间,如果不偷第三间房子,我们的结果就是上一步length==2的最大值。

我们直接来说当length为4时同理,可以总结出递推公式 dp(i) = max(dp(i-1),num[i]+dp(i-2))

代码

class Solution:
    def rob(self, nums):
        length = len(nums)
        if length == 0:
            return 0
        if length == 1:
            return nums[0]
        left, right = nums[0],max(nums[0], nums[1])
        for i in range(2, length):
            left,right = right,max(left + nums[i], right)
        return right

复杂度

HouHao1998 commented 3 years ago

思想

推算一下前三位,找到规律,递归

代码

class Solution {
    public int rob(int[] nums) {
        int size = nums.length;
        if (size == 0) {
            return 0;
        }
        int[] sum = new int[size];
        sum[0] = nums[0];
        if (size == 1) {
            return sum[0];
        }
        sum[1] = Math.max(sum[0], nums[1]);
        if (size == 2) {
            return sum[1];
        }
        sum[2] = Math.max(sum[1], sum[0] + nums[1]);
        for (int i = 2; i < size; i++) {
            sum[i] = Math.max(sum[i - 1], sum[i - 2] + nums[i]);
        }
        return sum[size - 1];
    }
}

复杂度度

peteruixi commented 3 years ago

思路

跟昨天的题目基本一致, 不过在这里需要考虑当前节点所需要的值

代码

def rob(self, nums: List[int]) -> int:
        N = len(nums)
        dp = [float('-inf')]*N
        if N == 1: return nums[-1]
        dp[0] = nums[0]
        dp[1] = max(nums[0],nums[1])
        for i in range(2, N):
            dp[i] = max(dp[i-1], dp[i-2]+nums[i])
        return max(dp[-1],dp[-2])

复杂度分析

时间复杂度 O(N) 空间复杂度 O(N)

renxumei commented 3 years ago
/**
 * @param {number[]} nums
 * @return {number}
 * 确定dp数组及含义 dp[i]为包括i以内的房屋中 最多可偷窃金额
 * 确定dp推导公式 dp[i] = max(dp[i-2] + nums[i], dp[i-1])
 * dp数组初始化 公式基础为dp[0]=nums[0]、 dp[1]=max(nums[0],nums[1])
 * 确定遍历顺序 dp[i]由dp[i-2]和dp[i-1]推导出来, 顺序为从前到后遍历
 */
var rob = function(nums) {
    const n = nums.length;
    if (!nums || n === 0) {
        return 0
    }
    let dp = new Array(n);
    dp[0] = nums[0];
    dp[1] = Math.max(nums[0],nums[1]);
    for (let i = 2; i < n; i++) {
        dp[i] = Math.max(dp[i-2] + nums[i], dp[i-1])
    }
    return dp[n-1];
};
vincentLW commented 3 years ago
class Solution {
    public int rob(int[] nums) {
        int count = 0;
        if(nums.length == 0){
            return 0;
        }
        if(nums.length == 1){
            return nums[0];
        }
        int[] s = new int[nums.length];
        s[0] = nums[0];
        s[1] = Math.max(nums[0],nums[1]);
        for(int i=2; i< nums.length; i++){
            s[i] = Math.max(s[i-1], s[i-2]+nums[i]);
        }
        return s[nums.length-1];
    }
}

时间复杂度 O(N) 空间复杂度 O(N)

kendj-staff commented 3 years ago
class Solution {
    public int rob(int[] nums) {
        if (nums.length == 1) {return nums[0];}
        int[] memo = new int[nums.length + 1];
        memo[0] = nums[0];
        memo[1] = Math.max(nums[0], nums[1]);

        for (int i = 2; i < memo.length; i++) {
            int getNum = i == nums.length ? 0 : nums[i];
            memo[i] = Math.max(memo[i - 1], memo[i - 2] + getNum);
        }

        return memo[memo.length - 1];
    }
}
ABOUTY commented 3 years ago
class Solution:
    """
    time: O(n)
    space: O(1)
    """
    def rob(self, nums: List[int]) -> int:
        if len(nums) == 1:
            return nums[0]
        elif len(nums) == 2:
            return max(nums[:2])

        pick1, pick2 = nums[0], max(nums[:2])

        for num in nums[2:]:
            # tmp = pick2
            # pick2 = max(pick1 + num, pick2)
            # pick1 = tmp
            pick1, pick2 = pick2, max(pick1 + num, pick2)

        return pick2
V-Enzo commented 3 years ago

思路

  1. 动态规划,有两种选择,一种是选择nums[i],那么最大值为dp[i-2]+nums[i],;另一种则为不选nums[i]时,则最大值为nums[i-1];
  2. 所以用一个dp数组,来构建到达下标i时,能够获得的最大收益。
    class Solution {
    public:
    int rob(vector<int>& nums) {
        if(nums.size() ==1){
            return nums[0];
        }
        int N = nums.size();
        vector<int> dp(N,0);
        dp[0] = nums[0];
        dp[1] = max(nums[1], nums[0]);
        for(int i=2;i<N; i++)
        {
            dp[i] = max(nums[i] + dp[i-2], dp[i-1]);
        }
        return dp[N-1];
    }
    };

    Complexity:

    Time:O(n) Space:O(n)

ccslience commented 3 years ago
class Solution:
    def rob(self, nums: List[int]) -> int:
        if not nums:
            return 0

        length = len(nums)
        if length == 1:
            return nums[0]
        else:
            prev = nums[0]
            cur = max(prev, nums[1])
            for i in range(2, length):
                cur, prev = max(prev + nums[i], cur), cur
            return cur
jaysonss commented 3 years ago

思路

记F(x)为[0,x]范围内能抢劫的最大收益,则有状态转移方程:F(x) =max(F(x-2) + nums[i], F(x-1))

还有一种方程是F(x) =max(F(x-3), F(x-2))+nums[i]

由于遍历过程中始终只能用到x-1,x-2两个变量,所以可以简化dp数组为双指针,从而优化空间复杂度

class Solution {
    public int rob(int[] nums) {
        int len = nums.length;
        if(len==1)return nums[0];
        int left = 0,right = nums[0];

        for(int i=1;i<len;i++){
            int iMax = Math.max(left+nums[i],right);
            left = right;
            right = iMax;
        }
        return right;
    }
}
Richard-LYF commented 3 years ago

class Solution: def rob(self, nums: List[int]) -> int: s=[]

    if nums==[]:
        return 0
    if len(nums)==1:
        return nums[0]
    if len(nums)==2:
        return max(nums)
    s.append(nums[0])
    s.append(max(nums[1],nums[0]))

    for i in range(2,len(nums)):
        s.append(max(s[i-2]+nums[i],s[i-1]))

    return s[-1]

    #o n o n 
Cartie-ZhouMo commented 3 years ago
class Solution:
    def rob(self, nums: List[int]) -> int:
        cur, pre = 0, 0
        for num in nums:
            cur, pre = max(pre + num, cur), cur
        return cur
wenlong201807 commented 3 years ago

代码块


var rob = function (nums) {
  const len = nums.length;
  if (len == 0) return 0;
  const dp = new Array(len + 1);
  dp[0] = 0;
  dp[1] = nums[0];
  for (let i = 2; i <= len; i++) {
    dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i - 1]);
  }
  return dp[len];
};

时间复杂度和空间复杂度

Toms-BigData commented 3 years ago

class Solution: def rob(self, nums: List[int]) -> int: if not nums: return 0

    length = len(nums)
    if length == 1:
        return nums[0]
    else:
        prev = nums[0]
        cur = max(prev, nums[1])
        for i in range(2, length):
            cur, prev = max(prev + nums[i], cur), cur
        return cur
winterdogdog commented 3 years ago
/**
 * @param {number[]} nums
 * @return {number}
 */
var rob = function(nums) {
    let len =  nums.length;
    let res = new Array(len + 1);
    res[0] = 0;
    res[1] = nums[0];
    for(let i = 2; i <= len; i++) {
        res[i] = Math.max(res[i - 1], nums[i - 1] + res[i - 2])
    };
    return res[len]
};
mokrs commented 3 years ago
int rob(vector<int>& nums) {        
    if (nums.size() == 1){
        return nums[0];
    }

    int p1 = nums[0], p2 = max(p1, nums[1]);

    for (int i = 2; i < nums.size(); ++i) {
        int t = p2;
        p2 = max(p1 + nums[i], p2);
        p1 = t;
    }

    return p2;
}
carinSkyrim commented 3 years ago

代码

    def rob(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        record = {}

        def helper(nums, index, record):
            if index == len(nums) - 1:
                record[index] = nums[-1]
                return nums[-1]
            elif index == len(nums) - 2:
                record[index] = max(nums[-1], nums[-2])
                return max(nums[-1], nums[-2])

            first_use = nums[index] + helper(nums, index + 2, record) if index + 2 not in record.keys() else nums[index]+record[index + 2]
            first_not_use = helper(nums, index + 1, record) if index + 1 not in record.keys() else record[index + 1]
            record[index] = max(first_use, first_not_use)
            return max(first_use, first_not_use)

        return helper(nums, 0, record) if nums else 0

复杂度

时间复杂度 O(n)
空间复杂度 O(n)

wangyifan2018 commented 3 years ago
class Solution:
    def rob(self, nums: List[int]) -> int:
        if not nums:
            return 0

        length = len(nums)
        if length == 1:
            return nums[0]
        else:
            prev = nums[0]
            cur = max(prev, nums[1])
            for i in range(2, length):
                cur, prev = max(prev + nums[i], cur), cur
            return cur
Bingbinxu commented 3 years ago

方法 动态规划 代码

实现语言: C++
class Solution {
public:
    int rob(vector<int>& nums) {
        // define robe x to obtain max value as dp function. 
        // dp(x) =  max(num[x] + dp(x-2), dp(x-1))

        vector<int> dp(2, 0); 
        for(int i=0; i< nums.size(); i++)
        {

            int current = max(nums[i] + dp[0], dp[1]); 
            dp[0] = dp[1]; 
            dp[1] = current; 
        }

        return dp[1]; 

    }
};

复杂度分析 时间复杂度: O(N) 空间复杂度: O(1)

newbeenoob commented 3 years ago

思路:


定义 :dp[i] 代表 在 i 位置 ( i 号房屋 ) 小偷能获得的最大获利

状态转移:据观察,dp[i] 只由相邻的两个位置的状态转移而来

状态转移方程: 由于相邻的房屋如果被闯入则会触发警报,所以 dp[i] 不能由 dp[i-1] + nums[i-1] 这个关系式转移而来,只能由 dp[i-2] + nums[i-1] 这个关系式转移而来 我们要求最大值,故转移方程为 : dp[i] = max(dp[i-1] , dp[i-2] + nums[i-1]

base case : dp[0] = 0 dp[1] = nums[0]

代码 Js :

var rob = function(nums) {

    const n = nums.length;
    // 初始化 dp 数组
    const dp = new Array(n+1).fill(0);

    dp[1] = nums[0];

    for(let i = 2 ; i <= n ; ++i) {
        dp[i] = Math.max(dp[i-1] , dp[i-2] + nums[i-1]);
    }

    return dp[n];
};

复杂度分析



由于当前状态只由前一个和前两个状态转移而来,所以可以用三个迭代变量代替dp数组:

var rob = function(nums) {

    const n = nums.length;
    // const dp = new Array(n+1).fill(0);

    let dp_i = nums[0];
    let dp_1 = dp_i , dp_2 = 0;

    for(let i = 2 ; i <= n ; ++i) {
        dp_i = Math.max(dp_1 , dp_2 + nums[i-1]);
        dp_2 = dp_1;
        dp_1 = dp_i;
    }

    return dp_i;
};

标签

线性DP

HWFrankFung commented 3 years ago

Codes

var rob = function(nums) {
    if (nums.length === 0) {
        return 0;
    }
    if (nums.length === 1) {
        return nums[0];
    }
    let sum1 = nums[0];
    let sum2 = nums[1];
    for (let lastIndex=2; lastIndex<nums.length; lastIndex++) {
        let tmp = sum1;
        if (sum2 > sum1) {
            sum1 = sum2;
        }
        sum2 = tmp + nums[lastIndex]; 
    }

    return sum1 > sum2 ? sum1 : sum2;
};
ymkymk commented 3 years ago

思路

动态规划

代码

``


class Solution {

 int rob(int[] nums) {
    int n = nums.length;
    // 记录 dp[i+1] 和 dp[i+2]
    int dp_i_1 = 0, dp_i_2 = 0;
    // 记录 dp[i]
    int dp_i = 0; 
    for (int i = n - 1; i >= 0; i--) {
        dp_i = Math.max(dp_i_1, nums[i] + dp_i_2);
        dp_i_2 = dp_i_1;
        dp_i_1 = dp_i;
    }
    return dp_i;
}
}

复杂度分析

时间复杂度:O(n)

空间复杂度:O(1)

SunStrongChina commented 3 years ago

198. 打家劫舍

入选理由

暂无

题目地址

https://leetcode-cn.com/problems/house-robber/

前置知识

暂无

题目描述

你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。

给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。

 

示例 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

朴素动态规划,无非就是偷不偷,偷了咋样,不偷咋样,定义dp为路过第i间房的最大能偷到的钱

class Solution:
    def rob(self, nums: List[int]) -> int:
        dp=[0 for i in range(len(nums))]
        if len(nums)<2:
            return nums[0]
        dp[0]=nums[0]
        dp[1]=max(nums[1],dp[0])
        max_value=max(dp[0],dp[1])
        for  i in range(2,len(nums)):
            dp[i]=max(dp[i-2]+nums[i],dp[i-1])
            max_value=max(max_value,dp[i])
        return max_value

时间复杂度:O(N) 空间复杂度:O(N)

ChenJingjing85 commented 3 years ago

思路

先用带缓存递归写。和爬楼梯还是一样的,只不过跳过前面一级

代码

class Solution:
    def rob(self, nums: List[int]) -> int:
        @lru_cache
        def mostAmount(i) -> int: #偷到第i间(包括i)为止的最大金额
            if i < 0: return 0
            #if i == 0: return nums[0]
            #if i == 1: return nums[1]
            #if i == 2: return nums[0]+nums[2]
            ans = max(mostAmount(i-2), mostAmount(i-3)) + nums[i]
            return ans
        l = len(nums)
        return max(mostAmount(l-1), mostAmount(l-2))

复杂度分析

时间复杂度:O(N) 空间复杂度:O(N)

laurallalala commented 3 years ago

代码

class Solution(object):
    def rob(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        if len(nums) == 1:
            return nums[0]
        n = len(nums)
        dp = [0]*n
        dp[0] = nums[0]
        dp[1] = nums[1]
        res = max(dp[0], dp[1])
        for i in range(2, n):
            if i-2>=0:
                dp[i] = max(dp[i], dp[i-2]+nums[i])
            if i-3>=0:
                dp[i] = max(dp[i], dp[i-3]+nums[i])
            res = max(res, dp[i])
        return res

复杂度

Lydia61 commented 3 years ago

打家劫舍

思路

动态规划,类似昨天的题目

代码

class Solution:
    def rob(self, nums: List[int]) -> int:
        prev = 0
        curr = 0
        for i in nums:
            prev, curr = curr, max(curr, prev + i)
        return curr

复杂度分析

skinnyh commented 3 years ago

Note

Solution

class Solution:
    def rob(self, nums: List[int]) -> int:
        dp = [0] * 3
        n = len(nums)
        for i in range(n):
            d1 = dp[(i - 1) % 3] if i >= 1 else 0
            d2 = dp[(i - 2) % 3] if i >= 2 else 0
            dp[i % 3] = max(nums[i] + d2, d1)
        return dp[(n - 1) % 3]

Time complexity: O(N)

Space complexity: O(1)

machuangmr commented 3 years ago

题目198. 打家劫舍

思路

cy-sues commented 3 years ago

动态规划

package ch10.code;

public class ClimbingStairs {
    public int climbStairs(int n) {
        if (n < 3)
            return n;

        int[] dp = new int[n + 1];
        dp[1] = 1;
        dp[2] = 2;
        for (int i = 3; i < n+1; i++) {
            dp[i] = dp[i - 1] + dp[i - 2];
        }
        return dp[n];
    }
}
falsity commented 3 years ago

class Solution { public int rob(int[] nums) { int n = nums.length; int[] dp = new int[n+1]; dp[0] = 0; dp[1] = nums[1]; for(int k = 2; k <= n; k++){ dp[k] = Math.max(dp[k-1], nums[k-1] = dp[k-2]); } return dp[n]; } }

joriscai commented 3 years ago

思路

代码

javascript

/*
 * @lc app=leetcode.cn id=198 lang=javascript
 *
 * [198] 打家劫舍
 */

// @lc code=start
/**
 * @param {number[]} nums
 * @return {number}
 */
var rob = function(nums) {
  const dp = []
  // 0和1项都可能是开始的点,即为0
  dp[0] = dp[1] = 0

  // 由于前两项是默认状态,故从2开始,相应地nums.length + 2为终止条件
  for (let i = 2; i < nums.length + 2; i++) {
    // nums[i - 2]为当前值
    // 由于不能连续,即i - 1不可取,故不能加上值
    dp[i] = Math.max(dp[i - 2] + nums[i - 2], dp[i - 1])
  }

  return dp[nums.length + 1]
};
// @lc code=end

复杂度分析

st2yang commented 3 years ago

思路

代码

复杂度

JianXinyu commented 3 years ago

思路

DP

Code

class Solution {
public:
    int rob(vector<int>& nums) {
        const int n = nums.size();
        if(n == 1)
            return nums[0];
        vector<int> dp(n);
        dp[0] = nums[0];
        dp[1] = max(dp[0], nums[1]);
        for(int i = 2; i < n; ++i){
            dp[i] = max(dp[i-2] + nums[i], dp[i-1]);
        }
        return max(dp[n-1], dp[n-2]);
    }
};

T: O(n), S: O(n)

Optimize:

class Solution {
public:
    int rob(vector<int>& nums) {
        const int n = nums.size();
        if(n == 1)
            return nums[0];

        int pre = nums[0];
        int cur = max(pre, nums[1]);
        for(int i = 2; i < n; ++i){
            int tmp = cur;
            cur = max(pre + nums[i], cur);
            pre = tmp;
        }
        return cur;
    }
};

T: O(n), S: O(1)

Abby-xu commented 3 years ago
class Solution:
    def rob(self, nums: List[int]) -> int:

        n = len(nums)

        if n <= 2:
            return max(nums)

        first = nums[0]
        second = max(nums[0], nums[1])
        for i in range(2, n):
            temp = max(first + nums[i], second)
            first = second
            second = temp
        return max(first, second)

Time: O(n) Space:O(1)

yibenxiao commented 3 years ago

【Day 55】198. 打家劫舍

思路

dp[i] = max(dp[i - 2] + nums[i - 2], dp[i - 1])

代码

class Solution {
public:
    int rob(vector<int>& nums) {
        if (nums.empty()) return 0;
        auto sz = nums.size();
        if (sz == 1) return nums[0];
        auto prev = nums[0];
        auto cur = max(prev, nums[1]);
        for (auto i = 2; i < sz; ++i) {
            auto tmp = cur;
            cur = max(nums[i] + prev, cur);
            prev = tmp;
        }
        return cur;
    }
};

复杂度

时间复杂度:O(N)

空间复杂度:O(1)

Auto-SK commented 3 years ago

思路

动态规划

程序

class Solution:
    def rob(self, nums: List[int]) -> int:
        dp = [0] * len(nums)
        if len(nums) == 1:
            return nums[0]
        if len(nums) == 2:
            return max(nums[0], nums[1])
        dp[0] = nums[0]
        dp[1] = max(nums[0], nums[1])
        for i in range(2, len(nums)):
            dp[i] = max(dp[i - 1], dp[i - 2] + nums[i])
        return dp[-1]

复杂度

ZETAVI commented 3 years ago

class Solution {
    public int rob(int[] nums) {
        int n = nums.length;
        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(dp[i - 2] + nums[i],dp[i - 1]);
        }
        return dp[n-1];
    }
}

复杂度分析:

时间复杂度:O(n) 空间复杂度:O(n)

brainlds commented 3 years ago

class Solution { public int rob(int[] nums) { if(nums == null) return -1; if(nums.length == 1) return nums[0]; int first = nums[0], second = Math.max(nums[0], nums[1]); for(int i = 2; i < nums.length;i++) { int temp = second; second = Math.max(first + nums[i], second); first = temp; } return second; } }

taojin1992 commented 3 years ago

Understand:

it will automatically contact the police if two adjacent houses were broken into on the same night.

maximum amount of money you can rob tonight without alerting the police.

1 <= nums.length <= 100
0 <= nums[i] <= 400

Plan:

dp[0] = nums[0]
dp[1] = max(nums[0], nums[1]) 
0 1 2 3 4 5
        |
        i

dp[i]: the max money by index i (after finishing index i)
if we rob (i-1)th house, dp[i] = dp[i-1]
else: dp[i] = dp[i-2] + nums[i]

dp[i] = max(dp[i-1], dp[i-2] + nums[i]) 

[1]
[1,2]
[1,9,10]
dp[0] = 0
dp[1] = 1
dp[2] = 9
dp[3] = max(9, 1 + 10)

Time: O(n), n = nums.length
Space: O(n)

--> optimized to O(1) space

Code:

class Solution {
    public int rob1(int[] nums) {
        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], dp[i - 2] + nums[i]);
        }
        return dp[nums.length - 1];
    }

    //[1.1]
    // prev2 = 1, prev1 = 1

    public int rob(int[] nums) {
        if (nums.length == 1) return nums[0];
        int prev2 = nums[0];  
        int prev1 = Math.max(nums[0], nums[1]);
        int money = Math.max(prev1, prev2);

        for (int i = 2; i < nums.length; i++) {      
            money = Math.max(prev1, prev2 + nums[i]);
            prev2 = prev1;
            prev1 = money;
        }
        return money;
    }
}
RocJeMaintiendrai commented 3 years ago

题目

https://leetcode-cn.com/problems/house-robber/

思路

DP

代码

class Solution {
    public int rob(int[] nums) {
        final int len = nums.length;
        if(len == 0) return 0;
        int dp[] = new int[len + 1];
        dp[0] = 0;
        dp[1] = nums[0];
        for(int i = 1; i < nums.length; i++) {
            dp[i + 1] = Math.max(dp[i], dp[i - 1] + nums[i]);
        }
        return dp[len];
    }
}

复杂度分析

时间复杂度

O(n)

空间复杂度

O(n)

CruiseYuGH commented 3 years ago

思路

关键点

代码

Python3 Code:


class Solution:
    def rob(self, nums: List[int]) -> int:
        if not nums:
            return 0
        size = len(nums)
        if size ==1:
            return nums[0]

        dp = [0]*size
        dp[0] = nums[0]
        dp[1] = max(nums[0], nums[1])
        for i in range(2,size):
            dp[i] = max(dp[i-2]+nums[i],dp[i-1])
        #print(dp)
        return dp[-1]

复杂度分析

令 n 为数组长度。

liudi9047 commented 3 years ago

class Solution { public int rob(int[] nums) { int count = 0; if(nums.length == 0){ return 0; } if(nums.length == 1){ return nums[0]; } int[] s = new int[nums.length]; s[0] = nums[0]; s[1] = Math.max(nums[0],nums[1]); for(int i=2; i< nums.length; i++){ s[i] = Math.max(s[i-1], s[i-2]+nums[i]); } return s[nums.length-1]; } }

q815101630 commented 3 years ago

稍微周末终于有空补下习题

这道题我直接发note吧,感觉理解还是比较清晰的

2FDF8E791746F485186EA84F4523D426
class Solution:
    def rob(self, nums: List[int]) -> int:
        if len(nums) < 2:
            return nums[0]
        dp = [0 for i in nums]
        dp[0] = nums[0]
        dp[1] = max(nums[0], nums[1])

        for i in range(2, len(dp)):
            dp[i] = max(dp[i-1], dp[i-2]+nums[i])

        return dp[-1]

复杂度

时间 O(n) 空间 O(n)

sumukeio commented 3 years ago

class Solution: def rob(self, nums: List[int]) -> int: n = len(nums) if n == 1: return nums[0] curr, prev = max(nums[1], nums[0]), nums[0]

    for i in range(2, n):
        curr, prev = max(prev + nums[i], curr), curr

    return curr
lilixikun commented 3 years ago

思路

转移方程: dp[i] = Matn.max(dp[i-2] + nums[i-2],dp[i-1])

代码

var rob = function(nums) {
    if(!nums||nums.length==0){
        return 0
    }
    if(nums.length==1) return nums[0]
    let first = nums[0]
    let second = Math.max(nums[0],nums[1])
    for(let i = 2;i<nums.length;i++){
        let tem = second
        second = Math.max(first + nums[i],second)
        first = tem
    }
    return second
};