Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 56519c4

Browse files
authored
Create: 0691-stickers-to-spell-word.c
1 parent a7d0016 commit 56519c4

File tree

1 file changed

+267
-0
lines changed

1 file changed

+267
-0
lines changed

c/0691-stickers-to-spell-word.c

Lines changed: 267 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,267 @@
1+
#define MIN 5
2+
3+
typedef struct myInstance {
4+
int index;
5+
int count;
6+
} Instance;
7+
8+
typedef struct myList {
9+
int size;
10+
int maxSize;
11+
Instance *data;
12+
} InstanceList;
13+
14+
// Function to clean up allocated memory
15+
void cleanup(InstanceList **mapping, int **stickerSignatures, int signatureSize) {
16+
// Clean up the memory used for mapping
17+
for (int i = 0; i < 26; i++) {
18+
InstanceList *current = mapping[i];
19+
if (current != NULL) {
20+
if (current->data != NULL) {
21+
free(current->data);
22+
}
23+
free(current);
24+
}
25+
}
26+
27+
// Clean up the memory used for sticker signatures
28+
for (int i = 0; i < signatureSize; i++) {
29+
if (stickerSignatures[i] != NULL) {
30+
free(stickerSignatures[i]);
31+
}
32+
}
33+
}
34+
35+
// Hash function to map a character to an index
36+
int hashFunction(char c) {
37+
return c - 'a';
38+
}
39+
40+
// Initialize the signature for a word (count of each letter)
41+
void initializeSignature(char *word, int *signature) {
42+
for (int i = 0; i < 26; i++) {
43+
signature[i] = 0;
44+
}
45+
46+
for (char *c = word; *c != '\0'; c++) {
47+
signature[hashFunction(*c)]++;
48+
}
49+
}
50+
51+
// Preprocess stickers and filter out dominated ones
52+
int preprocessStickers(char **stickers, int stickersSize,
53+
int **stickerSignatures, char **workingStickers, const int const *targetSignature) {
54+
for (int i = 0; i < stickersSize; i++) {
55+
workingStickers[i] = stickers[i];
56+
stickerSignatures[i] = (int *)malloc(sizeof(int) * 26);
57+
58+
for (int j = 0; j < 26; j++) {
59+
stickerSignatures[i][j] = 0;
60+
}
61+
62+
for (char *c = stickers[i]; *c != '\0'; c++) {
63+
int index = hashFunction(*c);
64+
65+
if (targetSignature[index] > 0) {
66+
stickerSignatures[i][index]++;
67+
}
68+
}
69+
}
70+
71+
int remaining = stickersSize;
72+
73+
for (int i = 0; i < remaining; i++) {
74+
for (int j = 0; j < remaining; j++) {
75+
if (i == j || workingStickers[j] == NULL) {
76+
continue;
77+
}
78+
79+
int dominated = 1;
80+
81+
for (int k = 0; k < 26; k++) {
82+
if (stickerSignatures[i][k] > stickerSignatures[j][k]) {
83+
dominated = 0;
84+
break;
85+
}
86+
}
87+
88+
if (dominated) {
89+
free(stickerSignatures[i]);
90+
stickerSignatures[i] = NULL;
91+
workingStickers[i] = NULL;
92+
remaining--;
93+
94+
if (i < remaining) {
95+
stickerSignatures[i] = stickerSignatures[remaining];
96+
workingStickers[i] = workingStickers[remaining];
97+
stickerSignatures[remaining] = NULL;
98+
workingStickers[remaining] = NULL;
99+
i--;
100+
}
101+
102+
break;
103+
}
104+
}
105+
}
106+
107+
return remaining;
108+
}
109+
110+
// Create a hash table to map characters to stickers
111+
int makeHashTable(char **stickers, int stickersSize, char *target, InstanceList **mapping) {
112+
for (int i = 0; i < 26; i++) {
113+
mapping[i] = NULL;
114+
}
115+
116+
for (char *c = target; *c != '\0'; c++) {
117+
int index = hashFunction(*c);
118+
119+
if (mapping[index] == NULL) {
120+
mapping[index] = (InstanceList *)malloc(sizeof(InstanceList));
121+
mapping[index]->data = NULL;
122+
}
123+
}
124+
125+
for (int i = 0; i < stickersSize; i++) {
126+
for (char *c = stickers[i]; *c != '\0'; c++) {
127+
int index = hashFunction(*c);
128+
129+
if (mapping[index] != NULL) {
130+
InstanceList *spot = mapping[index];
131+
132+
if (spot->data != NULL && spot->size > 0
133+
&& spot->data[spot->size - 1].index == i) {
134+
spot->data[spot->size - 1].count++;
135+
continue;
136+
}
137+
138+
if (spot->data == NULL) {
139+
spot->data = (Instance *)malloc(sizeof(Instance) * MIN);
140+
spot->size = 0;
141+
spot->maxSize = MIN;
142+
} else if (spot->size == spot->maxSize) {
143+
spot->maxSize *= 2;
144+
spot->data = realloc(spot->data, sizeof(Instance) * spot->maxSize);
145+
}
146+
147+
spot->data[spot->size].index = i;
148+
spot->data[spot->size].count = 1;
149+
spot->size++;
150+
}
151+
}
152+
}
153+
154+
return 0;
155+
}
156+
157+
// Find the index with the minimum size in mapping
158+
int minIndex(InstanceList **mapping, int *targetSignature) {
159+
int index = -1;
160+
161+
for (int i = 0; i < 26; i++) {
162+
if (targetSignature[i] > 0 && (index == -1 || mapping[i]->size < mapping[index]->size)) {
163+
index = i;
164+
}
165+
}
166+
167+
return index;
168+
}
169+
170+
// Recursive search function to find the minimum stickers required
171+
void search(InstanceList **mapping, int **stickerSignatures, int *targetSignature, int depth, int *maxDepth) {
172+
if (depth >= *maxDepth && *maxDepth > 0) {
173+
return;
174+
}
175+
176+
int minLetter = minIndex(mapping, targetSignature);
177+
178+
if (minLetter < 0) {
179+
if (*maxDepth == 0 || depth < *maxDepth) {
180+
*maxDepth = depth;
181+
}
182+
183+
return;
184+
}
185+
186+
for (int option = 0; option < mapping[minLetter]->size; option++) {
187+
int index = mapping[minLetter]->data[option].index;
188+
189+
for (int i = 0; i < 26; i++) {
190+
targetSignature[i] -= stickerSignatures[index][i];
191+
}
192+
193+
search(mapping, stickerSignatures, targetSignature, depth + 1, maxDepth);
194+
195+
for (int i = 0; i < 26; i++) {
196+
targetSignature[i] += stickerSignatures[index][i];
197+
}
198+
}
199+
200+
return;
201+
}
202+
203+
// Main function to calculate the minimum stickers required
204+
int minStickers(char **stickers, int stickersSize, char *target) {
205+
int targetSignature[26];
206+
initializeSignature(target, targetSignature);
207+
int *stickerSignatures[stickersSize];
208+
char *workingStickers[stickersSize];
209+
int domainSize = preprocessStickers(stickers, stickersSize, stickerSignatures, workingStickers, targetSignature);
210+
InstanceList *mapping[26];
211+
makeHashTable(workingStickers, domainSize, target, mapping);
212+
213+
for (int i = 0; i < 26; i++) {
214+
if (mapping[i] != NULL && mapping[i]->data == NULL) {
215+
cleanup(mapping, stickerSignatures, domainSize);
216+
return -1;
217+
}
218+
}
219+
220+
int maxDepth = 0;
221+
search(mapping, stickerSignatures, targetSignature, 0, &maxDepth);
222+
cleanup(mapping, stickerSignatures, domainSize);
223+
return maxDepth;
224+
}
225+
226+
// Alternative Solution
227+
228+
// int solve(int mask, char **stickers, char *target, int n, int m, int *dp) {
229+
// if (mask == (1 << m) - 1) {
230+
// return 0;
231+
// }
232+
// if (dp[mask] != -1) {
233+
// return dp[mask];
234+
// }
235+
// int ans = 1e9;
236+
// for (int i = 0; i < n; i++) {
237+
// int freq[26] = {0};
238+
// for (int j = 0; stickers[i][j] != '\0'; j++) {
239+
// freq[stickers[i][j] - 'a']++;
240+
// }
241+
// int new_mask = 0;
242+
// for (int j = 0; j < m; j++) {
243+
// if ((1 << j) & mask) continue;
244+
// if (freq[target[j] - 'a']) {
245+
// freq[target[j] - 'a']--;
246+
// new_mask |= (1 << j);
247+
// }
248+
// }
249+
// if (new_mask != 0) {
250+
// int temp = 1 + solve(new_mask | mask, stickers, target, n, m, dp);
251+
// ans = (temp < ans) ? temp : ans;
252+
// }
253+
// }
254+
// return dp[mask] = ans;
255+
// }
256+
257+
// int minStickers(char **stickers, int stickersSize, char *target) {
258+
// int mask = 0;
259+
// int n = stickersSize, m = strlen(target);
260+
// int *dp = (int *)malloc((1 << m) * sizeof(int));
261+
// for (int i = 0; i < (1 << m); i++) {
262+
// dp[i] = -1;
263+
// }
264+
// int ans = solve(mask, stickers, target, n, m, dp);
265+
// free(dp);
266+
// return (ans == 1e9) ? -1 : ans;
267+
// }

0 commit comments

Comments
 (0)