1+ //////////////////////////////////////////////////////////////////////////////
2+ // 1D Dynamic Programming
3+ // Time: O(n*m)
4+ // Space: O(m)
5+ //////////////////////////////////////////////////////////////////////////////
6+
17/**
28 * @param {string } s1
39 * @param {string } s2
@@ -21,33 +27,27 @@ function isInterleave(s1, s2, s3) {
2127 ) ;
2228 }
2329
24- const seen = new Array ( l1 + 1 ) . fill ( )
25- . map ( ( ) => new Array ( l2 + 1 ) ) ;
26- return checkStrings ( ) ;
30+ const seen = new Array ( l2 + 1 ) ;
31+ seen [ l2 ] = true ;
2732
28- /**
29- * @param {number= } i = `0`
30- * @param {number= } j = `0`
31- * @param {number= } k = `0`
32- * @return {boolean }
33- */
34- function checkStrings ( i = 0 , j = 0 , k = 0 ) {
35- return k === l3 || (
36- seen [ i ] [ j ] !== undefined
37- ? seen [ i ] [ j ]
38- : seen [ i ] [ j ] = (
39- i < l1
40- && s1 [ i ] === s3 [ k ]
41- && checkStrings ( i + 1 , j , k + 1 )
42- ) || (
43- j < l2
44- && s2 [ j ] === s3 [ k ]
45- && checkStrings ( i , j + 1 , k + 1 )
46- )
47- ) ;
33+ for ( let i = l2 - 1 ; i >= 0 ; -- i ) {
34+ seen [ i ] = seen [ i + 1 ] && s2 [ i ] === s3 [ l1 + i ] ;
4835 }
36+ for ( let i = l1 - 1 ; i >= 0 ; -- i ) {
37+ for ( let j = l2 ; j >= 0 ; -- j ) {
38+ seen [ j ] = ( seen [ j ] && s1 [ i ] === s3 [ i + j ] )
39+ || ( j !== l2 && seen [ j + 1 ] && s2 [ j ] === s3 [ i + j ] ) ;
40+ }
41+ }
42+ return seen [ 0 ] ;
4943}
5044
45+ //////////////////////////////////////////////////////////////////////////////
46+ // 2D Dynamic Programming
47+ // Time: O(n*m)
48+ // Space: O(n*m)
49+ //////////////////////////////////////////////////////////////////////////////
50+
5151/**
5252 * @param {string } s1
5353 * @param {string } s2
@@ -90,6 +90,12 @@ function isInterleave(s1, s2, s3) {
9090 return seen [ 0 ] [ 0 ] ;
9191}
9292
93+ //////////////////////////////////////////////////////////////////////////////
94+ // Depth First Search Recursion With Memoization
95+ // Time: O(n*m)
96+ // Space: O(n*m)
97+ //////////////////////////////////////////////////////////////////////////////
98+
9399/**
94100 * @param {string } s1
95101 * @param {string } s2
@@ -113,17 +119,29 @@ function isInterleave(s1, s2, s3) {
113119 ) ;
114120 }
115121
116- const seen = new Array ( l2 + 1 ) ;
117- seen [ l2 ] = true ;
122+ const seen = new Array ( l1 + 1 ) . fill ( )
123+ . map ( ( ) => new Array ( l2 + 1 ) ) ;
124+ return checkStrings ( ) ;
118125
119- for ( let i = l2 - 1 ; i >= 0 ; -- i ) {
120- seen [ i ] = seen [ i + 1 ] && s2 [ i ] === s3 [ l1 + i ] ;
121- }
122- for ( let i = l1 - 1 ; i >= 0 ; -- i ) {
123- for ( let j = l2 ; j >= 0 ; -- j ) {
124- seen [ j ] = ( seen [ j ] && s1 [ i ] === s3 [ i + j ] )
125- || ( j !== l2 && seen [ j + 1 ] && s2 [ j ] === s3 [ i + j ] ) ;
126- }
126+ /**
127+ * @param {number= } i = `0`
128+ * @param {number= } j = `0`
129+ * @param {number= } k = `0`
130+ * @return {boolean }
131+ */
132+ function checkStrings ( i = 0 , j = 0 , k = 0 ) {
133+ return k === l3 || (
134+ seen [ i ] [ j ] !== undefined
135+ ? seen [ i ] [ j ]
136+ : seen [ i ] [ j ] = (
137+ i < l1
138+ && s1 [ i ] === s3 [ k ]
139+ && checkStrings ( i + 1 , j , k + 1 )
140+ ) || (
141+ j < l2
142+ && s2 [ j ] === s3 [ k ]
143+ && checkStrings ( i , j + 1 , k + 1 )
144+ )
145+ ) ;
127146 }
128- return seen [ 0 ] ;
129147}
0 commit comments