1
概览
背包问题可以大致分为三类,分别是:
- 背包组合问题
- True/False 问题
- 最大最小问题
其基础的背包问题一般由两个模型演变而来:
- 0-1 背包问题
- 完全背包问题
本文先研究 0-1 背包和完全背包,而后对其他问题进行研究。
例题索引
0-1 背包
问题 | 类型 | 递推公式 | 备注 |
---|---|---|---|
例题 LC474:1和0 | 0-1 背包最大最小值问题 | dp[i] = max(dp[i], dp[i-num] + 1) |
两个背包 |
例题 LC416:分割等和子集 | 0-1 背包True/False问题 | dp[i] = dp[i] or dp[i - num] |
|
例题 LC494:目标和 | 0-1 背包组合问题 | dp[i] += dp[i - num] |
|
例题 LC1049:最后一块石头的重量 III | 0-1 背包最大最小值问题 | dp[i] = max(dp[i], dp[i-stone] + stone) |
Summary
2024年9月9日更新:不要想那么多的模板,记住区间的开合关系即可,比如用左闭右开区间 [), 和 python 很像,则代码有几个注意点:
- left = 0, right = len(nums); 因为 right 取不到
- case 1: nums[mid] < target: left target mid right: 此时需要更新 right = mid, 因为取不到,不需要 mid - 1
- case 2: nums[mid] > target: left mid target right: 此时需要更新 left = mid + 1 不要重复取值
Summary
LCS 问题有很多的子问题,大致包括以下:
-
最长公共子串,要求子串在原字符串中是连续的
-
最长公共子序列
-
最大子序列
-
最长递增子序列
最长公共子串
暴力求解
def LCSubStr(str1, str2, m, n):
LCSuff = [[0 for i in range(n + 1)] for j in range(m + 1)]
# 最长公共子串的长度
result = 0
# str1 中的最后相同的位置
p = 0
for i in range(m + 1):
for j in range(n + 1):
if(i == 0 or j == 0):
LCSuff[i][j] = 0
elif(str1[i - 1] == str2[j - 1]):
LCSuff[i][j] = LCSuff[i-1][j-1] + 1
result = max(result, LCSuff[i][j])
p = i
else:
LCSuff[i][j] = 0
return str1[p - result:p], result
X = 'OldSite:GeeksforGeeks.org'
Y = 'NewSite:GeeksQuiz.com'
m = len(X)
n = len(Y)
print('Length of Longest Common Substring is',
LCSubStr(X, Y, m, n))
String
Python String
求 String 长度
C String
Problems
在算法中,字符串的操作和数组一样,都是很热门的考察点,这篇文章将总结一下常见的有关 string 的算法,方便查阅学习、总结。
判断两个字符串是否只相差一个字母
注意,针对已经排序的字符串,判断这两个字符串是否只相差一个字母(也就是说第二个字符串比第一个字符串多最后一个字母,如 abc
和 abcd
这种)。