动态规划难不倒我
一:股票(一次交易):
假设你有一个数组,其中第 i 个元素是股票在第i 天的价格。
你有一次买入和卖出的机会。(只有买入了股票以后才能卖出)。请你设计一个算法来计算可以获得的最大收益。
题目翻译: 给你一个数组, 找到两个从左到右,右面减左面最大的数。
思路: 从左到右依次遍历, 每次用一个变量记录最小值,另外一个变量记录,收益最大。每次遍历的时候看看当前值-最小值是不是比原来的最大收益还大,如果是则更新最大收益。
class Solution:
def maxProfit(self , prices ):
min_num = prices[0]
Max_pre = 0
length = len(prices)
for i in range(1, length):
if prices[i] < min_num:
min_num = prices[i]
if prices[i] - min_num > Max_pre:
Max_pre = prices[i] - min_num
return Max_pre
二:子数组的最大累加和:
给定一个数组arr,返回子数组的最大累加和
例如,arr = [1, -2, 3, 5, -2, 6, -1],所有子数组中,[3, 5, -2, 6]可以累加出最大的和12,所以返回12.
题目保证没有全为负数的数据
[要求]时间复杂度为O(n),空间复杂度为O(1)
思路: 首先最大累加和是没有负数的,因为大不了我不加,就是0。
思考一个问题: 到某个点的最大累加和应该怎么求?
A点的最大累加和 = A点之前的最大累加和 + A点的值,如果发现加完是个负数,说明A点还不如不要呢,此时A点的最大累加和就是0。
因此思路就明确了,我们可以使用一个变量计算当前点的最大累加和。然后使用另外一个变量存储整个过程的最大累加和。当遍历一个结点的时候,我们先计算当前点的最大累加和,如果是负数,则当前点的最大累加和就是0,如果不是负数,那么当前点的最大累加和与总的最大累加和相比,如果大于总的累加和,则更新总的累加和,最后返回总的累加和就可以了。
class Solution:
def maxsumofSubarray(self , arr ):
max_flag = arr[0]
res = arr[0]
for i in range(1, len(arr)):
max_flag += arr[i]
max_flag = max(0, max_flag)
res = max(max_flag, res)
return res
三:连续子数组的最大和:
输入一个整型数组,数组里有正数也有负数。数组中的一个或连续多个整数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为 O(n).
class Solution:
def FindGreatestSumOfSubArray(self, array):
a, dp = array[0], []
for i in array[1:]:
a = max(a + i, i)
dp.append(a)
return max(dp)
四:求路径:
思路: 对于起点的那一行,那一列都是只有一条路径,则全部初始化成1, 而对于中间的路径都等于左边路径数目+上面路径数目。最终返回最右下角的值即可。
class Solution:
def uniquePaths(self , m , n ):
dp = [[0]*n]*m
for i in range(m):
dp[i][0] = 1
for j in range(n):
dp[0][j] = 1
for i in range(1, m):
for j in range(1, n):
dp[i][j] = dp[i-1][j] + dp[i][j-1]
return dp[m-1][n-1];
五:换钱的最少货币数:
给定数组arr,arr中所有的值都为正整数且不重复。每个值代表一种面值的货币,每种面值的货币可以使用任意张,再给定一个aim,代表要找的钱数,求组成aim的最少货币数。
如果无解,请返回-1.
【要求】
时间复杂度O(n \times aim)O(n×aim),空间复杂度On。
class Solution:
def minMoney(self , arr , aim ):
dp = [aim + 1]*(aim +1) # 把dp数组定义绝对大
dp[0] = 0 # 总钱数是0的时候所需的货币数肯定是0
for i in range(1, aim + 1):#遍历目标值
for j in arr: # 遍历钱数
if j <= i:# 如果可以换
dp[i] = min(dp[i], dp[i-j]+1)
# 没有钱可以兑换
if dp[aim] > aim:
return -1
else:
return dp[aim]