1. 有效的括号 ✌
代码实现:
栈
bool isValid(char *s) { char stack[10000]; int top = -1; while (*s) { if (*s == '(' || *s == '{' || *s == '[') { stack[++top] = *s; } else { if (top == -1) { // 栈空 return false; } int top_val = stack[top]; // 获取栈顶元素 if (top_val == '(' && *s != ')' || top_val == '[' && *s != ']' || top_val == '{' && *s != '}') { return false; } else { top--; } } s++; } return top == -1 ? true : false; }
2. 海贼OJ #595. 程序调用关系 ✌
代码实现:
#include <stdio.h> #include <string.h> int main(int argc, char *argv[]) { int n; scanf("%d", &n); char S[n][110]; for (int i = 0; i < n; i++) { scanf("%s", S[i]); } char s[110]; scanf("%s", s); char stack[n][110]; // 创建一个栈 int top = -1; int flag = 1; // 标记位 for (int i = 0; i < n; i++) { if (strcmp(S[i], "return") != 0) { strcpy(stack[++top], S[i]); } else if (top != -1) { top--; } if (top != -1 && strcmp(stack[top], s) == 0) { flag = 0; break; } } if (flag) { printf("NOT REFERENCED\n"); } else { for (int i = 0; i <= top; i++) { if (i) { printf("->"); } printf("%s", stack[i]); } putchar('\n'); } return 0; }
3. 海贼OJ #838. 2020年数据结构41题 😭
代码实现:
4. 比较含退格的字符串 ✌
代码实现:
方法一:栈
// 将字符串进栈 void Push(char *str, char *stack, int *top) { for (int i = 0; i < strlen(str); i++) { if (str[i] != '#') { stack[++(*top)] = str[i]; } else if (*top != -1) { (*top)--; } } stack[++(*top)] = '\0'; } bool backspaceCompare(char *s, char *t) { char *stack1 = malloc(sizeof(char) * (strlen(s) + 1)); int top1 = -1; char *stack2 = malloc(sizeof(char) * (strlen(t) + 1)); int top2 = -1; Push(s, stack1, &top1); Push(t, stack2, &top2); if (top1 != top2) { return false; } return strcmp(stack1, stack2) == 0; }
方法二:重构字符串
char* build(char *str) { int n = strlen(str), len = 0; char *ret = malloc(sizeof(char) * (n + 1)); for (int i = 0; i < n; i++) { if (str[i] != '#') { ret[len++] = str[i]; } else if (len > 0) { len--; } } ret[len] = '\0'; return ret; } bool backspaceCompare(char *s, char *t) { char *str_s = build(s); char *str_t = build(t); return strcmp(str_s, str_t) == 0; }
5. 海贼OJ #263. 火车进栈
代码实现:
#include <stdio.h> #include <stdbool.h> #include <string.h> int path[20], vis[21]; int pathSize; int len; int stack[20]; // 判断是否符合栈先进后出的要求 bool judge_one_result(int n) { int top = -1; int x = 1; for (int i = 0; i < n; i++) { if (top == -1 || stack[top] < path[i]) { while (x <= path[i]) { stack[++top] = x; x++; } } if (top == -1 || stack[top] != path[i]) { return false; } top--; } return true; } void dfs(int n) { // n:最大可以选取的数字 if (pathSize == n) { // 边界 if (judge_one_result(pathSize)) { if (len >= 20) { exit(0); // 结束所有程序 exit(0):表示程序正常退出,exit(1)或exit(-1)表示程序异常退出 } else { len++; for (int i = 0; i < n; i++) { printf("%d", path[i]); } putchar('\n'); } } return; } for (int i = 1; i <= n; i++) { if (vis[i]) { // 标记位思想 continue; } path[pathSize++] = i; vis[i] = 1; dfs(n); // 回溯 pathSize--; vis[i] = 0; } } int main(int argc, char *argv[]) { int n; scanf("%d", &n); pathSize = len = 0; memset(vis, 0, sizeof(vis)); dfs(n); return 0; }
难点:判断是否符合栈先进后出的要求
// 判断是否符合栈先进后出的要求 bool judge_one_result(int n) { int top = -1; int x = 1; for (int i = 0; i < n; i++) { if (top == -1 || stack[top] < path[i]) { while (x <= path[i]) { stack[++top] = x; x++; } } if (top == -1 || stack[top] != path[i]) { return false; } top--; } return true; }
6. 验证栈序列
代码实现:
bool validateStackSequences(int *pushed, int pushedSize, int *popped, int poppedSize) { int *stack = (int*)malloc(sizeof(int) * pushedSize); int top = -1; for (int i = 0, j = 0; i < pushedSize; i++) { stack[++top] = pushed[i]; while (top > -1 && stack[top] == popped[j]) { top--; j++; } } free(stack); return top == -1; }
7. 海贼OJ #265. 括号画家
代码实现:
记录匹配的下标
#include <stdio.h> int main(int argc, char *argv[]) { char str1[10000]; gets(str1); char *str = str1 - 1; // 让数组下标从1开始 int match[10001] = {0}; int stack[10000]; // 定义一个栈,存储数组下标 int top = -1; // 栈顶指针 for (int i = 1; str[i]; i++) { switch (str[i]) { case '(': case '[': case '{': stack[++top] = i; break; case ')': { if (top != -1 && str[stack[top]] == '(') { match[stack[top]] = i; match[i] = stack[top]; //delete 可以没有 top--; } else { stack[++top] = i; } } break; case ']': { if (top != -1 && str[stack[top]] == '[') { match[stack[top]] = i; match[i] = stack[top]; //delete 可以没有 top--; } else { stack[++top] = i; } } break; case '}': { if (top != -1 && str[stack[top]] == '{') { match[stack[top]] = i; match[i] = stack[top]; // delete 可以没有 top--; } else { stack[++top] = i; } } break; } } int temp_ans = 0, ans = 0, i = 1; while (str[i]) { if (match[i]) { temp_ans += (match[i] - i + 1); i = match[i] + 1; } else { i += 1; temp_ans = 0; } if (temp_ans > ans) { ans = temp_ans; } } printf("%d\n", ans); return 0; }
8. 设计循环队列
代码实现:
9. 简化路径 ✌
代码实现:
// 分割'/'得到名字 char **split(const char *s, int *returnSize) { int n = strlen(s); char **ans = (char **)malloc(sizeof(char *) * n); int l = 0, r = 0, len = 0; while (r < n) { while (l < n && s[l] == '/') { l++; } r = l; while (r < n && s[r] != '/') { r++; } if (l < n) { ans[len] = (char*)malloc(sizeof(char) * (r - l + 1)); strncpy(ans[len], s + l, r - l); ans[len][r - l] = '\0'; len++; } l = r; } *returnSize = len; return ans; } char *simplifyPath(char *path){ int namesSize = 0; int n = strlen(path); char **names = split(path, &namesSize); char **stack = (char**)malloc(sizeof(char*) * namesSize); int top = -1; for (int i = 0; i < namesSize; ++i) { if (!strcmp(names[i], "..")) { // 遇到".." if (top > -1) { top--; } } else if (!strcmp(names[i], ".")) { // 遇到"." 跳过 continue; } else { if (top == -1 || strcmp(stack[top], names[i])) { // 遇到目录名 stack[++top] = names[i]; } } } char *ans = (char*)malloc(sizeof(char) * (n + 1)); int ind = 0; if (top == -1) { ans[ind] = '/'; ind++; } else { for (int i = 0; i <= top; i++) { ans[ind++] = '/'; strcpy(ans + ind, stack[i]); ind += strlen(stack[i]); } } ans[ind] = '\0'; for (int i = 0; i < namesSize; i++) { free(names[i]); } free(names); free(stack); return ans; }
10. 栈排序 ✌
代码实现:
typedef struct { int data[5000]; int top; } SortedStack; SortedStack* sortedStackCreate() { SortedStack *s = malloc(sizeof(*s)); s->top = -1; return s; } int min_ind(SortedStack *obj) { if (obj == NULL || obj->top == -1) { return -1; } int min = 0; for (int i = 1; i <= obj->top; i++) { if (obj->data[min] > obj->data[i]) { min = i; } } return min; } void sortedStackPush(SortedStack *obj, int val) { if (obj == NULL) { return; } obj->data[++obj->top] = val; // 更新最小值到栈顶 int ind = min_ind(obj); if (ind != obj->top) { int t = obj->data[ind]; obj->data[ind] = obj->data[obj->top]; obj->data[obj->top] = t; } } void sortedStackPop(SortedStack *obj) { if (obj == NULL || obj->top == -1) { return; } obj->top--; // 更新最小值到栈顶 int ind = min_ind(obj); if (ind == -1 || ind == obj->top) { return; } int t = obj->data[ind]; obj->data[ind] = obj->data[obj->top]; obj->data[obj->top] = t; } int sortedStackPeek(SortedStack *obj) { if (obj == NULL || obj->top == -1) { return -1; } return obj->data[obj->top]; } bool sortedStackIsEmpty(SortedStack *obj) { if (obj == NULL) { return true; } return obj->top == -1; } void sortedStackFree(SortedStack *obj) { if (obj == NULL) { return; } free(obj); } /** * Your SortedStack struct will be instantiated and called as such: * SortedStack* obj = sortedStackCreate(); * sortedStackPush(obj, val); * sortedStackPop(obj); * int param_3 = sortedStackPeek(obj); * bool param_4 = sortedStackIsEmpty(obj); * sortedStackFree(obj); */