2
2
* @param {string[] } words
3
3
* @return {number }
4
4
*/
5
- var longestStrChain = function ( words ) {
6
- const len = words . length ;
7
- words . sort ( ( a , b ) => a . length - b . length ) ;
8
- // dp[i] meaning: the longest string chain length ending with sorted words[i]
9
- let dp = new Array ( words . length ) . fill ( 1 ) ;
5
+ var longestStrChain = function ( words )
6
+ {
7
+ let tiers = new Array ( 16 ) ;
8
+ for ( let i = 0 ; i < tiers . length ; i ++ )
9
+ tiers [ i ] = [ ] ;
10
+ for ( let word of words )
11
+ tiers [ word . length - 1 ] . push ( { word, len :1 } ) ;
10
12
11
- // verify if a is a predecessor of word b
12
- const isValid = ( a , b ) => {
13
- if ( b . length - a . length !== 1 ) {
14
- return false ;
13
+ const isPredecessor = function ( word1 , word2 ) // Assumes word2.length = word1.length+1
14
+ {
15
+ let w1p = 0 , misses = 0 ;
16
+ for ( let w2p = 0 ; w2p < word2 . length ; w2p ++ )
17
+ {
18
+ if ( word2 [ w2p ] !== word1 [ w1p ] )
19
+ {
20
+ if ( misses === 1 )
21
+ return false ;
22
+ misses = 1 ;
23
+ }
24
+ else
25
+ {
26
+ w1p ++ ;
27
+ if ( w1p === word1 . length )
28
+ return true ;
29
+ }
30
+ }
31
+ return true ;
32
+ } ;
33
+
34
+
35
+ for ( let i = tiers . length - 1 ; i > 0 ; i -- )
36
+ {
37
+ for ( let w2 = 0 ; w2 < tiers [ i ] . length ; w2 ++ )
38
+ {
39
+ for ( let w1 = 0 ; w1 < tiers [ i - 1 ] . length ; w1 ++ )
40
+ {
41
+ if ( tiers [ i - 1 ] [ w1 ] . len >= tiers [ i ] [ w2 ] . len + 1 )
42
+ continue ;
43
+ if ( isPredecessor ( tiers [ i - 1 ] [ w1 ] . word , tiers [ i ] [ w2 ] . word ) )
44
+ tiers [ i - 1 ] [ w1 ] . len = tiers [ i ] [ w2 ] . len + 1 ;
45
+ }
46
+ }
15
47
}
16
- let lenOfA = a . length ;
17
- let lenOfB = b . length ;
18
- let i = 0 ;
19
- let j = 0 ;
20
- while ( i < lenOfA && j < lenOfB ) {
21
- if ( a . charAt ( i ) === b . charAt ( j ) ) {
22
- i ++ ;
23
- j ++ ;
24
- }
25
- else {
26
- j ++
27
- }
48
+
49
+ let max = 0 ;
50
+ for ( let i = 0 ; i < tiers . length ; i ++ )
51
+ {
52
+ for ( let j = 0 ; j < tiers [ i ] . length ; j ++ )
53
+ max = Math . max ( max , tiers [ i ] [ j ] . len ) ;
28
54
}
29
- // if the last char is diff, then i = j
30
- // if a char is different in the middle, then i = j - 1
31
- if ( i === j - 1 || i === j ) {
32
- return true ;
33
- }
34
- else {
35
- return false ;
36
- }
37
- }
38
-
39
- for ( let i = 0 ; i < len ; i ++ ) {
40
- for ( let j = i + 1 ; j < len ; j ++ ) {
41
- if ( isValid ( words [ i ] , words [ j ] ) ) {
42
- dp [ j ] = Math . max ( dp [ j ] , dp [ i ] + 1 ) ;
43
- }
44
- }
45
- }
46
- let max = dp [ 0 ] ;
47
- for ( let i = 0 ; i < dp . length ; i ++ ) {
48
- max = Math . max ( max , dp [ i ] ) ;
49
- }
50
- return max
51
-
52
-
53
- } ;
55
+
56
+ return max ;
57
+ } ;
0 commit comments