91.粉刷房子
思路:动态规划
92.翻转字符
思路:动态规划
93.最长斐波那契数列
思路:从暴力的角度去遍历,可以从两层循环遍历,通过map去判断第三个位置的数是否存在。
94.最少回文分割
思路:抽象dp
func minCut(s string) int {
is := make([][]bool, len(s))
for i := 0; i < len(s); i++ {
is[i] = make([]bool, len(s))
for j := 0; j < len(s); j++ {
is[i][j] = true
}
}
for i := len(s) - 2; i >= 0; i-- {
for j := i + 1; j < len(s); j++ {
is[i][j] = s[i] == s[j] && is[i+1][j-1]
}
}
f := make([]int, len(s))
for i := 0; i < len(s); i++ {
if is[0][i] { // 如果0-i是回文串就不必考虑了
continue
}
f[i] = math.MaxInt32
for j := 0; j < i; j++ {
if f[j]+1 < f[i] && is[j+1][i] {
f[i] = f[j] + 1
}
}
}
return f[len(s)-1]
}
95.最长公共子序列
思路:抽象dp,二维dp
96.字符串交织
思路:抽象dp,注意喝95题的区别,都是dp问题。
97.子序列的数目
思路:抽象二维dp
dfs+回忆录, dfs func( i , j int)表示从i,j出发走到末尾匹配有多少种可能。
func numDistinct(s string, t string) int {
visited := make([][]int , len(s))
for i := 0 ; i < len(s); i++{
visited[i] = make([]int , len(t))
}
var dfs func( i , j int)int
dfs = func ( i , j int)int {
if j == len(t){
return 1
}
if i == len(s){
return 0
}
if visited[i][j] != 0{
return visited[i][j]
}
res := 0
res += dfs(i + 1 , j)
if s[i] == t[j] {
res += dfs(i + 1 , j + 1 )
}
visited[i][j] = res
return res
}
return dfs(0 , 0 )
}
98.路径的数目
思路:简单二维dp
99.最小路径之和
思路:简单二维dp
100.三角形中最小路径之和
思路:简单dp