distribute_repeating_ints.c (3825B)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | // 1655. Distribute Repeating Integers #include "leetcode.h" /* * you are given an array of 'n' integers, 'nums' where there are at most 50 * unique values in the array. you are also given an array of 'm' customer order * quantities 'quantity', where 'quantity[i]' is the amount of integers the i'th * customer ordered. determine if it is possible to distribute 'nums' such that * the i'th customer gets exactly 'quantity[i]' integers, the integers the i'th * customer gets are all equal, and every customer is satisfied. return 'true' * if it is possible to distribute 'nums' according to the above conditions. */ static bool ans = false; struct hash_entry { int key; int val; }; struct hash_map { struct hash_entry *entries; int capacity; int size; }; int cmp_desc(const void *a, const void *b) { return (*(int *)b - *(int *)a); } int cmp_hash(const void *a, const void *b) { return ((struct hash_entry *)b)->val - ((struct hash_entry *)a)->val; } void dfs(int *quantity, int n, int *counts, int m, int i) { if (i == n && ans) { ans = true; return; } for (int j = 0; j < m; j++) { int cnt = counts[j]; if (cnt >= quantity[i]) { counts[j] -= quantity[i]; dfs(quantity, n, counts, m, i + 1); counts[j] += quantity[i]; } } } struct hash_map *hash_map_init(int capacity) { struct hash_map *obj = (struct hash_map *)malloc(sizeof(struct hash_map)); obj->capacity = capacity; obj->size = 0; obj->entries = (struct hash_entry *)calloc(obj->capacity, sizeof(struct hash_entry)); return obj; } void hash_map_free(struct hash_map *obj) { if (obj) { if (obj->entries) free(obj->entries); free(obj); } } unsigned int hash(int key, int capacity) { return (unsigned int)key % capacity; } void hash_map_put(struct hash_map *obj, int key, int val) { unsigned int idx = hash(key, obj->capacity); while (obj->entries[idx].key && obj->entries[idx].key != key) idx = (idx + 1) % obj->capacity; if (!obj->entries[idx].key) obj->size++; obj->entries[idx].key = key; obj->entries[idx].val = val; } int hash_map_get(struct hash_map *obj, int key) { unsigned int idx = hash(key, obj->capacity); int start_idx = idx; while (obj->entries[idx].key) { if (obj->entries[idx].key == key) return obj->entries[idx].val; idx = (idx + 1) % obj->capacity; if (idx == start_idx) break; } return 0; } bool canDistribute(int *nums, int numsSize, int *quantity, int quantitySize) { ans = false; struct hash_map *counter = hash_map_init(numsSize); for (int i = 0; i < numsSize; i++) { int curr = hash_map_get(counter, nums[i]); hash_map_put(counter, nums[i], curr + 1); } int *counts = (int *)malloc(counter->size * sizeof(int)); struct hash_entry *entries = (struct hash_entry *)malloc(counter->size * sizeof(struct hash_entry)); int entries_idx = 0; for (int i = 0; i < counter->capacity; i++) if (counter->entries[i].key) entries[entries_idx++] = counter->entries[i]; qsort(entries, counter->size, sizeof(struct hash_entry), cmp_hash); for (int i = 0; i < counter->size; i++) counts[i] = entries[i].val; int counts_size = counter->size; free(entries); hash_map_free(counter); qsort(quantity, quantitySize, sizeof(int), cmp_desc); dfs(quantity, quantitySize, counts, counts_size, 0); free(counts); return ans; } int main() { int n1[] = {1, 2, 3, 4}, q1[] = {2}; int n2[] = {1, 2, 3, 3}, q2[] = {2}; int n3[] = {1, 1, 2, 2}, q3[] = {2, 2}; printf("%d\n", canDistribute(n1, ARRAY_SIZE(n1), q1, ARRAY_SIZE(q1))); // expect: 0 printf("%d\n", canDistribute(n2, ARRAY_SIZE(n2), q2, ARRAY_SIZE(q2))); // expect: 1 printf("%d\n", canDistribute(n3, ARRAY_SIZE(n3), q3, ARRAY_SIZE(q3))); // expect: 1 } |