动态规划算法python_LeetCode in python--动态规划

这部分是动态规划的算法题。

给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。

示例 1:

输入: "babad"

输出: "bab"

注意: "aba" 也是一个有效答案。

示例 2:

输入: "cbbd"

输出: "bb"

思路

动态规划的思想,比如CABAC,如果只有一个字符‘B’,那么一定是回文的,然后看B两边,如果“ABA”两边相同,那么是回文的;再看“ABA”的两边。一直到左右两边不相等,或者溢出。和之前存储的回文串长度比较。

考虑示例1和示例2两种情况。

代码

class Solution(object):

def longestPalindrome(self, s):

""":type s: str:rtype: str"""

palindrome = ""

for i in range(len(s)):

len1 = len(self.getPalindrome(s, i, i))

if len1 > len(palindrome):

palindrome = self.getPalindrome(s, i, i)

len2 = len(self.getPalindrome(s, i, i+1))

if len2 > len(palindrome):

palindrome = self.getPalindrome(s, i, i+1)

return palindrome

def getPalindrome(self, s, l, r):

while l >= 0 and r < len(s) and s[l] == s[r]:

l -= 1

r += 1

return s[l+1 : r]

给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

示例:

输入: [-2,1,-3,4,-1,2,1,-5,4],

输出: 6

解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。

思路

如果数组里所有的整数都是负数,那么选择最大的数即可,因为越累加越小。

正负数都有的情况,需要两个变量,一个是global_max,从全局来看,每次最大的是什么组合,另一个是local_max,和global_max相比,更新global_max。

代码

class Solution(object):

def maxSubArray(self, nums):

""":type nums: List[int]:rtype: int"""

if max(nums) < 0:

return max(nums)

local_max, global_max = 0, 0

for i in nums:

local_max = max(0, local_max + i)

global_max = max(global_max, local_max)

return global_max

一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。

机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。

问总共有多少条不同的路径?

例如,上图是一个7 x 3 的网格。有多少可能的路径?

说明:m 和 n 的值均不超过 100。

示例 1:

输入: m = 3, n = 2

输出: 3

解释:

从左上角开始,总共有 3 条路径可以到达右下角。

1. 向右 -> 向右 -> 向下

2. 向右 -> 向下 -> 向右

3. 向下 -> 向右 -> 向右

示例 2:

输入: m = 7, n = 3

输出: 28

思路

动态规划问题,首先一行一列的情况下,只有一种走法;其他情况=它上面的格子的走法数量+它左边格子的走法数量

代码

假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

注意:给定 n 是一个正整数。

示例 1:

输入: 2

输出: 2

解释: 有两种方法可以爬到楼顶。

1. 1 阶 + 1 阶

2. 2 阶

示例 2:

输入: 3

输出: 3

解释: 有三种方法可以爬到楼顶。

1. 1 阶 + 1 阶 + 1 阶

2. 1 阶 + 2 阶

3. 2 阶 + 1 阶

思路

典型的动态规划问题,对于第n阶台阶来说,有两种办法,一种是爬一个台阶,到第n-1阶;第二种是爬两个台阶,到第n-2阶。

得出动态规划递推式:

代码

class Solution(object):

def climbStairs(self, n):

""":type n: int:rtype: int"""

if n == 1: return 1

if n == 2: return 2

result = [1, 2]

for i in range(2,n):

result.append(result[i-1] + result[i-2])

return result[-1]

给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。

如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润。

注意你不能在买入股票前卖出股票。

示例1:

输入: [7,1,5,3,6,4]

输出: 5

解释: 在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。

注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格。

示例2:

输入: [7,6,4,3,1]

输出: 0

解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。

思路:

一次循环,在价格最低的时候买入,在价格最高的时候卖出,将最大的利润保存下来。

代码:

class Solution(object):

def maxProfit(self, prices):

""":type prices: List[int]:rtype: int"""

if not prices: return 0

max_prices = 0

min_prices = prices[0]

for i in prices:

min_prices = min(min_prices, i)

max_prices = max(max_prices, i-min_prices)

return max_prices

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

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

示例1:

输入: [1,2,3,1]

输出: 4

解释: 偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。

偷窃到的最高金额 = 1 + 3 = 4 。

示例2:

输入: [2,7,9,3,1]

输出: 12

解释: 偷窃 1 号房屋 (金额 = 2), 偷窃 3 号房屋 (金额 = 9),接着偷窃 5 号房屋 (金额 = 1)。

偷窃到的最高金额 = 2 + 9 + 1 = 12 。

思路

动态规划思想

当前最大的累计收益= max(前一家的收益,前前一家的收益加上当前的收益)

状态转移方程: dp[i] = max(dp[i-1], dp[i-2]+nums[i])

代码

class Solution(object):

def rob(self, nums):

""":type nums: List[int]:rtype: int"""

n = len(nums)

if n == 0:

return 0

if n == 1:

return nums[0]

p = nums[0]

q = max(nums[0],nums[1])

for i in range(2,n):

next_ = max(p+nums[i],q)

p,q = q, next_

return q

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值