2
2
#include <stdlib.h>
3
3
#include <string.h>
4
4
5
+
5
6
#define container_of (ptr , type , member ) \
6
7
((type *)((char *)(ptr) - (size_t)&(((type *)0)->member)))
7
8
11
12
#define list_for_each (p , head ) \
12
13
for (p = (head)->next; p != (head); p = p->next)
13
14
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
-
17
15
struct list_head {
18
16
struct list_head * next , * prev ;
19
17
};
20
18
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
+
21
29
static inline void INIT_LIST_HEAD (struct list_head * list )
22
30
{
23
31
list -> next = list -> prev = list ;
@@ -46,107 +54,58 @@ static inline void list_add_tail(struct list_head *_new, struct list_head *head)
46
54
__list_add (_new , head -> prev , head );
47
55
}
48
56
49
- static inline void __list_del (struct list_head * entry )
57
+ static void new_word_add (struct list_head * head , char * word )
50
58
{
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 );
53
62
}
54
63
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 )
96
66
{
97
67
int i , j ;
98
- struct word_node * wn ;
99
- struct dfs_cache * result ;
100
-
101
68
if (* s == '\0' ) {
102
69
return NULL ;
103
- } else if (caches [index ] != NULL ) {
104
- return caches [index ];
70
+ } else if (sols [index ] != NULL ) {
71
+ return sols [index ];
105
72
} 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 ]);
124
86
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 );
130
90
}
131
- result -> num ++ ;
91
+ sol -> count ++ ;
132
92
}
133
93
} 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 ]);
137
97
}
138
98
}
139
99
}
140
-
141
- return result ;
100
+ return sol ;
142
101
}
143
102
}
144
103
145
104
/**
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 )
150
109
{
151
110
if (wordDictSize == 0 ) {
152
111
* returnSize = 0 ;
@@ -155,24 +114,24 @@ static char **wordBreak(char* s, char** wordDict, int wordDictSize, int *returnS
155
114
156
115
int i , total = 0 ;
157
116
int len = strlen (s );
158
- int * sizes = malloc (wordDictSize * sizeof (int ));
117
+ int * lens = malloc (wordDictSize * sizeof (int ));
159
118
160
119
/* Add into hash list */
161
120
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 ];
164
123
}
165
124
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 );
169
128
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 ++ ) {
172
131
results [i ] = malloc (total + 100 );
173
132
char * p = results [i ];
174
133
struct list_head * n ;
175
- list_for_each (n , cache -> heads [i ]) {
134
+ list_for_each (n , & sol -> heads [i ]) {
176
135
struct word_node * wn = list_entry (n , struct word_node , link );
177
136
char * q = wn -> word ;
178
137
while ((* p ++ = * q ++ ) != '\0' ) {}
@@ -181,7 +140,7 @@ static char **wordBreak(char* s, char** wordDict, int wordDictSize, int *returnS
181
140
* (p - 1 ) = '\0' ;
182
141
}
183
142
184
- * returnSize = cache -> num ;
143
+ * returnSize = sol -> count ;
185
144
return results ;
186
145
}
187
146
0 commit comments