目录
402. 移掉 K 位数字
题目描述
解题思路
代码实现
17. 电话号码的字母组合
题目描述
解题思路
代码实现
402. 移掉 K 位数字
题目描述
给你一个以字符串表示的非负整数 num 和一个整数 k ,移除这个数中的 k 位数字,使得剩下的数字最小。请你以字符串形式返回这个最小的数字。
示例 1 :
输入:num = "1432219", k = 3 输出:"1219" 解释:移除掉三个数字 4, 3, 和 2 形成一个新的最小的数字 1219 。
示例 2 :
输入:num = "10200", k = 1 输出:"200" 解释:移掉首位的 1 剩下的数字为 200. 注意输出不能有任何前导零。
示例 3 :
输入:num = "10", k = 2 输出:"0" 解释:从原数字移除所有的数字,剩余为空就是 0 。
提示:
- 1 <= k <= num.length <= 105
- num仅由若干位数字(0 - 9)组成
- 除了 0 本身之外,num不含任何前导零
解题思路
利用单调栈的思想来移除字符串中的k个数字,使得剩下的数字组成的数最小。
-  初始化: - 获取输入字符串num的长度length。
- 初始化一个栈stack,用于存放结果。栈的大小为length + 1,因为最后还需要存放一个字符串结束符\0。
- 初始化栈顶指针top为-1,表示栈为空。
- 初始化遍历索引i为0。
 
- 获取输入字符串
-  遍历输入字符串: - 对于输入字符串中的每个字符,进行以下操作: - 如果栈不为空且栈顶元素大于当前字符,并且还有剩余要移除的字符数k,那么将栈顶元素弹出,同时k减1。这一步是为了确保栈内的元素是单调递增的,这样可以确保得到的数最小。
- 如果当前字符不是'0'或者栈不为空,那么将当前字符压入栈中。这里有一个条件判断是为了避免在结果的最前面出现前导零。
 
- 如果栈不为空且栈顶元素大于当前字符,并且还有剩余要移除的字符数
 
- 对于输入字符串中的每个字符,进行以下操作: 
-  处理剩余的移除次数: - 如果遍历完输入字符串后还有剩余的移除次数k,那么继续从栈顶弹出元素,直到移除次数用完或者栈为空。
 
- 如果遍历完输入字符串后还有剩余的移除次数
-  处理特殊情况: - 如果栈为空(即所有字符都被移除了),那么需要在栈中放入一个'0'字符。
 
-  结束处理: - 在栈顶放入一个字符串结束符\0。
- 返回栈的地址作为结果。
 
- 在栈顶放入一个字符串结束符
代码实现
char* removeKdigits(char* num, int k) {int length = strlen(num), top = -1, i = 0;char* stack = (char*)malloc(sizeof(char) * (length + 1));for (i; i < length; i++) {while (top != -1 && stack[top] > num[i] && k > 0) {top--;k--;}if (num[i] != '0' || top != -1)stack[++top] = num[i];}while (k > 0 && top > -1) {top--;k--;}if (top == -1)stack[++top] = '0';stack[++top] = '\0';return stack;
}
17. 电话号码的字母组合
题目描述
给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。
给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。

示例 1:
输入:digits = "23" 输出:["ad","ae","af","bd","be","bf","cd","ce","cf"]
示例 2:
输入:digits = "" 输出:[]
示例 3:
输入:digits = "2" 输出:["a","b","c"]
提示:
- 0 <= digits.length <= 4
- digits[i]是范围- ['2', '9']的一个数字。
解题思路
- 初始化: - 定义二维字符数组 map,将每个数字映射到其对应的字母集合。
- 定义全局变量 path(用于存储当前组合),ans(用于存储所有组合),pathsize和anssize(分别用于跟踪path和ans的大小),以及n(输入数字字符串的长度)。
 
- 定义二维字符数组 
- letterCombinations 函数: - 获取输入数字字符串的长度 n。
- 为 path和ans分配内存空间。
- 检查如果 n为0,则直接返回空数组,并设置returnSize为0。
 
- 获取输入数字字符串的长度 
- 回溯函数 backtrace: - 递归终止条件:如果已处理完所有数字字符(idx == n),则复制当前path到新字符串temp,并将temp添加到ans数组中。
- 递归过程: - 获取当前数字字符在 map中对应的字母集合words。
- 遍历 words中的每个字母:- 将当前字母添加到 path中。
- 递归调用 backtrace函数处理下一个数字字符。
- 回溯:将 path中的最后一个字母移除,以尝试words中的下一个字母。
 
- 将当前字母添加到 
 
- 获取当前数字字符在 
 
- 递归终止条件:如果已处理完所有数字字符(
- 返回结果: - 在 letterCombinations函数中,将anssize赋值给returnSize。
- 返回 ans数组,其中包含了所有可能的字母组合。
 
- 在 
代码实现
/*** Note: The returned array must be malloced, assume caller calls free().*/
char map[10][5] = {"",    "",    "abc",  "def", "ghi","jkl", "mno", "pqrs", "tuv", "wxyz"};
char* path;
char** ans;
int pathsize, anssize, n;
void backtrace(int idx, char* digits) {if (idx == n) {char* temp = (char*)malloc(sizeof(char) * (n + 1));for (int i = 0; i < n; i++)temp[i] = path[i];temp[n] = '\0';ans[anssize++] = temp;return;}char* words = map[digits[idx] - '0'];for (int i = 0; i < strlen(words); i++) {path[pathsize++] = words[i];backtrace(idx + 1, digits);pathsize--;}
}
char** letterCombinations(char* digits, int* returnSize) {n = strlen(digits);path = (char*)malloc(sizeof(char) * n);ans = (char**)malloc(sizeof(char*) * 300);anssize = pathsize = 0;if (n == 0) {*returnSize = 0;return ans;}backtrace(0, digits);*returnSize = anssize;return ans;
}