动态规划
Vaccy Zhu
自律是解决人生问题最主要的工具,也是解决人生痛苦最重要的方法!
展开
-
监控二叉树-贪心968-python
无转载 2022-06-29 19:37:28 · 120 阅读 · 0 评论 -
最后一块石头的重量II-动态规划1049-python
可转化为01背包问题,sum为N,neg为dp[-1][-1]。转载 2022-06-21 12:47:29 · 83 阅读 · 0 评论 -
不相交的线-动态规划1035-python
没看答案。原创 2022-06-15 16:56:18 · 124 阅读 · 0 评论 -
买卖股票的最佳时机IV-动态规划188-python
没看答案,允许交易k次。labuladong版原创 2022-06-09 17:11:16 · 87 阅读 · 0 评论 -
买卖股票的最佳时机III-动态规划123-python
没看答案,可以交易最多两次。labuladong版原创 2022-06-09 17:05:36 · 99 阅读 · 0 评论 -
买卖股票的最佳时机含手续费-动态规划714-python
没看答案,可以交易无数次,但每次买入或卖出都需要支付手续费。labuladong版(超时)简化版(省略k)原创 2022-06-09 16:21:25 · 141 阅读 · 0 评论 -
最佳买卖股票时机含冷冻期-动态规划309-python
没看答案,可以交易无数次,但是卖出后的第二天不可以买入。labuladong版(超时)简化版(省略k)原创 2022-06-09 15:57:48 · 77 阅读 · 0 评论 -
最长递增子序列的个数-动态规划673-python
要用到两个动态规划数组,时间复杂度O(n^2),空间复杂度O(n)。class Solution: def findNumberOfLIS(self, nums: List[int]) -> int: ''' state: dp[i]表示以nums[i]结尾的最长递增子序列的长度 count[i]表示以nums[i]结尾的最长递增子序列的数量 basecase: 每遍历一个nums[i],dp[i]和count[i转载 2022-05-10 14:04:51 · 154 阅读 · 0 评论 -
分割回文串II-动态规划132-python
import sysclass Solution: def minCut(self, s: str) -> int: ''' state: dp[i]表示s[:i+1]的最少分割次数 basecase: [sys.maxsize] * n 用于min函数的比较 transfer: 考虑s[:i+1]的最后一个回文子串,假设其为s[j+1:i+1], 则dp[i] = min(dp[i], d转载 2022-05-08 15:48:10 · 133 阅读 · 0 评论 -
分割平衡字符串-贪心1221-python
没看答案,用两个变量need_R和need_L记录需要的R和L,当两者相等时即为一个平衡字符串,res+=1,两个变量归零。class Solution: def balancedStringSplit(self, s: str) -> int: need_R = need_L = 0 res = 0 for ch in s: if ch == 'R': need_L += 1原创 2022-05-06 15:43:32 · 460 阅读 · 0 评论 -
Dota2参议院-贪心649-python
没看答案,贪心思想。class Solution: def predictPartyVictory(self, senate: str) -> str: ''' 贪心思想胜利策略:优先ban后面出现的敌对方,如果后面没有敌对方,ban前面出现的敌对方,直到胜利。 ''' sen = list(senate) while True: num_R = num_D = 0 # 当前剩余的R o原创 2022-05-06 15:14:58 · 472 阅读 · 0 评论 -
最长回文子序列-动态规划516-python
没看答案。class Solution: def longestPalindromeSubseq(self, s: str) -> int: ''' state: dp[i][j]表示s[i:j]中的最长回文子序列 basecase: 先遍历列(从下到上),再遍历行(从左到右) transfer: i==j,dp[i][j]=1; i==j-1,若s[i]==s[j],则dp[i][j]=2,原创 2022-04-27 18:47:48 · 386 阅读 · 0 评论 -
回文子串-动态规划647-python
没看答案,双指针+传统判断回文串,用memo储存已经判断过的子串,防止重复判断,时间复杂度O(n^3)。from collections import defaultdictclass Solution: def countSubstrings(self, s: str) -> int: memo = defaultdict(bool) n = len(s) res = 0 def dfs(s, start, end):原创 2022-04-27 14:03:53 · 279 阅读 · 0 评论 -
两个字符串的删除操作-动态规划583-python
没看答案,只允许删除操作的编辑距离问题。class Solution: def minDistance(self, word1: str, word2: str) -> int: ''' state: dp[i][j]表示word1[:j]和word2[:i]相同所需的最小步数 basecase: word1或word2为空字符串时的最小步数,即dp数组的第一行和第一列 transfer: 若word1[j-1]与word2[i原创 2022-04-26 11:54:23 · 495 阅读 · 0 评论 -
不同的子序列-动态规划115-python
解决两个字符串的动态规划问题,一般都是用两个指针 i,j 分别指向两个字符串的最后,然后一步步往前走,缩小问题的规模。class Solution: def numDistinct(self, s: str, t: str) -> int: ''' state: dp[i][j]表示t[j:]在s[i:]中出现的次数 basecase: j=n时t为'',空字符串在任意字符串中出现次数均为1, 所以有dp[:转载 2022-04-25 19:54:53 · 91 阅读 · 0 评论 -
最长连续递增序列-动态规划674-python&c++
没看答案。class Solution: def findLengthOfLCIS(self, nums: List[int]) -> int: ''' state: dp[i]表示以元素nums[i]为结尾的数组的连续递增子序列长度 basecase: dp数组初始化每个元素都为1 transfer: dp[i] = dp[i-1]+1 如果nums[i-1] < nums[i] result: max(原创 2022-04-02 19:40:34 · 1103 阅读 · 0 评论 -
单词拆分-动态规划139-python&c++
没看答案,动态规划-完全背包问题。from collections import defaultdictclass Solution: def wordBreak(self, s: str, wordDict: List[str]) -> bool: ''' basecase: dp[0]=True表示背包重量为0时不拿物品也符合。 state: dp[i]表示s[0:i]能否拼接出来。 i可以理解为背包重量,原创 2022-03-31 11:21:20 · 998 阅读 · 0 评论 -
完全平方数-动态规划279
没看答案,动态规划-完全背包问题。import mathclass Solution: def numSquares(self, n: int) -> int: ''' basecase: 初始化只考虑1的情况 state: 由于int(sqrt(n))的的平方一定小于等于n,所以物品相当于candidate数组中的元素,背包重量为n dp[j]表示背包重量为j时的最少完全平方数 transfe原创 2022-03-30 18:43:22 · 107 阅读 · 0 评论 -
组合总和IV-动态规划377-python
先举个例子,nums = [1, 2, 3],target = 35.假设用1,2,3拼凑出35的总组合个数为y。我们可以考虑三种情况:(1)有效组合的末尾数字为1,这类组合的个数为 x1。我们把所有该类组合的末尾1去掉,那么不难发现,我们找到了一个子问题,x1即为在[1,2,3]中凑出35 - 1 = 34的总组合个数。因为我如果得到了和为34的所有组合,我只要在所有组合的最后面,拼接一个1,就得到了和为35且最后一个数字为1的组合个数了。(2)有效组合的末尾数字为2,这类组合的个数为 x2。我们把原创 2022-03-29 11:18:40 · 770 阅读 · 0 评论 -
零钱兑换II-动态规划518-python
动态规划,完全背包问题。class Solution: def change(self, amount: int, coins: List[int]) -> int: ''' basecase: dp[0][0] = 1 表示总金额为0时一个硬币也不拿是一种方式。 state: dp[i][j]表示总金额为j,硬币为coins[0:i]时的组合数。 transfer: 当总金额j小于当前硬币coins[i-1]时,肯定拿不了:d原创 2022-03-26 15:18:50 · 1058 阅读 · 0 评论 -
一和零-动态规划474-python
答案解析,可以转化为01背包问题,但因为有两个target,所以要用到三维dp数组。from collections import Counterclass Solution: def findMaxForm(self, strs: List[str], m: int, n: int) -> int: nums0 = [] nums1 = [] length = len(strs) for s in strs:转载 2022-03-26 10:37:08 · 77 阅读 · 0 评论 -
目标和-动态规划494-python
01背包问题,答案解析。class Solution: def findTargetSumWays(self, nums: List[int], target: int) -> int: # 公式推导和变量意义见答案解析。 diff = (sum(nums) - target) if diff < 0 or diff % 2 == 1: return 0 neg = (sum(nums)-targe转载 2022-03-24 20:42:19 · 101 阅读 · 0 评论 -
分割等和子集-动态规划416-python&c++
没看答案,暴力回溯法。class Solution: def canPartition(self, nums: List[int]) -> bool: if sum(nums) % 2 == 1: return False nums = sorted(nums) target = sum(nums) // 2 sumTrack = 0 flag = False def原创 2022-03-23 14:52:20 · 664 阅读 · 0 评论 -
整数划分-动态规划343-python
纯数学问题,答案解析。import mathclass Solution: def integerBreak(self, n: int) -> int: ''' math.pow()时间复杂度为O(1) 而 ** 和 pow()时间复杂度为O(logn) ''' if n <= 3: return n-1 a = n // 3 b原创 2022-03-19 17:57:03 · 629 阅读 · 0 评论 -
不同的二叉搜索树-动态规划96-python
答案解析class Solution: def numTrees(self, n: int) -> int: dp = [0] * (n+1) dp[0] = dp[1] = 1 for i in range(2, n+1): for j in range(1, i+1): dp[i] += dp[j-1] * dp[i-j] return dp[n]转载 2022-03-20 10:47:32 · 91 阅读 · 0 评论 -
不同路径II-动态规划63-python
没看答案。class Solution: def uniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int: ''' basecase:dptable的第一行和第一列中出现1的格子之前的都为1,之后的都为0 state:dp[i][j]表示到达网格(i, j)有多少条路经 transfer:如果网格(i, j)为1, dp[i][j] = 0原创 2022-03-18 11:46:00 · 930 阅读 · 0 评论 -
使用最小花费爬楼梯-动态规划746-python
没看答案。class Solution: def minCostClimbingStairs(self, cost: List[int]) -> int: ''' basecase:dp[0] = dp[1] = 0,因为cost的长度大于等于2 state:dp[i]表示有i个台阶时的最低花费,台阶从0开始算 transfer:dp[i] = min(dp[i-2]+cost[i-2], dp[i-1]+cost[i-1])原创 2022-03-17 16:41:19 · 589 阅读 · 0 评论 -
加油站-贪心134-python
class Solution: def canCompleteCircuit(self, gas, cost): # 如果总加油量小于总耗油量,那一定无法行驶一周 # 反之则一定可以行驶一周 if sum(gas) < sum(cost): return -1 ''' 算法思路:如果x到不了y+1(但能到y),那么从x到y的任一点出发都不可能到达y+1。 因原创 2022-03-16 17:21:54 · 1384 阅读 · 0 评论 -
划分字母区间-贪心763-python&c++
答案解析from collections import defaultdictclass Solution: def partitionLabels(self, s: str) -> List[int]: end_pos = defaultdict(int) start, end = 0, 0 res = [] # 记录每个字母的最后出现位置 for i, ch1 in enumerate(s):原创 2022-03-15 10:37:11 · 423 阅读 · 0 评论 -
用最少数量的箭引爆气球-贪心452-python
没看答案,和重叠区间问题类似,只不过按照题意,区间首尾相接也算重叠。class Solution: def findMinArrowShots(self, points: List[List[int]]) -> int: points = sorted(points, key=lambda x:[x[1], x[0]]) count = 1 end = points[0][1] for balloon in points:原创 2022-03-14 09:44:20 · 597 阅读 · 0 评论 -
跳跃游戏II-贪心45-python&c++
答案解析class Solution: def jump(self, nums: List[int]) -> int: n = len(nums) res, furthest = 0, 0 end = 0 for i in range(n-1): furthest = max(i + nums[i], furthest) if i == end:原创 2022-03-11 12:32:47 · 94 阅读 · 0 评论 -
跳跃游戏-贪心55-python&c++
答案解析class Solution: def canJump(self, nums: List[int]) -> bool: furthest, n = 0, len(nums) for i in range(n): if i <= furthest: furthest = max(i+nums[i], furthest) if furthest >= n-1:原创 2022-03-10 14:51:02 · 151 阅读 · 0 评论 -
根据身高重建队列-贪心406-python
没看答案,遍历people中的每个人,每个人都按他们的要求排好队。class Solution: def reconstructQueue(self, people: List[List[int]]) -> List[List[int]]: # 按题意的ki从低到高排,ki相同的再按身高hi从高到低排 # 这样排序是为了方便后续的插入算法 people = sorted(people, key=lambda x:(x[1],-x[0]))原创 2022-03-10 10:50:27 · 783 阅读 · 0 评论 -
分发糖果-贪心135-python
答案解析class Solution: def candy(self, ratings: List[int]) -> int: n = len(ratings) res = 1 inc, dec = 1, 0 preNum = 1 for i in range(1, n): if ratings[i] >= ratings[i-1]:转载 2022-03-09 22:33:27 · 303 阅读 · 0 评论 -
单调递增的数字-贪心738-python
没看答案。class Solution: def monotoneIncreasingDigits(self, n: int) -> int: def check(num): # 从高位到低位提取num的每一位数字 ls = [] while num != 0: ls.append(num%10) num = num // 10原创 2022-03-09 17:51:26 · 703 阅读 · 0 评论 -
摆动序列-贪心376-python
没看答案,时间复杂度O(n),空间复杂度O(1),但实现过于复杂不推荐。class Solution: def wiggleMaxLength(self, nums: List[int]) -> int: res = n = len(nums) if n == 1: return res i, j = 0, 1 if nums[1]-nums[0] > 0: pre = 1原创 2022-03-08 18:08:33 · 591 阅读 · 0 评论 -
柠檬水找零-贪心860-python
没看答案,直接按题意分情况讨论即可。from collections import defaultdictclass Solution: def lemonadeChange(self, bills: List[int]) -> bool: cash = defaultdict(int) for csh in bills: cash[csh] += 1 if csh == 10:原创 2022-03-08 10:29:36 · 436 阅读 · 0 评论 -
K次取反后最大化的数组和-贪心1005-python
没看答案:每次取反前要先排序,是因为取反最小的数字是局部最优解,取反次数用完后极为全局最优解。当数组只有0和正数时,可以无视次数,因为可以重复取反0。class Solution: def largestSumAfterKNegations(self, nums: List[int], k: int) -> int: for i in range(k): nums = sorted(nums) if nums[0] == 0:原创 2022-03-07 11:10:11 · 266 阅读 · 0 评论 -
分发饼干-贪心455-python
没看答案,利用贪心思想:从大尺寸饼干开始分发,优先满足大胃口的孩子。class Solution: def findContentChildren(self, g: List[int], s: List[int]) -> int: res = 0 g, s = sorted(g), sorted(s) i, j = len(g)-1, len(s)-1 while i >= 0 and j >= 0:原创 2022-03-07 10:27:50 · 550 阅读 · 0 评论 -
无重叠区间-贪心435-python
贪心算法可以认为是动态规划算法的一个特例,相比动态规划,使用贪心算法需要满足更多的条件(贪心选择性质),但是效率比动态规划要高。什么是贪心选择性质呢,简单说就是:每一步都做出一个局部最优的选择,最终的结果就是全局最优。注意哦,这是一种特殊性质,其实只有一小部分问题拥有这个性质。pythonclass Solution: def eraseOverlapIntervals(self, intervals: List[List[int]]): intervals = sorte.原创 2021-08-10 20:19:19 · 154 阅读 · 0 评论