leetcode动态规划之买卖股票+打家劫舍

刷题的时候发现这两种可以单独放出来总结下。

121 买卖股票I

题目:给定一维数组代表每日的股票价格,只可以买入卖出一次,求最大利润
解析:股票系列的问题,一般定义的dp数组都是二维的,其中第二维只有0和1,0代表买入,1代表卖出,dp数组的含义也是和求的一样,递推公式直接看下面代码把

func maxProfit(prices []int) int {// 动态规划解法dp := make([][]int, len(prices))for i := 0; i < len(prices); i++ {dp[i] = make([]int, 2)}// 所以在这里初始化的是一个二维数组,且第二维度只有0和1两个值// 0代表持有该股票,1代表不持有该股票// 初始化DP数组dp[0][0] = -prices[0] // 若第一天就持有的话,只能是当天买入dp[0][1] = 0 // 若第一天不持有,很合理for i := 1; i < len(prices); i++ {dp[i][0] = max(dp[i-1][0], -prices[i])dp[i][1] = max(dp[i-1][1], dp[i-1][0] + prices[i])}return dp[len(prices)-1][1]
}func max(a, b int) int {if a > b {return a} return b
}
122 买卖股票II

题目:可多次买入和卖出

func maxProfit(prices []int) int {// 动态规划解法dp := make([][]int, len(prices))for i := 0; i < len(prices); i++ {dp[i] = make([]int, 2)}// 所以在这里初始化的是一个二维数组,且第二维度只有0和1两个值// 0代表持有该股票,1代表不持有该股票// 初始化DP数组dp[0][0] = -prices[0] // 若第一天就持有的话,只能是当天买入dp[0][1] = 0 // 若第一天不持有,很合理for i := 1; i < len(prices); i++ {dp[i][0] = max(dp[i-1][0], dp[i-1][1] - prices[i]) // 注意这一行dp[i][1] = max(dp[i-1][1], dp[i-1][0] + prices[i])}return dp[len(prices)-1][1]
}func max(a, b int) int {if a > b {return a} return b
}
123 买卖股票III

题目:最多可完成两笔交易
解析:这道题需要细化五种dp状态:

  • 没有操作
  • 第一次持有股票
  • 第一次不持有股票
  • 第二次持有股票
  • 第二次不持有股票
func maxProfit(prices []int) int {// 先定义DP数组dp := make([][]int, len(prices)) // 一维数组定义数量是输入数组的个数,二维的是5for i := 0; i < len(prices); i++ {dp[i] = make([]int, 5)}dp[0][0] = 0 // 初始化DP数组dp[0][1] = -prices[0]dp[0][2] = 0dp[0][3] = -prices[0]dp[0][4] = 0for i := 1; i < len(prices); i++ {dp[i][0] = dp[i-1][0]dp[i][1] = max(dp[i-1][1], dp[i-1][0] - prices[i])dp[i][2] = max(dp[i-1][2], dp[i-1][1] + prices[i])dp[i][3] = max(dp[i-1][3], dp[i-1][2] - prices[i])dp[i][4] = max(dp[i-1][4], dp[i-1][3] + prices[i])}return dp[len(prices)-1][4]
}
func max(a, b int) int {if a > b {return a}return b
}
188 买卖股票IIII

题目:可以完成K笔交易,k是入参
解析:k笔交易,每笔有买入和卖出两个操作,二维数组就是2k+1的大小,注意这道题初始化用取余操作,遍历的时候也用取余来判断到底是买入还是卖出
一共算下来是三个状态:

  • 无状态
  • 买入
  • 卖出
func maxProfit(k int, prices []int) int {// k表示最多有k次交易dp := make([][]int, len(prices)+1)for i := 0; i < len(prices); i++ {dp[i] = make([]int, 2*k+1) // 每次交易表示买入和卖出,初始化二维数组里的每个数组}for i := 1; i < len(dp[0]); i++ { // 初始化的时候,对于第一天的所有可买入的case进行初始化if i % 2 != 0 {dp[0][i] = -prices[0]}}for i := 1; i < len(prices); i++ {dp[i][0] = dp[i-1][0]for j := 1; j < len(dp[0]); j++ {if j % 2 != 0 {dp[i][j] = max(dp[i-1][j], dp[i-1][j-1] - prices[i])} else {dp[i][j] = max(dp[i-1][j], dp[i-1][j-1] + prices[i])}}}return dp[len(prices) - 1][2*k] // 最后一天的最后一笔交易(初始化的时候是2*k+1)
}
func max(a, b int) int {if a > b {return a}return b
}
309 买卖股票有冷冻期

题目:卖出后冷冻期为1天
解析:这道题分为如下几种状态(记住下面的这些状态):
状态0:处于买入状态
状态1:处于保持卖出状态
状态2:处于今天卖出状态
状态4:处于冷冻期

func maxProfit(prices []int) int {n := len(prices)dp := make([][]int, n)for i := 0; i < n; i++ {dp[i] = make([]int, 4) // 0123四种状态}dp[0][0] = -prices[0] // 只有第1天的买入情况需要初始化,其余的默认为0for i := 1; i < n; i++ { // 从第二天开始遍历dp[i][0] = max(dp[i-1][0], max(dp[i-1][1] - prices[i], dp[i-1][3] - prices[i]))dp[i][1] = max(dp[i-1][1], dp[i-1][3])dp[i][2] = dp[i-1][0] + prices[i]dp[i][3] = dp[i-1][2]}return max(dp[n-1][1], max(dp[n-1][2], dp[n-1][3]))
}
func max(a, b int) int {if a > b {return a}return b
}
714 买卖股票加手续费

这个就很简单了,就是在买卖股票II上,卖出的时候减去手续费就行

func maxProfit(prices []int, fee int) int {n := len(prices)dp := make([][]int, n)for i := 0; i < n; i++ {dp[i] = make([]int, 2) // 0和11两种状态}dp[0][0] = -prices[0]for i := 1; i < n; i++ {dp[i][0] = max(dp[i-1][0], dp[i-1][1] - prices[i])dp[i][1] = max(dp[i-1][1], dp[i-1][0] + prices[i] - fee)}return dp[n-1][1]
}
func max(a, b int) int {if a > b {return a}return b
}

198 打家劫舍

题目:给一个数组,不能连着偷,求最大的
解析:就正常的动态规划,定义好了初始值后就遍历

func rob(nums []int) int {if len(nums) == 1 { // 兼容测试用例return nums[0]}dp := make([]int, len(nums)+1)dp[0] = nums[0]dp[1] = max(nums[0], nums[1])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
}
213 打家劫舍II

题目:需要偷的是一个环
解析:那就分成两个部分

  • 0 – n-2
  • 1 – n-1

然后再比较两个部分中的最大值

func rob(nums []int) int {if len(nums) == 1 {return nums[0]}if len(nums) == 2 {return max(nums[0], nums[1])}res1 := robRange(nums, 0, len(nums) - 2)res2 := robRange(nums, 1, len(nums) - 1)return max(res1, res2)
}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 < len(nums); 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 b}return a
}
337 打家劫舍III

题目:是一个二叉树,也不能连着偷
解析:其实用的是递归+二叉树的后续遍历,先求出左右子节点,在分别判断是偷合适还是不偷合适,用一个数组,0表示不偷,1表示偷

/*** Definition for a binary tree node.* type TreeNode struct {*     Val int*     Left *TreeNode*     Right *TreeNode* }*/
func rob(root *TreeNode) int {res := robTree(root)return max(res[0], res[1])
}func max(a, b int) int {if a > b {return a} return b
}func robTree(cur *TreeNode) []int{if cur == nil {return []int{0, 0}}// 二叉树后序遍历left := robTree(cur.Left)right := robTree(cur.Right)// 考虑去偷当前的屋子robCur := cur.Val + left[0] + right[0]// 考虑不偷当前的屋子notRobCur := max(left[0], left[1]) + max(right[0], right[1])return []int{notRobCur, robCur}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/146351.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

【夏虫语冰】测试服务器端口是否打开(命令行、Python)

文章目录 1、简介2、命令行2.1 telnet2.1.1 工具简介2.1.2 工具配置2.1.3 工具使用 2.2 curl2.2.1 工具简介2.2.1 工具下载2.2.1 工具使用 2.3 wget2.3.1 工具简介2.3.2 工具下载2.3.2 工具使用 2.4 nc2.4.1 工具简介2.4.2 工具安装2.4.3 工具使用 2.5 ssh2.5.1 工具简介2.5.2 …

动态规划算法(1)--矩阵连乘和凸多边形剖分

目录 一、动态数组 1、创建动态数组 2、添加元素 3、删除修改元素 4、访问元素 5、返回数组长度 6、for each遍历数组 二、输入多个数字 1、正则表达式 2、has.next()方法 三、矩阵连乘 1、什么是矩阵连乘&#xff1f; 2、动态规划思路 3、手推m和s矩阵 4、完…

番外4:VMware安装

step4: 安装过程中&#xff0c;有些选项不需要点&#xff08;安装地址建议选C盘或默认&#xff0c;装载在其他盘后续会报错&#xff09;&#xff0c;如&#xff1a; may error&#xff08;本人猜测安装虚拟机完整版需要C盘的一些桥插件支持&#xff09;: step5: 安装虚拟机成功…

给奶牛做直播之三

​一、前言 上一篇给牛奶做直播之二 主要讲用RTMP搭建点播服务器&#xff0c;整了半天直播还没上场&#xff0c;今天不讲太多理论的玩意&#xff0c;奶牛今天放假了也不出场&#xff0c;就由本人亲自上场来个直播首秀&#xff0c;见下图&#xff0c;如果有兴趣的话&#xff0…

Android修行手册 - Activity 在 Java 和 Kotlin 中怎么写构造参数

点击跳转>Unity3D特效百例点击跳转>案例项目实战源码点击跳转>游戏脚本-辅助自动化点击跳转>Android控件全解手册点击跳转>Scratch编程案例点击跳转>软考全系列 &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff0c;以及各种资源分享&…

大喜国庆,聊聊我正式进入职场的这三个月...

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;正逐渐往全干发展 &#x1f4c3;个人状态&#xff1a; 研发工程师&#xff0c;现效力于中国工业软件事业 &#x1f680;人生格言&#xff1a; 积跬步…

实现三栏布局的十种方式

本文节选自我的博客&#xff1a;实现三栏布局的十种方式 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是MilesChen&#xff0c;偏前端的全栈开发者。&#x1f4dd; CSDN主页&#xff1a;爱吃糖的猫&#x1f525;&#x1f4e3; 我的博客&#xff1a;爱吃糖的猫&…

02-Zookeeper实战

上一篇&#xff1a;01-Zookeeper特性与节点数据类型详解 1. zookeeper安装 Step1&#xff1a; 配置JAVA环境&#xff0c;检验环境&#xff1a; java -versionStep2: 下载解压 zookeeper wget https://mirror.bit.edu.cn/apache/zookeeper/zookeeper-3.5.8/apache-zookeepe…

番外5:下载+安装+配置Linux

任务前期工作&#xff1a; 01. 电脑已安装好VMware Workstation软件&#xff1b; 02.提前下载好Rhel-8.iso映像文件&#xff08;文件较大一般在9.4GB&#xff0c;建议采用迅雷下载&#xff09;&#xff0c;本人使用的以下版本&#xff08;地址ed2k://|file|rhel-8.4-x86_64-dvd…

C++-哈希Hash

本期我们来学习哈希 目录 unordered系列关联式容器 unordered_map unordered_set 性能比较 哈希概念 哈希冲突 哈希函数 哈希冲突解决 闭散列 模拟实现 开散列 模拟实现 全部代码 unordered系列关联式容器 在 C98 中&#xff0c; STL 提供了底层为红黑树结构的一…

【算法基础】一文掌握十大排序算法,冒泡排序、插入排序、选择排序、归并排序、计数排序、基数排序、希尔排序和堆排序

目录 1 冒泡排序&#xff08;Bubble Sort&#xff09; 2 插入排序&#xff08;Insertion Sort&#xff09; 3 选择排序&#xff08;Selection Sort&#xff09; 4. 快速排序&#xff08;Quick Sort&#xff09; 5. 归并排序&#xff08;Merge Sort&#xff09; 6 堆排序 …

【day10.01】使用select实现服务器并发

用select实现服务器并发&#xff1a; linuxlinux:~/study/1001$ cat server.c #include <myhead.h>#define ERR_MSG(msg) do{\printf("%d\n",__LINE__);\perror(msg);\ }while(0)#define PORT 8880#define IP "192.168.31.38"int main(int argc, c…

11链表-迭代与递归

目录 LeetCode之路——206. 反转链表 分析&#xff1a; 解法一&#xff1a;迭代 解法二&#xff1a;递归 LeetCode之路——206. 反转链表 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例 1&#xff1a; 输入&#xff1a;head […

开绕组电机零序Bakc EMF-based无感控制以及正交锁相环inverse Park-based

前言 最近看论文遇到了基于反Park变换的锁相环&#xff0c;用于从开绕组永磁同步电机零序电压信号中提取转子速度与位置信息&#xff0c;实现无感控制。在此记录 基于零序Back EMF的转子估算 开绕组电机的零序反电动势 e 0 − 3 ω e ψ 0 s i n 3 θ e e_0-3\omega_e\psi_…

SoloX:Android和iOS性能数据的实时采集工具

SoloX&#xff1a;Android和iOS性能数据的实时采集工具 github地址&#xff1a;https://github.com/smart-test-ti/SoloX 最新版本&#xff1a;V2.7.6 一、SoloX简介 SoloX是开源的Android/iOS性能数据的实时采集工具&#xff0c;目前主要功能特点&#xff1a; 无需ROOT/越狱…

直播协议 python 常见直播协议

1. 推流、直播 和 点播分别是什么意思&#xff1f; 推流 主播将本地视频源和音频源推送到云服务器&#xff0c;也被称为“RTMP发布”。 直播 即直接观看主播实时推送过来的音视频数据。 点播 视频源已经事先存储于云服务器之上的音视频文件&#xff0c;观众随时可以观看。 目…

STM32晶振的选择与计算

目录 1、石英晶体特性和型号2、振荡器理论2.1负电阻2.2跨导2.3负阻振荡器原理 3、皮尔斯振荡器设计3.1 皮尔斯振荡器简介3.2反馈电阻器3.3负载电容3.4振荡器跨导3.5驱动电平和外部电阻计算3.5.1计算驱动电平3.5.2另一种驱动电平测量方法3.5.3计算外部电阻 3.6启动时间3.7晶体拉…

八个不可不知的SQL高级方法

结构化查询语言&#xff08;SQL&#xff09;是一种广泛使用的工具&#xff0c;用于管理和操作数据库。基本的SQL查询简单易学&#xff0c;但掌握高级SQL技术可以将您的数据分析和管理能力提升到新的高度。 高级SQL技术是指一系列功能和函数&#xff0c;使您能够对数据执行复杂…

记录:Unity脚本的编写

目录 前言添加脚本到unity编写c#脚本查看效果 前言 在学习软件构造这门课的时候&#xff0c;对unity和c#进行了 一定程度的学习&#xff0c;包括简单的建立地形&#xff0c;添加对象&#xff0c;添加材质等&#xff0c;前不久刚好学习了如何通过c#脚本对模型进行操控&#xff…

uniapp - 微信小程序实现腾讯地图位置标点展示,将指定地点进行标记选点并以一个图片图标展示出来(详细示例源码,一键复制开箱即用)

效果图 在uniapp微信小程序平台端开发,简单快速的实现在地图上进行位置标点功能,使用腾讯地图并进行标点创建和设置(可以自定义标记点的图片)。 你只需要复制代码,改个标记图标和位置即可。