当前位置: 首页 > article >正文

LeetCode--198. 打家劫舍【从返回最大值到输出路径】

198. 打家劫舍

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

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


像这种dp都是三分钟出来了,难的又做不出来,感觉目前就是纯记忆了,真得废了

func rob(nums []int) int {
    n := len(nums)
    f := make([][]int, n)

    for i := 0; i < n; i ++ {
        f[i] = make([]int, 2)
    }
    f[0][1] = nums[0]

    for i := 1; i < n; i ++ {
        f[i][0] = max(f[i - 1][1], f[i - 1][0])
        f[i][1] = f[i - 1][0] + nums[i]
    }

    return max(f[n - 1][0], f[n - 1][1])
}

滚动数组优化

byd,这几把dp空间复杂度都O(1)了,好虾仁

func rob(nums []int) int {
    n := len(nums)
    f := make([][]int, 2)

    for i := 0; i < 2; i ++ {
        f[i] = make([]int, 2)
    }
    f[0][1] = nums[0]

    for i := 1; i < n; i ++ {
        f[i%2][0] = max(f[(i - 1)%2][1], f[(i - 1)%2][0])
        f[i%2][1] = f[(i - 1)%2][0] + nums[i]
    }

    return max(f[(n - 1)%2][0], f[(n - 1)%2][1])
}

无需二维数组的做法

虽然这种看起来还算优雅吧,但是在计算路径的时候可能不是太友好。

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

    nums[1] = max(nums[1], nums[0])
    for i := 2; i < n + 2; i ++ {
        f[i] = max(f[i - 1], f[i - 2] + nums[i - 2])
    }

    return f[n + 1]
}

输出路径

这部分还是花了一点时间,总体思路是用三位数组解决的,至于测试,我是通过遍历path,将ans加起来,然后return,通过了力扣的测试,应该是没啥问题的。

每次走都有一次路径的保存,同时有偷和不偷的两种选择,这个思路和上面是一样的,虽然这里完全可以优化很多空间,但是为了好理解,我直接把没有优化过的放出来了。

package main

import "fmt"

func rob(nums []int) int {
	n := len(nums)
	f := make([][]int, n)
	path := make([][][]int, n)
	for i := 0; i < n; i++ {
		f[i] = make([]int, 2)
		path[i] = make([][]int, 2)
	}
	f[0][1] = nums[0]
	path[0][1] = append([]int{}, nums[0])

	for i := 1; i < n; i++ {
		if f[i-1][0] > f[i-1][1] {
			f[i][0] = f[i-1][0]
			path[i][0] = append([]int{}, path[i-1][0]...)
		} else {
			f[i][0] = f[i-1][1]
			path[i][0] = append([]int{}, path[i-1][1]...)
		}

		f[i][1] = f[i-1][0] + nums[i]
		cur := append([]int{}, path[i-1][0]...)
		cur = append(cur, nums[i])

		path[i][1] = cur
	}
	if f[n-1][0] > f[n-1][1] {
		fmt.Println(path[n-1][0])
		return f[n-1][0]
	} else {
		fmt.Println(path[n-1][1])
		return f[n-1][1]
	}
}

func main() {
	fmt.Println(rob([]int{1, 1, 1, 2}))
}

有一段时间没写blog了,只是因为感觉遇到的题没啥含金量,写不出什么东西来,就随便讲下思路就push上github了,感觉还是比较水,就没上传到博客上面,哈哈,有兴趣可以看看我的Github🥳


http://www.kler.cn/a/588563.html

相关文章:

  • 【Go语言圣经2.4】
  • 以太坊生态中有代币标准和协议,针对不同场景设计了丰富的功能
  • 网络安全演练有哪些形式
  • GO语言的GC(垃圾回收)原理
  • 浏览器缓存机制:JavaScript 文件缓存导致 404 错误的解决方案
  • HTML5与CSS3新特性详解
  • vue父组件向子组件传函数,子组件调用函数向父组件传参
  • 【CXX】6.9 CxxVector<T> — std::vector<T>
  • Linux内核传输层UDP源码分析
  • 日志、类加载器、XML(配置文件)
  • 【HarmonyOS NEXT】实现文字环绕动态文本效果
  • JS基础部分
  • DeepSeek在学术写作选择研究方向的2个核心提示词
  • pip install和conda install的区别
  • C# --- LINQ
  • 没有公网服务器的情况下,建立反弹 Shell
  • 网络编程、URI和URL的区别、TCP/IP协议、IP和端口、URLConnection
  • LLM(3): Transformer 架构
  • 数据结构-树(详解)
  • 力扣Hot100——35.搜索插入的位置(二分查找)