max_freq_elem_op2.c (3912B)
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 129 130 131 132 133 134 135 136 137 | // 3347. Maximum Frequency of an Element After Performing Operations II #include "leetcode.h" /* * you are given an integer array 'nums' and two integers 'k' and * 'numOperations'. you must perform an operation 'numOperations' times on * 'nums', where in each operation you select an index 'i' that was not selected * in any previous operations, and add an integer in the range '[-k, k]' to * 'nums[i]'. return the maximum possible frequency of any elements in 'nums' * after performing the operations. */ struct hash_item { int key; int val; UT_hash_handle hh; }; struct hash_item *hash_find_item(struct hash_item **obj, int key) { struct hash_item *p = NULL; HASH_FIND_INT(*obj, &key, p); return p; } bool hash_add_item(struct hash_item **obj, int key, int val) { if (hash_find_item(obj, key)) return false; struct hash_item *p = (struct hash_item *)malloc(sizeof(struct hash_item)); p->key = key; p->val = val; HASH_ADD_INT(*obj, key, p); return true; } void hash_set_item(struct hash_item **obj, int key, int val) { struct hash_item *p = hash_find_item(obj, key); if (!p) hash_add_item(obj, key, val); else p->val = val; } int hash_get_item(struct hash_item **obj, int key, int val) { struct hash_item *p = hash_find_item(obj, key); if (!p) return val; return p->val; } void hash_free(struct hash_item **obj) { struct hash_item *curr = NULL, *tmp = NULL; HASH_ITER(hh, *obj, curr, tmp) { HASH_DEL(*obj, curr); free(curr); } } int cmp(const void *a, const void *b) { return (*(int *)a - *(int *)b); } void add_mode(int *nums, int numsSize, int k, struct hash_item **modes, int val) { hash_add_item(modes, val, 1); if (val - k >= nums[0]) hash_add_item(modes, val - k, 1); if (val + k <= nums[numsSize - 1]) hash_add_item(modes, val + k, 1); } int left_bound(int *nums, int numsSize, int val) { int left = 0, right = numsSize - 1; while (left < right) { int mid = (left + right) / 2; if (nums[mid] < val) left = mid + 1; else right = mid; } return left; } int right_bound(int *nums, int numsSize, int val) { int left = 0, right = numsSize - 1; while (left < right) { int mid = (left + right + 1) / 2; if (nums[mid] > val) right = mid - 1; else left = mid; } return left; } int maxFrequency(int *nums, int numsSize, int k, int numOperations) { qsort(nums, numsSize, sizeof(int), cmp); int ans = 0, prev = 0; struct hash_item *num_cnt = NULL, *modes = NULL; for (int i = 0; i < numsSize; i++) { if (nums[i] != nums[prev]) { hash_set_item(&num_cnt, nums[prev], i - prev); if (i - prev > ans) ans = i - prev; add_mode(nums, numsSize, k, &modes, nums[prev]); prev = i; } } hash_set_item(&num_cnt, nums[prev], numsSize - prev); if (numsSize - prev > ans) ans = numsSize - prev; add_mode(nums, numsSize, k, &modes, nums[prev]); int mode_size = HASH_COUNT(modes), pos = 0; int *sorted_modes = (int *)malloc(mode_size * sizeof(int)); for (struct hash_item *p = modes; p; p = p->hh.next) sorted_modes[pos++] = p->key; qsort(sorted_modes, mode_size, sizeof(int), cmp); for (int i = 0; i < mode_size; i++) { int mode = sorted_modes[i], tmp; int l = left_bound(nums, numsSize, mode - k); int r = right_bound(nums, numsSize, mode + k); if (hash_find_item(&num_cnt, mode)) { int cnt = hash_get_item(&num_cnt, mode, 0); tmp = fmin(r - l + 1, cnt + numOperations); } else tmp = fmin(r - l + 1, numOperations); if (tmp > ans) ans = tmp; } hash_free(&num_cnt); hash_free(&modes); free(sorted_modes); return ans; } int main() { int n1[] = {1, 4, 5}, n2[] = {5, 11, 20, 20}; printf("%d\n", maxFrequency(n1, ARRAY_SIZE(n1), 1, 2)); // expect: 2 printf("%d\n", maxFrequency(n2, ARRAY_SIZE(n2), 5, 1)); // expect: 2 } |