首页 > 其他分享 >leetcode-动态规划1-4

leetcode-动态规划1-4

时间:2022-10-09 17:12:14浏览次数:47  
标签:示例 int 复杂度 func prices 卖出 动态 规划 leetcode

目录

leetcode-动态规划题目方法

五部曲:
1. 确定dp数组(dp table)以及下标的含义
2. 确定递推公式
3. dp数组如何初始化
4. 确定遍历顺序
5. 举例推导dp数组

什么是动态规划
动态规划,英⽂:Dynamic Programming,简称DP,如果某⼀问题有很多重叠⼦问题,使⽤动态规划是最有效的。

leetcode-动态规划题目

1.斐波拉切数列

斐波拉切数列:1 1 2 3 5 8
斐波那契数,通常⽤ F(n) 表⽰,形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始,后⾯的每⼀项数字都是前⾯两项数字的和。也就是:
F(0) = 0,F(1) = 1
F(n) = F(n - 1) + F(n - 2),其中 n > 1
给你n ,请计算 F(n) 。

⽰例 1:
  输⼊:2
  输出:1
	解释:F(2) = F(1) + F(0) = 1 + 0 = 1

⽰例 2:
  输⼊:3
  输出:2
  解释:F(3) = F(2) + F(1) = 1 + 1 = 2

答案解析:

/*
数组解决:
时间复杂度:O(n)
空间复杂度:O(n)
*/
func demo1(n int) int {
	li := []int{1, 1}
	for i := 2; i <= n; i++ {
		num := li[i-1] + li[i-2]
		li = append(li, num)
	}
	return li[len(li)-1]
}

当然可以发现,我们只需要维护两个数值就可以了,不需要记录整个序列。demo2

/*
变量解决:
时间复杂度:O(n)
空间复杂度:O(1)
*/
func demo2(n int) int {
	num := 1
	num2 := 0
	if n == 0 {
		return num
	}
	for i := 0; i <= n; i++ {
		num, num2 = num2, num+num2
	}
	return num2
}

/*
递归解决:
时间复杂度:O(2^n)
空间复杂度:O(n),
*/
func demo3(n int) int {
	if n <= 2 {
		return n
	}
	return demo3(n-1) + demo3(n-2)
}

2.爬楼梯

题目:爬楼梯
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?


示例 1:
输入:n = 2
输出:2
解释:有两种方法可以爬到楼顶。
1. 1 阶 + 1 阶
2. 2 阶

示例 2:
输入:n = 3
输出:3
解释:有三种方法可以爬到楼顶。
1. 1 阶 + 1 阶 + 1 阶
2. 1 阶 + 2 阶
3. 2 阶 + 1 阶

答案:

/*
解析:
利用dp数组方法:
f(x)=f(x-1)+f(x-2)

时间复杂度:$O(n)
空间复杂度:$O(n)
*/
func climbStairs(n int) int {
	if n <= 1 {
		return n
	}
	dp := []int{0, 1, 2}

	for i := 3; i <= n; i++ {
		num := dp[i-1] + dp[i-2]
		dp = append(dp, num)
	}
	return dp[len(dp)-1]
}



/*
变量解决:优化空间复杂度
不用维护数组,维护需要的两个变量
时间复杂度:$O(n)
空间复杂度:$O(1)
*/
func climbStairs2(n int) int {
	if n <= 1 { 
		return n
	}
	dp1 := 1
	dp2 := 2
	for i := 3; i <= n; i++ {
		dp1, dp2 = dp2, dp1+dp2
	}
	return dp2
}

3.买卖股票最佳时机(一次买卖)

题目:买卖股票最佳时机,只有一次买卖机会

示例 1:
输入:[7,1,5,3,6,4]
输出:5
解释:在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
     注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格;同时,你不能在买入前卖出股票。

示例 2:
输入:prices = [7,6,4,3,1]
输出:0
解释:在这种情况下, 没有交易完成, 所以最大利润为 0。

答案:

func main() {
	li := []int{7, 1, 5, 3, 6, 4}
	fmt.Println(maxProfit(li))
}


/*
解析:
时间复杂度:O(n)
空间复杂度:O(1)
*/
func maxProfit(prices []int) int {
	maxNum := 10000000 //7,1,1,
	minNum := 0 //0,0,4,

	for i := 0; i < len(prices); i++ {
		maxNum = min(maxNum, prices[i])
		minNum = max(minNum, prices[i]-maxNum)
	}
	return minNum
}

func min(x, y int) int {
	if x > y {
		return y
	}
	return x
}

func max(x, y int) int {
	if x > y {
		return x
	}
	return y
}

4.买卖股票最佳时机2(多次买卖)

题目:
描述:给你一个整数数组 prices ,其中 prices[i] 表示某支股票第 i 天的价格。在每一天,你可以决定是否购买和/或出售股票。你在任何时候 最多 只能持有 一股 股票。你也可以先购买,然后在 同一天 出售。返回 你能获得的 最大利润 。

示例 1:
输入:prices = [7,1,5,3,6,4]
输出:7
解释:在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5 - 1 = 4 。
     随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6 - 3 = 3 。
     总利润为 4 + 3 = 7 。

示例 2:
输入:prices = [1,2,3,4,5]
输出:4
解释:在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5 - 1 = 4 。
     总利润为 4 。

示例 3:
输入:prices = [7,6,4,3,1]
输出:0
解释:在这种情况下, 交易无法获得正利润,所以不参与交易可以获得最大利润,最大利润为 0 。

答案:

/*
低买高买股票,最大收益
思路:
买入:1.当前的价格与明天价格比较,当天低比明天低就买入(如果手里没有股票),
卖出:1.当天比明天高就当天卖出(如果手里有股票)
     2.如果当天价格比明天低,且明天为最后一天,则明天(最后一天)卖出
[]
*/
func maxProfit1(prices []int) int {
	is := false
	buy := 0 //买入价格
	sell := 0 //卖出价格
	profit := 0 //总收益
	for i := 0; i < len(prices); i++ {
		if i == len(prices)-1 && is == true {
			//最后一天卖出
			sell = prices[i]
			profit += sell - buy
			break
		}

		if i == len(prices)-1 {
			break
		}

		if !is {
			//手上没有股票,准备买入
			if prices[i] <= prices[i+1] {
				//当天买入
				is = true       //已经买入
				buy = prices[i] //记录买入价格
				continue
			}
		} else {
			//手上有股票,准备卖出
			if prices[i] > prices[i+1] {
				//当天卖出
				is = false       //已经卖出
				sell = prices[i] //记录卖出价格
				profit += sell - buy
			}
		}
	}
	return profit
}

标签:示例,int,复杂度,func,prices,卖出,动态,规划,leetcode
From: https://www.cnblogs.com/guyouyin123/p/16772828.html

相关文章

  • 动态规划,三角形的最大路径和
    三角形的最大路径和#include<string>#include<iostream>#include<cctype>#include<algorithm>#include<vector>#include<unordered_map>#include<cstring>#......
  • leetcode-647. 回文子串
    647.回文子串回文子串是指这个子串正着读反着读读得内容都一样,比如aaa,有以下回文字串a,a,a,aa,,aa,aaa,字符虽然一样但不是同一个字符仍然被看作一个子串我们可以使用双......
  • leetcode-621. 任务调度器
    621.任务调度器假设有任务["A","A","A","B","B","B"],n=2,可以画图表示CPU的时间分配MT表示maxTime,这个任务列表中出现次数最大的任务数量,这里就是MT=3MC表示maxCou......
  • Leetcode 117 -- 树&&bfs
    题目描述填充每个节点的下一个节点题目要求我们填充每个节点的\(next\)指针,让它指向它的(同一层)右侧的节点,如果没有,指向$NULL,(初始时全部指向\(NULL\))。思路看到......
  • Leetcode 927 -- 思维
    题目描述三等分思路题目要求我们将源数组划分为三个连续的序列,即\([0,i],[i+1,j-1],[j,n-1]\),使得这三个序列的二进制所表示的数相等。首先,我们需要挖掘出一个性......
  • 洛谷 P2387 [NOI2014] 魔法森林 题解【动态加点 SPFA】
    题目大意给定一个由\(n\)个点\(m\)条边的无向图,每条边有权值\((a,b)\),求一条路径使这条路径上的\((a_{\max}+b_{\max})\)最小。思路正解应该是LCT动态维护MST......
  • leetcode 22 括号生成 js 实现
    22.括号生成难度中等数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合示例1:输入:n=3输出:["((()))","(()())","(()......
  • LeetCode 字符串相乘算法题解 All In One
    LeetCode字符串相乘算法题解AllInOnejs/ts实现字符串相乘jsbignumbermultiply/js大数相乘字符串相乘原理&图解LeetCode43.MultiplyStringsLee......
  • java---三个小案例--冒泡---动态扩容--将输入的字母中带x的置为null,不是x的依次向前
    三个案例1.动态录入往数组里录入n个数字,并用冒泡排序2.动态输入n个字母,并将输入的字母中带x的置为null,不是x的依次向前3.动态录入学生成绩并保存到数组中,每录入一个成绩......
  • LeetCode算法笔记 53. 最大子数组和
    给你一个整数数组nums,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。子数组是数组中的一个连续部分。示例1:输入:nums=[-2,1,-3,4,-1,2......