Skip to content

Commit 82eac5b

Browse files
committed
sol 150, 239 and 1295
1 parent b81824b commit 82eac5b

File tree

4 files changed

+255
-0
lines changed

4 files changed

+255
-0
lines changed

c_code/1295_findNumbers.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#define BASE_OCT 10
2+
#define EVEN_BASE 2
3+
int GetBitsNum(int val)
4+
{
5+
int bit = 0;
6+
while (val != 0) {
7+
val /= BASE_OCT;
8+
bit++;
9+
}
10+
return bit;
11+
}
12+
13+
int findNumbers(int* nums, int numsSize)
14+
{
15+
int i;
16+
int cnt = 0;
17+
for (i = 0; i < numsSize; i++) {
18+
int bits = GetBitsNum(nums[i]);
19+
if (bits % EVEN_BASE == 0) { cnt++; }
20+
}
21+
return cnt;
22+
}

c_code/150_evalRPN.c

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#define HALF_NUM 2
2+
int StackCal(const char *p, int *stackArray, int top)
3+
{
4+
if (p[1] == '\0' && p[0] == '+') {
5+
stackArray[top - 1] += stackArray[top];
6+
top--;
7+
} else if (p[1] == '\0' && p[0] == '-') {
8+
stackArray[top - 1] -= stackArray[top];
9+
top--;
10+
} else if (p[1] == '\0' && p[0] == '*') {
11+
stackArray[top - 1] *= stackArray[top];
12+
top--;
13+
} else if (p[1] == '\0' && p[0] == '/') {
14+
stackArray[top - 1] /= stackArray[top];
15+
top--;
16+
} else {
17+
stackArray[++top] = atoi(p);
18+
}
19+
return top;
20+
}
21+
22+
int evalRPN(char ** tokens, int tokensSize)
23+
{
24+
int res;
25+
int *stackArray = (int*)malloc((tokensSize / HALF_NUM + 1) * sizeof(int)); // 没加1时会越界,例["4","13","5","/","+"]
26+
int top = -1;
27+
28+
int i;
29+
for (i = 0; i < tokensSize; i++) {
30+
top = StackCal(tokens[i], stackArray, top);
31+
}
32+
if (top == 0) { // 计算成功,top回到数组栈首尾
33+
res = stackArray[0];
34+
free(stackArray);
35+
return res;
36+
}
37+
return -1;
38+
}

c_code/239_maxSlidingWindow_sol1.c

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
// Prior Quneue,完全用数组形式实现的最大堆功能
2+
typedef struct MaxPriorQue {
3+
int** heap; // 二维数组 heap[i][0/1] 0是idx,1是val
4+
int size; // 当前队列大小
5+
int capcity; // 队列最大容量
6+
} MaxPriorQueStru, *pMaxPriorQueStru;
7+
8+
void init(pMaxPriorQueStru p, int size)
9+
{
10+
p->size = 0;
11+
p->heap = (int**)malloc((size + 1) * sizeof(int*));
12+
// if (p->heap == NULL) { return NULL;}
13+
p->capcity = size + 1;
14+
15+
int i;
16+
for (i = 0; i < p->capcity; i++) {
17+
p->heap[i] = (int *)malloc(2 * sizeof(int));
18+
// if (p->heap[i] == NULL) { return NULL; }
19+
}
20+
21+
return;
22+
}
23+
24+
int cmpValOrIdx(int *a, int *b)
25+
{
26+
return a[1] == b[1] ? a[0] - b[0] : a[1] - b[1]; // 优先比较数值,再比较下标
27+
}
28+
29+
// 完全用数组形式实现的最大堆功能
30+
void push(pMaxPriorQueStru p, int idx, int val)
31+
{
32+
// 已保证堆足够大,不用担心溢出
33+
p->size += 1;
34+
35+
// 先放末端节点
36+
p->heap[p->size][0] = idx;
37+
p->heap[p->size][1] = val;
38+
39+
// 通过与上层节点不断比较交换,找到合适位置
40+
int i0 = p->size >> 1;
41+
int i1 = p->size;
42+
while (i0 > 0 && cmpValOrIdx(p->heap[i0], p->heap[i1]) < 0) {
43+
int *tmp = p->heap[i0]; // 交换二级指针指向的一级指针地址
44+
p->heap[i0] = p->heap[i1];
45+
p->heap[i1] = tmp;
46+
i1 = i0; // 继续往上一层末端节点比较
47+
i0 >>= 1;
48+
}
49+
50+
return;
51+
}
52+
53+
void pop(pMaxPriorQueStru p)
54+
{
55+
// 将顶端的值与末尾节点交换,再自减容量
56+
int *tmp = p->heap[1]; // 交换二级指针指向的一级指针地址
57+
p->heap[1] = p->heap[p->size];
58+
p->heap[p->size] = tmp;
59+
p->size--;
60+
61+
// 调整堆,把末尾节点下沉到合适位置
62+
int i = 1; // 从顶端开始
63+
while (i <= p->size) {
64+
int l = i << 1; // 左孩子索引
65+
int r = l + 1; // 右孩子索引
66+
int max = i;
67+
if (l <= p->size && cmpValOrIdx(p->heap[max], p->heap[l]) < 0) {
68+
max = l;
69+
}
70+
if (r <= p->size && cmpValOrIdx(p->heap[max], p->heap[r]) < 0) {
71+
max = r;
72+
}
73+
if (max == i) { // 如果父节点就已是最大值,则调整完毕,顶端交换的值已找到合适位置
74+
break;
75+
}
76+
// 需要交换
77+
int *tmp = p->heap[i]; // 交换二级指针指向的一级指针地址
78+
p->heap[i] = p->heap[max];
79+
p->heap[max] = tmp;
80+
81+
i = max; // 和max的指针交换后,当前max索引是被交换到顶端的底部值,待进一步下沉比较
82+
}
83+
// i下沉到最末端或者末尾节点已下沉到合适位置,结束调整
84+
85+
return;
86+
}
87+
88+
int* top(pMaxPriorQueStru p)
89+
{
90+
return p->heap[1]; // 为方便下标引用,索引0空置不用
91+
}
92+
93+
void SetFree(pMaxPriorQueStru p)
94+
{
95+
int i;
96+
for (i = 0; i < p->capcity; i++) {
97+
free(p->heap[i]);
98+
}
99+
free(p->heap);
100+
free(p);
101+
return;
102+
}
103+
104+
// 利用最大堆队列数据结构来完成
105+
int* maxSlidingWindow(int* nums, int numsSize, int k, int* returnSize)
106+
{
107+
if (k == 1) {
108+
*returnSize = numsSize;
109+
return nums;
110+
}
111+
112+
// 压入前k个数据
113+
pMaxPriorQueStru q = (pMaxPriorQueStru)malloc(sizeof(MaxPriorQueStru));
114+
if (q == NULL) { return NULL; }
115+
init(q, numsSize);
116+
117+
int resSize = numsSize - k + 1;
118+
int *resArr = (int *)malloc(resSize * sizeof(int));
119+
if (resArr == NULL) { return NULL; }
120+
121+
int end = 0;
122+
int i;
123+
for (i = 0; i < k; i++) {
124+
push(q, i, nums[i]);
125+
}
126+
int *heap = top(q);
127+
// resArr[*returnSize++] = heap[1]; // 作用是:resArr[*returnSize], 再returnSize++,加在地址上了,与预期不符
128+
resArr[end++] = heap[1];
129+
//printf("%d \n", *returnSize);
130+
//printf("%d ", heap[1]);
131+
132+
// 从k往后移动
133+
for (i = k; i < numsSize; i++) {
134+
push(q, i, nums[i]);
135+
heap = top(q);
136+
while (heap[0] <= i - k) {
137+
pop(q);
138+
heap = top(q);
139+
}
140+
//resArr[*returnSize++] = heap[1];
141+
resArr[end++] = heap[1];
142+
// printf("%d \n", *returnSize);
143+
// printf("%d ", heap[1]);
144+
}
145+
//printf("%d \n", *returnSize);
146+
147+
*returnSize = end;
148+
SetFree(q);
149+
150+
return resArr;
151+
}

c_code/239_maxSlidingWindow_sol2.c

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/**
2+
* Note: The returned array must be malloced, assume caller calls free().
3+
*/
4+
int* maxSlidingWindow(int* nums, int numsSize, int k, int* returnSize)
5+
{
6+
if (k == 1) {
7+
*returnSize = numsSize;
8+
return nums;
9+
}
10+
// 单调队列思路,从左到右递减;思路类同第一个保存第一第二个最大值思路
11+
int maxQueIdx[numsSize];
12+
int resSize = numsSize - k + 1;
13+
int *resArr = (int *)malloc(resSize * sizeof(int));
14+
if (resArr == NULL) { return NULL; }
15+
*returnSize = resSize;
16+
17+
int i;
18+
int left = 0;
19+
int right = 0;
20+
for (i = 0; i < k; i++) {
21+
while (left < right && nums[i] >= nums[maxQueIdx[right - 1]]) {
22+
right--; // 出队列
23+
}
24+
maxQueIdx[right++] = i;
25+
}
26+
resSize = 0;
27+
resArr[resSize++] = nums[maxQueIdx[left]];
28+
29+
for (i = k; i < numsSize; i++) {
30+
// 若窗口加入的新元素比队尾元素大于等于,则队尾元素出队列
31+
// 之所以等于也要出队列,是因为下标idx最新,不容易移除窗口
32+
while (left < right && nums[i] >= nums[maxQueIdx[right - 1]]) { // 当前队尾元素为right - 1,队尾指针在right
33+
right--; // 出队列
34+
}
35+
maxQueIdx[right++] = i;
36+
37+
while (maxQueIdx[left] <= i - k) { // 最大值不在窗外
38+
left++; // 弹出队首元素,左移
39+
}
40+
resArr[resSize++] = nums[maxQueIdx[left]];
41+
}
42+
43+
return resArr;
44+
}

0 commit comments

Comments
 (0)