创作目的:为了方便自己后续复习重点,以及养成写博客的习惯。
一、滑动窗口最大值
思路:参考了ledcode官方题解
ledcode题目:https://leetcode.cn/problems/sliding-window-maximum/
AC代码:
void swap(int** a, int** b) {
int* tmp = *a;
*a = *b, *b = tmp;
}
int cmp(int* a, int* b) {
return a[0] == b[0] ? a[1] - b[1] : a[0] - b[0];
}
struct Heap {
int** heap;
int size;
int capacity;
};
void init(struct Heap* obj, int capacity) {
obj->size = 0;
obj->heap = NULL;
obj->capacity = capacity;
obj->heap = malloc(sizeof(int*) * (obj->capacity + 1));
for (int i = 1; i <= obj->capacity; i++) {
obj->heap[i] = malloc(sizeof(int) * 2);
}
}
void setFree(struct Heap* obj) {
for (int i = 1; i <= obj->capacity; i++) {
free(obj->heap[i]);
}
free(obj->heap);
free(obj);
}
void push(struct Heap* obj, int num0, int num1) {
int sub1 = ++(obj->size), sub2 = sub1 >> 1;
(obj->heap[sub1])[0] = num0, (obj->heap[sub1])[1] = num1;
while (sub2 > 0 && cmp(obj->heap[sub2], obj->heap[sub1]) < 0) {
swap(&(obj->heap[sub1]), &(obj->heap[sub2]));
sub1 = sub2, sub2 = sub1 >> 1;
}
}
void pop(struct Heap* obj) {
int sub = 1;
swap(&(obj->heap[sub]), &(obj->heap[(obj->size)--]));
while (sub <= obj->size) {
int sub1 = sub << 1, sub2 = sub << 1 | 1;
int maxSub = sub;
if (sub1 <= obj->size && cmp(obj->heap[maxSub], obj->heap[sub1]) < 0) {
maxSub = sub1;
}
if (sub2 <= obj->size && cmp(obj->heap[maxSub], obj->heap[sub2]) < 0) {
maxSub = sub2;
}
if (sub == maxSub) {
break;
}
swap(&(obj->heap[sub]), &(obj->heap[maxSub]));
sub = maxSub;
}
}
int* top(struct Heap* obj) {
return obj->heap[1];
}
int* maxSlidingWindow(int* nums, int numsSize, int k, int* returnSize) {
struct Heap* q = malloc(sizeof(struct Heap));
init(q, numsSize);
for (int i = 0; i < k; i++) {
push(q, nums[i], i);
}
int* ans = malloc(sizeof(int) * (numsSize - k + 1));
*returnSize = 0;
ans[(*returnSize)++] = top(q)[0];
for (int i = k; i < numsSize; ++i) {
push(q, nums[i], i);
while (top(q)[1] <= i - k) {
pop(q);
}
ans[(*returnSize)++] = top(q)[0];
}
setFree(q);
return ans;
}
二、前k个高频元素
思路:参考了ledcode官方题解
lecode题目:https://leetcode.cn/problems/top-k-frequent-elements/
AC代码:
struct hash_table {
int key;
int val;
UT_hash_handle hh;
};
typedef struct hash_table* hash_ptr;
struct pair {
int first;
int second;
};
void swap(struct pair* a, struct pair* b) {
struct pair t = *a;
*a = *b, *b = t;
}
void sort(struct pair* v, int start, int end, int* ret, int* retSize, int k) {
int picked = rand() % (end - start + 1) + start;
swap(&v[picked], &v[start]);
int pivot = v[start].second;
int index = start;
for (int i = start + 1; i <= end; i++) {
// 使用双指针把不小于基准值的元素放到左边,
// 小于基准值的元素放到右边
if (v[i].second >= pivot) {
swap(&v[index + 1], &v[i]);
index++;
}
}
swap(&v[start], &v[index]);
if (k <= index - start) {
// 前 k 大的值在左侧的子数组里
sort(v, start, index - 1, ret, retSize, k);
} else {
// 前 k 大的值等于左侧的子数组全部元素
// 加上右侧子数组中前 k - (index - start + 1) 大的值
for (int i = start; i <= index; i++) {
ret[(*retSize)++] = v[i].first;
}
if (k > index - start + 1) {
sort(v, index + 1, end, ret, retSize, k - (index - start + 1));
}
}
}
int* topKFrequent(int* nums, int numsSize, int k, int* returnSize) {
hash_ptr head = NULL;
hash_ptr p = NULL, tmp = NULL;
// 获取每个数字出现次数
for (int i = 0; i < numsSize; i++) {
HASH_FIND_INT(head, &nums[i], p);
if (p == NULL) {
p = malloc(sizeof(struct hash_table));
p->key = nums[i];
p->val = 1;
HASH_ADD_INT(head, key, p);
} else {
p->val++;
}
}
struct pair values[numsSize];
int valuesSize = 0;
HASH_ITER(hh, head, p, tmp) {
values[valuesSize].first = p->key;
values[valuesSize++].second = p->val;
}
int* ret = malloc(sizeof(int) * k);
*returnSize = 0;
sort(values, 0, valuesSize - 1, ret, returnSize, k);
return ret;
}
全篇后记:
记录自己的学习历程,希望自己可以坚持把题都刷完。