Skip to content

Commit 648f284

Browse files
author
xiaolingtong@bilibili.com
committed
double sequence issue
1 parent db55c6e commit 648f284

File tree

6 files changed

+252
-0
lines changed

6 files changed

+252
-0
lines changed

src/com/blankj/hard/_115/Solution.kt

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package com.blankj.hard._115
2+
3+
import com.blankj.ext.print
4+
import kotlin.math.min
5+
6+
class Solution {
7+
fun numDistinct(s: String, t: String): Int {
8+
if (s.length < t.length) return 0
9+
val dp = Array(s.length + 1) { IntArray(t.length + 1) }
10+
for (i in s.indices) {
11+
dp[i][0] = 1
12+
}
13+
for (i in t.indices) {
14+
dp[0][i] = 0
15+
}
16+
dp[0][0] = 1
17+
for (i in s.indices) {
18+
for (j in 0 until min(i + 1, t.length)) {
19+
if (s[i] == t[j]) {
20+
dp[i + 1][j + 1] = dp[i][j] + dp[i][j + 1]
21+
} else {
22+
dp[i + 1][j + 1] = dp[i][j + 1]
23+
}
24+
}
25+
}
26+
return dp[s.length][t.length]
27+
}
28+
29+
fun numDistinctWithLessSpace(s: String, t: String): Int {
30+
if (s.length < t.length) return 0
31+
val dp = IntArray(t.length + 1)
32+
if (s.isNotEmpty()) {
33+
dp[0] = 1
34+
}
35+
for (i in s.indices) {
36+
for (j in min(i, t.length - 1) downTo 0) {
37+
if (s[i] == t[j]) {
38+
dp[j + 1] += dp[j]
39+
}
40+
}
41+
}
42+
return dp[t.length]
43+
}
44+
45+
}
46+
47+
fun main() {
48+
Solution().numDistinct("rabbbit", "rabbit").print()
49+
Solution().numDistinct("babgbag", "bag").print()
50+
}

src/com/blankj/hard/_132/Solution.kt

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package com.blankj.hard._132
2+
3+
import com.blankj.ext.print
4+
import kotlin.math.min
5+
6+
class Solution {
7+
fun minCut(s: String): Int {
8+
val isPal = Array(s.length) { BooleanArray(s.length) }
9+
for (right in s.indices) {
10+
for (left in 0..right) {
11+
if (s[right] == s[left] && (right - left <= 2 || isPal[left + 1][right - 1])) {
12+
isPal[left][right] = true
13+
}
14+
}
15+
}
16+
val dp = IntArray(s.length)
17+
for (i in s.indices) {
18+
if (isPal[0][i]) {
19+
dp[i] = 0
20+
} else {
21+
dp[i] = i
22+
for (j in 1..i) {
23+
if (isPal[j][i]) {
24+
dp[i] = min(dp[i], dp[j - 1] + 1)
25+
}
26+
}
27+
}
28+
}
29+
return dp.last()
30+
}
31+
}
32+
33+
fun main() {
34+
Solution().minCut("aab").print()
35+
Solution().minCut("a").print()
36+
Solution().minCut("ab").print()
37+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package com.blankj.medium._1143
2+
3+
import com.blankj.ext.print
4+
import kotlin.math.max
5+
6+
7+
class Solution {
8+
fun longestCommonSubsequence(text1: String, text2: String): Int {
9+
val len1 = text1.length
10+
val len2 = text2.length
11+
if (len1 < len2) {
12+
return longestCommonSubsequence(text2, text1)
13+
}
14+
val dp = Array<IntArray>(2) { IntArray(len2 + 1) }
15+
for (i in text1.indices) {
16+
for (j in text2.indices) {
17+
if (text1[i] == text2[j]) {
18+
dp[(i + 1) % 2][j + 1] = dp[i % 2][j] + 1
19+
} else {
20+
dp[(i + 1) % 2][j + 1] = max(dp[i % 2][j + 1], dp[(i + 1) % 2][j])
21+
}
22+
}
23+
}
24+
return dp[len1 % 2][len2]
25+
}
26+
}
27+
28+
fun main() {
29+
Solution().longestCommonSubsequence("abcde", "ace").print()
30+
Solution().longestCommonSubsequence("abc", "abc").print()
31+
Solution().longestCommonSubsequence("abc", "def").print()
32+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package com.blankj.medium._873
2+
3+
import com.blankj.ext.print
4+
import kotlin.math.max
5+
6+
7+
class Solution {
8+
fun lenLongestFibSubseq(arr: IntArray): Int {
9+
if (arr.isEmpty()) return 0
10+
val dp = Array(arr.size) { IntArray(arr.size) }
11+
var res = 2
12+
val map = arr.mapIndexed { index, i -> i to index }
13+
.associate { it }
14+
.toMutableMap()
15+
for (i in 1 until arr.size) {
16+
for (j in 0 until i) {
17+
val k = map.getOrDefault(arr[i] - arr[j], -1)
18+
dp[i][j] = if (k in 0 until j) dp[j][k] + 1 else 2
19+
res = max(res, dp[i][j])
20+
}
21+
}
22+
return if (res > 2) res else 0
23+
}
24+
}
25+
26+
fun main() {
27+
Solution().lenLongestFibSubseq(intArrayOf(1,2,3,4,5,6,7,8)).print()
28+
Solution().lenLongestFibSubseq(intArrayOf(1,3,7,11,12,14,18)).print()
29+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package com.blankj.medium._926
2+
3+
import com.blankj.ext.print
4+
import kotlin.math.min
5+
6+
7+
class Solution {
8+
fun minFlipsMonoIncr(s: String): Int {
9+
if (s.isEmpty()) return 0
10+
val dp = Array(2) { IntArray(2) }
11+
dp[0][0] = if (s[0] == '0') 0 else 1
12+
dp[1][0] = if (s[0] == '1') 0 else 1
13+
14+
for (i in 1 until s.length) {
15+
val prev0 = dp[0][(i - 1) % 2]
16+
val prev1 = dp[1][(i - 1) % 2]
17+
dp[0][i % 2] = prev0 + if (s[i] == '1') 1 else 0
18+
dp[1][i % 2] = min(prev1, prev0) + if (s[i] == '0') 1 else 0
19+
}
20+
return min(dp[0][s.lastIndex % 2], dp[1][s.lastIndex % 2])
21+
}
22+
}
23+
24+
fun main() {
25+
Solution().minFlipsMonoIncr("00110").print()
26+
Solution().minFlipsMonoIncr("010110").print()
27+
Solution().minFlipsMonoIncr("00011000").print()
28+
}

src/com/blankj/medium/_97/Solution.kt

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
package com.blankj.medium._97
2+
3+
import com.blankj.ext.print
4+
5+
class Solution {
6+
// 状态方程 dp[i][j] 表示 s1[0..i] 和 s2[0..j] 能不能交织成 s3[0..i+j+1]
7+
/** dp[i-1][j] s1[i] == s3[i+j+1]
8+
* dp[i][j] =
9+
* dp[i][j - 1] s2[i] == s3[i + j + 1]
10+
* 当 i == 0 或者 j == 0 时, i - 1 或者 j - 1 == -1, 意味着当其中一方变为空串了,只剩另一个数组,
11+
* 这时的 dp[i][j] 就取决于 非空的数组下标元素是否于 s3 下标相等的同时, 以及前一位 dp[i - 1][j - 1] 的值
12+
* 因为实际数据结构不存在 -1 下标, 故整体数组需要右移一格
13+
*/
14+
fun isInterleave(s1: String, s2: String, s3: String): Boolean {
15+
if (s1.length + s2.length != s3.length) return false
16+
// 因为数组不支持表示 -1 下标, 故整体右移一格
17+
val dp = Array(s1.length + 1) { BooleanArray(s2.length + 1) }
18+
dp[0][0] = true
19+
for (i in s1.indices) {
20+
dp[i + 1][0] = s1[i] == s3[i] && dp[i][0]
21+
}
22+
for (i in s2.indices) {
23+
dp[0][i + 1] = s2[i] == s3[i] && dp[0][i]
24+
}
25+
for (i in s1.indices) {
26+
for (j in s2.indices) {
27+
val ch1 = s1[i]
28+
val ch2 = s2[j]
29+
val ch3 = s3[i + j + 1]
30+
dp[i + 1][j + 1] = (ch1 == ch3 && dp[i][j + 1])
31+
|| (ch2 == ch3 && dp[i + 1][j])
32+
}
33+
}
34+
return dp[s1.length][s2.length]
35+
}
36+
37+
38+
fun isInterleaveWithLessSpace(s1: String, s2: String, s3: String): Boolean {
39+
if (s1.length + s2.length != s3.length) return false
40+
// 因为数组不支持表示 -1 下标, 故整体右移一格
41+
if (s1.length < s2.length) return isInterleaveWithLessSpace(s2, s1, s3)
42+
val dp = BooleanArray(s2.length + 1)
43+
dp[0] = true
44+
45+
for (i in s2.indices) {
46+
dp[i + 1] = s2[i] == s3[i] && dp[i]
47+
}
48+
// 二维转一维后, 逐行遍历并更新 dp 数组的值
49+
// dp[j] 相当于之前的 f(j, j)
50+
for (i in s1.indices) {
51+
dp[0] = s1[i] == s3[i] && dp[0]
52+
for (j in s2.indices) {
53+
val ch1 = s1[i]
54+
val ch2 = s2[j]
55+
val ch3 = s3[i + j + 1]
56+
dp[j + 1]= (ch1 == ch3 && dp[j + 1])
57+
|| (ch2 == ch3 && dp[j])
58+
}
59+
}
60+
return dp[s2.length]
61+
}
62+
}
63+
64+
fun main() {
65+
Solution().isInterleave(
66+
"aabcc",
67+
"dbbca",
68+
"aadbbcbcac"
69+
).print()
70+
Solution().isInterleave(
71+
"aabcc", "dbbca", "aadbbbaccc"
72+
).print()
73+
Solution().isInterleave(
74+
"", "", ""
75+
).print()
76+
}

0 commit comments

Comments
 (0)