22#include <stdlib.h>
33#include <string.h>
44
5+
56#define container_of (ptr , type , member ) \
67 ((type *)((char *)(ptr) - (size_t)&(((type *)0)->member)))
78
1112#define list_for_each (p , head ) \
1213 for (p = (head)->next; p != (head); p = p->next)
1314
14- #define list_for_each_safe (p , n , head ) \
15- for (p = (head)->next, n = p->next; p != (head); p = n, n = p->next)
16-
1715struct list_head {
1816 struct list_head * next , * prev ;
1917};
2018
19+ struct word_node {
20+ char * word ;
21+ struct list_head link ;
22+ };
23+
24+ struct solution {
25+ int count ;
26+ struct list_head heads [];
27+ };
28+
2129static inline void INIT_LIST_HEAD (struct list_head * list )
2230{
2331 list -> next = list -> prev = list ;
@@ -46,107 +54,58 @@ static inline void list_add_tail(struct list_head *_new, struct list_head *head)
4654 __list_add (_new , head -> prev , head );
4755}
4856
49- static inline void __list_del (struct list_head * entry )
57+ static void new_word_add (struct list_head * head , char * word )
5058{
51- entry -> next -> prev = entry -> prev ;
52- entry -> prev -> next = entry -> next ;
59+ struct word_node * wn = malloc (sizeof (* wn ));
60+ wn -> word = word ;
61+ list_add_tail (& wn -> link , head );
5362}
5463
55- static inline void list_del (struct list_head * entry )
56- {
57- __list_del (entry );
58- entry -> next = entry -> prev = NULL ;
59- }
60-
61- struct word_node {
62- char * word ;
63- struct list_head link ;
64- };
65-
66- struct dfs_cache {
67- int num ;
68- int cap ;
69- struct list_head * * heads ;
70- };
71-
72- static struct dfs_cache * resize (struct dfs_cache * * caches , int index )
73- {
74- int i ;
75- struct dfs_cache * cache = caches [index ];
76- if (cache -> num + 1 > cache -> cap ) {
77- cache -> cap *= 2 ;
78- struct list_head * * heads = malloc (cache -> cap * sizeof (* heads ));
79- for (i = 0 ; i < cache -> cap ; i ++ ) {
80- if (i < cache -> num ) {
81- heads [i ] = cache -> heads [i ];
82- } else {
83- heads [i ] = malloc (sizeof (struct list_head ));
84- INIT_LIST_HEAD (heads [i ]);
85- }
86- }
87- free (cache -> heads );
88- cache -> heads = heads ;
89- }
90-
91- return cache ;
92- }
93-
94- static struct dfs_cache * dfs (char * s , char * * words , int * sizes , int num ,
95- struct dfs_cache * * caches , int index )
64+ static struct solution * dfs (char * s , char * * words , int * lens , int size ,
65+ struct solution * * sols , int index )
9666{
9767 int i , j ;
98- struct word_node * wn ;
99- struct dfs_cache * result ;
100-
10168 if (* s == '\0' ) {
10269 return NULL ;
103- } else if (caches [index ] != NULL ) {
104- return caches [index ];
70+ } else if (sols [index ] != NULL ) {
71+ return sols [index ];
10572 } else {
106- result = malloc (sizeof (* result ));
107- result -> num = 0 ;
108- result -> cap = 1 ;
109- result -> heads = malloc (sizeof (struct list_head * ));
110- result -> heads [0 ] = malloc (sizeof (struct list_head ));
111- INIT_LIST_HEAD (result -> heads [0 ]);
112- caches [index ] = result ;
113- for (i = 0 ; i < num ; i ++ ) {
114- if (!memcmp (s , words [i ], sizes [i ])) {
115- struct dfs_cache * next = dfs (s + sizes [i ], words , sizes , num , caches , index + sizes [i ]);
116- if (next != NULL ) {
117- int k = result -> num ;
118- for (j = k ; j < k + next -> num ; j ++ ) {
119- result = resize (caches , index );
120- wn = malloc (sizeof (* wn ));
121- wn -> word = words [i ];
122- list_add (& wn -> link , result -> heads [j ]);
123-
73+ struct solution * sol = malloc (sizeof (* sol ) + 60 * sizeof (struct list_head ));
74+ sol -> count = 0 ;
75+ sols [index ] = sol ;
76+ for (i = 0 ; i < size ; i ++ ) {
77+ if (!strncmp (s , words [i ], lens [i ])) {
78+ /* post-order traverse */
79+ struct solution * sub_sol = dfs (s + lens [i ], words , lens , size , sols , index + lens [i ]);
80+ if (sub_sol != NULL ) {
81+ int k = sol -> count ;
82+ for (j = k ; j < k + sub_sol -> count ; j ++ ) {
83+ /* Append all sub-solutions */
84+ INIT_LIST_HEAD (& sol -> heads [j ]);
85+ new_word_add (& sol -> heads [j ], words [i ]);
12486 struct list_head * p ;
125- list_for_each (p , next -> heads [j - k ]) {
126- struct word_node * wnn = list_entry (p , struct word_node , link );
127- wn = malloc (sizeof (* wn ));
128- wn -> word = wnn -> word ;
129- list_add_tail (& wn -> link , result -> heads [j ]);
87+ list_for_each (p , & sub_sol -> heads [j - k ]) {
88+ struct word_node * wn = list_entry (p , struct word_node , link );
89+ new_word_add (& sol -> heads [j ], wn -> word );
13090 }
131- result -> num ++ ;
91+ sol -> count ++ ;
13292 }
13393 } else {
134- wn = malloc ( sizeof ( * wn ));
135- wn -> word = words [ i ] ;
136- list_add ( & wn -> link , result -> heads [result -> num ++ ]);
94+ /* leaf node */
95+ INIT_LIST_HEAD ( & sol -> heads [ 0 ]) ;
96+ new_word_add ( & sol -> heads [sol -> count ++ ], words [ i ]);
13797 }
13898 }
13999 }
140-
141- return result ;
100+ return sol ;
142101 }
143102}
144103
145104/**
146- ** Return an array of size *returnSize.
147- ** Note: The returned array must be malloced, assume caller calls free().
148- ** /
149- static char * * wordBreak (char * s , char * * wordDict , int wordDictSize , int * returnSize )
105+ * Return an array of size *returnSize.
106+ * Note: The returned array must be malloced, assume caller calls free().
107+ */
108+ char * * wordBreak (char * s , char * * wordDict , int wordDictSize , int * returnSize )
150109{
151110 if (wordDictSize == 0 ) {
152111 * returnSize = 0 ;
@@ -155,24 +114,24 @@ static char **wordBreak(char* s, char** wordDict, int wordDictSize, int *returnS
155114
156115 int i , total = 0 ;
157116 int len = strlen (s );
158- int * sizes = malloc (wordDictSize * sizeof (int ));
117+ int * lens = malloc (wordDictSize * sizeof (int ));
159118
160119 /* Add into hash list */
161120 for (i = 0 ; i < wordDictSize ; i ++ ) {
162- sizes [i ] = strlen (wordDict [i ]);
163- total += sizes [i ];
121+ lens [i ] = strlen (wordDict [i ]);
122+ total += lens [i ];
164123 }
165124
166- struct dfs_cache * * caches = malloc (len * sizeof (* caches ));
167- memset (caches , 0 , len * sizeof (* caches ));
168- struct dfs_cache * cache = dfs (s , wordDict , sizes , wordDictSize , caches , 0 );
125+ struct solution * * sols = malloc (len * sizeof (void * ));
126+ memset (sols , 0 , len * sizeof (void * ));
127+ struct solution * sol = dfs (s , wordDict , lens , wordDictSize , sols , 0 );
169128
170- char * * results = malloc (cache -> num * sizeof (char * ));
171- for (i = 0 ; i < cache -> num ; i ++ ) {
129+ char * * results = malloc (sol -> count * sizeof (char * ));
130+ for (i = 0 ; i < sol -> count ; i ++ ) {
172131 results [i ] = malloc (total + 100 );
173132 char * p = results [i ];
174133 struct list_head * n ;
175- list_for_each (n , cache -> heads [i ]) {
134+ list_for_each (n , & sol -> heads [i ]) {
176135 struct word_node * wn = list_entry (n , struct word_node , link );
177136 char * q = wn -> word ;
178137 while ((* p ++ = * q ++ ) != '\0' ) {}
@@ -181,7 +140,7 @@ static char **wordBreak(char* s, char** wordDict, int wordDictSize, int *returnS
181140 * (p - 1 ) = '\0' ;
182141 }
183142
184- * returnSize = cache -> num ;
143+ * returnSize = sol -> count ;
185144 return results ;
186145}
187146
0 commit comments