57
57
58
58
** 方法一:动态规划**
59
59
60
- 定义 ` dp [i][j]` 表示 ` text1[0:i-1] ` 和 ` text2[0:j-1] ` 的最长公共子序列(闭区间) 。
60
+ 我们定义 $f [ i] [ j ] $ 表示 $ text1$ 的前 $i$ 个字符和 $ text2$ 的前 $j$ 个字符的最长公共子序列的长度。那么答案为 $f [ m ] [ n ] $,其中 $m$ 和 $n$ 分别为 $text1$ 和 $text2$ 的长度 。
61
61
62
- 递推公式如下 :
62
+ 如果 $text1$ 的第 $i$ 个字符和 $text2$ 的第 $j$ 个字符相同,则 $f [ i ] [ j ] = f [ i - 1 ] [ j - 1 ] + 1$;如果 $text1$ 的第 $i$ 个字符和 $text2$ 的第 $j$ 个字符不同,则 $f [ i ] [ j ] = max(f [ i - 1 ] [ j ] , f [ i ] [ j - 1 ] )$。即状态转移方程为 :
63
63
64
- ![ ] ( https://fastly.jsdelivr.net/gh/doocs/leetcode@main/solution/1100-1199/1143.Longest%20Common%20Subsequence/images/CodeCogsEqn.gif )
64
+ $$
65
+ f[i][j] =
66
+ \begin{cases}
67
+ f[i - 1][j - 1] + 1, & text1[i - 1] = text2[j - 1] \\
68
+ max(f[i - 1][j], f[i][j - 1]), & text1[i - 1] \neq text2[j - 1]
69
+ \end{cases}
70
+ $$
65
71
66
- 时间复杂度: $O(mn)$ 。
72
+ 时间复杂度 $O(m \times n)$,空间复杂度 $O(m \times n)$。其中 $m$ 和 $n$ 分别为 $text1$ 和 $text2$ 的长度 。
67
73
68
74
<!-- tabs:start -->
69
75
75
81
class Solution :
76
82
def longestCommonSubsequence (self , text1 : str , text2 : str ) -> int :
77
83
m, n = len (text1), len (text2)
78
- dp = [[0 ] * (n + 1 ) for _ in range (m + 1 )]
84
+ f = [[0 ] * (n + 1 ) for _ in range (m + 1 )]
79
85
for i in range (1 , m + 1 ):
80
86
for j in range (1 , n + 1 ):
81
87
if text1[i - 1 ] == text2[j - 1 ]:
82
- dp [i][j] = dp [i - 1 ][j - 1 ] + 1
88
+ f [i][j] = f [i - 1 ][j - 1 ] + 1
83
89
else :
84
- dp [i][j] = max (dp [i - 1 ][j], dp [i][j - 1 ])
85
- return dp[ - 1 ][ - 1 ]
90
+ f [i][j] = max (f [i - 1 ][j], f [i][j - 1 ])
91
+ return f[m][n ]
86
92
```
87
93
88
94
### ** Java**
@@ -93,17 +99,17 @@ class Solution:
93
99
class Solution {
94
100
public int longestCommonSubsequence (String text1 , String text2 ) {
95
101
int m = text1. length(), n = text2. length();
96
- int [][] dp = new int [m + 1 ][n + 1 ];
102
+ int [][] f = new int [m + 1 ][n + 1 ];
97
103
for (int i = 1 ; i <= m; ++ i) {
98
104
for (int j = 1 ; j <= n; ++ j) {
99
105
if (text1. charAt(i - 1 ) == text2. charAt(j - 1 )) {
100
- dp [i][j] = dp [i - 1 ][j - 1 ] + 1 ;
106
+ f [i][j] = f [i - 1 ][j - 1 ] + 1 ;
101
107
} else {
102
- dp [i][j] = Math . max(dp [i - 1 ][j], dp [i][j - 1 ]);
108
+ f [i][j] = Math . max(f [i - 1 ][j], f [i][j - 1 ]);
103
109
}
104
110
}
105
111
}
106
- return dp [m][n];
112
+ return f [m][n];
107
113
}
108
114
}
109
115
```
@@ -115,16 +121,18 @@ class Solution {
115
121
public:
116
122
int longestCommonSubsequence(string text1, string text2) {
117
123
int m = text1.size(), n = text2.size();
118
- vector<vector<int >> dp(m + 1, vector<int >(n + 1));
124
+ int f[ m + 1] [ n + 1 ] ;
125
+ memset(f, 0, sizeof f);
119
126
for (int i = 1; i <= m; ++i) {
120
127
for (int j = 1; j <= n; ++j) {
121
- if (text1[ i - 1] == text2[ j - 1] )
122
- dp[ i] [ j ] = dp[ i - 1] [ j - 1 ] + 1;
123
- else
124
- dp[ i] [ j ] = max(dp[ i - 1] [ j ] , dp[ i] [ j - 1 ] );
128
+ if (text1[ i - 1] == text2[ j - 1] ) {
129
+ f[ i] [ j ] = f[ i - 1] [ j - 1 ] + 1;
130
+ } else {
131
+ f[ i] [ j ] = max(f[ i - 1] [ j ] , f[ i] [ j - 1 ] );
132
+ }
125
133
}
126
134
}
127
- return dp [ m] [ n ] ;
135
+ return f [ m] [ n ] ;
128
136
}
129
137
};
130
138
```
@@ -134,20 +142,20 @@ public:
134
142
```go
135
143
func longestCommonSubsequence(text1 string, text2 string) int {
136
144
m, n := len(text1), len(text2)
137
- dp := make([][]int, m+1)
138
- for i := 0; i <= m; i++ {
139
- dp [i] = make([]int, n+1)
145
+ f := make([][]int, m+1)
146
+ for i := range f {
147
+ f [i] = make([]int, n+1)
140
148
}
141
149
for i := 1; i <= m; i++ {
142
150
for j := 1; j <= n; j++ {
143
151
if text1[i-1] == text2[j-1] {
144
- dp [i][j] = dp [i-1][j-1] + 1
152
+ f [i][j] = f [i-1][j-1] + 1
145
153
} else {
146
- dp [i][j] = max(dp [i-1][j], dp [i][j-1])
154
+ f [i][j] = max(f [i-1][j], f [i][j-1])
147
155
}
148
156
}
149
157
}
150
- return dp [m][n]
158
+ return f [m][n]
151
159
}
152
160
153
161
func max(a, b int) int {
@@ -169,17 +177,17 @@ func max(a, b int) int {
169
177
var longestCommonSubsequence = function (text1 , text2 ) {
170
178
const m = text1 .length ;
171
179
const n = text2 .length ;
172
- const dp = new Array ( m + 1 ). fill ( 0 ). map (() => new Array (n + 1 ).fill (0 ));
180
+ const f = Array . from ({ length : m + 1 }, () => Array (n + 1 ).fill (0 ));
173
181
for (let i = 1 ; i <= m; ++ i) {
174
182
for (let j = 1 ; j <= n; ++ j) {
175
183
if (text1[i - 1 ] == text2[j - 1 ]) {
176
- dp [i][j] = dp [i - 1 ][j - 1 ] + 1 ;
184
+ f [i][j] = f [i - 1 ][j - 1 ] + 1 ;
177
185
} else {
178
- dp [i][j] = Math .max (dp [i - 1 ][j], dp [i][j - 1 ]);
186
+ f [i][j] = Math .max (f [i - 1 ][j], f [i][j - 1 ]);
179
187
}
180
188
}
181
189
}
182
- return dp [m][n];
190
+ return f [m][n];
183
191
};
184
192
```
185
193
@@ -189,17 +197,17 @@ var longestCommonSubsequence = function (text1, text2) {
189
197
function longestCommonSubsequence(text1 : string , text2 : string ): number {
190
198
const m = text1 .length ;
191
199
const n = text2 .length ;
192
- const dp = Array .from ({ length: m + 1 }, () => Array (n + 1 ).fill (0 ));
200
+ const f = Array .from ({ length: m + 1 }, () => Array (n + 1 ).fill (0 ));
193
201
for (let i = 1 ; i <= m ; i ++ ) {
194
202
for (let j = 1 ; j <= n ; j ++ ) {
195
203
if (text1 [i - 1 ] === text2 [j - 1 ]) {
196
- dp [i ][j ] = dp [i - 1 ][j - 1 ] + 1 ;
204
+ f [i ][j ] = f [i - 1 ][j - 1 ] + 1 ;
197
205
} else {
198
- dp [i ][j ] = Math .max (dp [i - 1 ][j ], dp [i ][j - 1 ]);
206
+ f [i ][j ] = Math .max (f [i - 1 ][j ], f [i ][j - 1 ]);
199
207
}
200
208
}
201
209
}
202
- return dp [m ][n ];
210
+ return f [m ][n ];
203
211
}
204
212
```
205
213
@@ -210,17 +218,38 @@ impl Solution {
210
218
pub fn longest_common_subsequence (text1 : String , text2 : String ) -> i32 {
211
219
let (m , n ) = (text1 . len (), text2 . len ());
212
220
let (text1 , text2 ) = (text1 . as_bytes (), text2 . as_bytes ());
213
- let mut dp = vec! [vec! [0 ; n + 1 ]; m + 1 ];
221
+ let mut f = vec! [vec! [0 ; n + 1 ]; m + 1 ];
214
222
for i in 1 ..= m {
215
223
for j in 1 ..= n {
216
- dp [i ][j ] = if text1 [i - 1 ] == text2 [j - 1 ] {
217
- dp [i - 1 ][j - 1 ] + 1
224
+ f [i ][j ] = if text1 [i - 1 ] == text2 [j - 1 ] {
225
+ f [i - 1 ][j - 1 ] + 1
226
+ } else {
227
+ f [i - 1 ][j ]. max (f [i ][j - 1 ])
228
+ }
229
+ }
230
+ }
231
+ f [m ][n ]
232
+ }
233
+ }
234
+ ```
235
+
236
+ ### ** C#**
237
+
238
+ ``` cs
239
+ public class Solution {
240
+ public int LongestCommonSubsequence (string text1 , string text2 ) {
241
+ int m = text1 .Length , n = text2 .Length ;
242
+ int [,] f = new int [m + 1 , n + 1 ];
243
+ for (int i = 1 ; i <= m ; ++ i ) {
244
+ for (int j = 1 ; j <= n ; ++ j ) {
245
+ if (text1 [i - 1 ] == text2 [j - 1 ]) {
246
+ f [i , j ] = f [i - 1 , j - 1 ] + 1 ;
218
247
} else {
219
- dp [ i - 1 ][ j ] . max ( dp [ i ][ j - 1 ])
248
+ f [ i , j ] = Math . Max ( f [ i - 1 , j ], f [ i , j - 1 ]);
220
249
}
221
250
}
222
251
}
223
- dp [ m ][ n ]
252
+ return f [ m , n ];
224
253
}
225
254
}
226
255
```
0 commit comments