算法-打家劫舍

145 阅读1分钟

基础款

  1. 确定dp数组(dp table)以及下标的含义

dp[i]:考虑下标i(包括i)以内的房屋,最多可以偷窃的金额为dp[i]

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

  2. dp[0] 一定是 nums[0],dp[1]就是nums[0]和nums[1]的最大值即:dp[1] = max(nums[0], nums[1]);

  3. 顺序从前到后

 func rob(nums []int)int  {
	if len(nums) == 0{
        return 0
    }
    if len(nums) == 1{
        return nums[0]
    }
    if len(nums) == 2{
        return max(nums[0],nums[1])
    }
    dp := make([]int,len(nums))
    dp[0] = nums[0]

    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
}

围成一个圈

分两种情况,一个包括首不包括尾,一个包括尾不包括首

func rob(nums []int) int {
if len(nums)  == 1{
		return nums[0]
	}
	if len(nums)==2 {
		return max(nums[0],nums[1])
	}

	return max(robrange(nums,0,len(nums)-2),robrange(nums,1,len(nums)-1)) 
}

func robrange(nums []int,start,end int)int{
    dp := make([]int,len(nums))
    dp[start] = nums[start]
    dp[start+1] = max(nums[start],nums[start+1])
    for i:= start+2;i<=end;i++{
        dp[i] = max(dp[i-1],dp[i-2]+nums[i])
    }
    return dp[end]
}



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

后序遍历

dp = []int{不偷,偷}

/**
 * Definition for a binary tree node.
 * type TreeNode struct {
 *     Val int
 *     Left *TreeNode
 *     Right *TreeNode
 * }
 */
func rob(root *TreeNode) int {
    //0代表没偷金额,1代表偷了
    res := []int{}
    var rotree func(root *TreeNode)[]int
    rotree = func(root *TreeNode)[]int{
        if root == nil{
            return []int{0,0}
        }
        left := rotree(root.Left)
        right := rotree(root.Right)

        //butou
        notrobcur := max(left[0],left[1])+max(right[0],right[1])
        //tou
        robcur:=root.Val+left[0]+right[0]
        return []int{notrobcur,robcur}
    }

    res = rotree(root)
    return max(res[0],res[1])
}

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