当前位置:首页 > 洛谷 > 洛谷P1106题【删除K个数字得到最小数】解题思路与C++代码详解

洛谷P1106题【删除K个数字得到最小数】解题思路与C++代码详解

7个月前 (09-23)

洛谷P1106题【删除K个数字得到最小数】解题思路与C++代码详解 洛谷题解 栈结构 单调栈 C++ 第1张

一、题目解读

洛谷P1106题要求给定一个数字串num和整数k,通过删除num中的k个数字,得到一个最小的可能结果。题目需注意处理前导零(如删除后全为0需返回"0")及数字串本身的非负特性。核心在于如何在删除操作中保持数字顺序并最小化结果。

二、解题思路

采用单调栈优化策略:

1. 维护一个单调递增的,从num左到右遍历数字。

2. 若栈顶数字大于当前数字且k未用完,则弹出栈顶(删除较大数),直至栈顶小于等于当前数字或k耗尽。

3. 遍历结束后,若k仍有剩余,从栈末尾删除对应数字(末尾数字对结果影响最小)。

4. 去除栈中元素构成的新串的前导零,确保结果合法。

三、解题步骤

1. 初始化:创建栈存储数字,k记录剩余删除次数。

2. 遍历数字串:

○ 若栈不空且栈顶>当前数字且k>0,弹出栈顶并k减1。

○ 将当前数字入栈。

3. 处理剩余k:若k未耗尽,从栈末尾弹出对应元素。

4. 构建结果:去除前导零后拼接栈中元素,空串则返回"0"。

四、代码与注释

#include <iostream>
#include <string>
#include <vector>
using namespace std;

// 删除k个数字得到最小数
string removeKDigits(string num, int k) {
    vector<char> stack;  // 单调栈,存储递减序列
    
    for (char digit : num) {  // 遍历数字串
        while (!stack.empty() && k > 0 && stack.back() > digit) {  // 若栈顶大于当前数字且可删除
            stack.pop_back();  // 弹出栈顶(删除较大数)
            k--;
        }
        stack.push_back(digit);  // 当前数字入栈
    }
    
    while (k-- > 0) {  // 处理剩余k:末尾删除
        stack.pop_back();
    }
    
    string result;
    bool leadingZero = true;  // 标记前导零
    for (char digit : stack) {
        if (leadingZero && digit == '0') continue;  // 跳过前导0
        leadingZero = false;
        result += digit;
    }
    return result.empty()? "0" : result;  // 空串返回0
}

int main() {
    string num;
    int k;
    cin >> num >> k;
    cout << removeKDigits(num, k) << endl;
    return 0;
}

五、总结

本解法通过单调栈巧妙地将删除操作转化为栈维护问题,核心逻辑在于“优先删除较大的数字以保留较小数字的左侧位置”,时间复杂度O(n),适用于需优化数字序列的算法场景。需特别注意前导零处理以避免结果错误。


原创内容 转载请注明出处

分享给朋友:

相关文章

力扣746:三步通关最小花费爬楼梯

力扣746:三步通关最小花费爬楼梯

题目解析:站在楼梯的某个台阶时,需要支付当前台阶对应的体力值cost[i],之后可以选择向上爬1或2个台阶。最终目标是到达‌楼层顶部‌(即数组末尾之后的位置),且初始位置可选择下标0或1的台阶作为起点...

力扣965题深度解析:单值二叉树的判断技巧

力扣965题深度解析:单值二叉树的判断技巧

重新解读题目 判断一棵二叉树是否为“单值二叉树”,即所有节点的值是否完全相同。题目看似简单,实则考验对树结构递归特性的理解。若一棵树的所有节点值相同,其必然满足:根节点与左右子树的值一致,且...

标题:洛谷B3617题解析:八进制转十六进制算法实现与优化(附AC100代码)

标题:洛谷B3617题解析:八进制转十六进制算法实现与优化(附AC100代码)

一、题目解读洛谷B3617题要求将输入的八进制字符串转换为十六进制表示。题目需处理大数场景,且对输入合法性有明确限制(长度不超过1000,仅包含0-7字符)。由于八进制与十六进制无法直接转换,需借助十...

力扣3112题解法:带时间限制的最短路径问题解析(C++代码)

力扣3112题解法:带时间限制的最短路径问题解析(C++代码)

一、题目解读力扣3112题要求解决带时间限制的最短路径问题:给定一个有向图,节点具有消失时间,需计算从起点到各节点的最短路径,且路径总时间不能超过节点的消失时间。题目难点在于需在传统最短路径算法(如D...

洛谷1220题解:动态规划与区间DP优化解法(附代码注释)

洛谷1220题解:动态规划与区间DP优化解法(附代码注释)

一、题目解读洛谷1220题要求计算在n个位置放置灯的情况下,通过关闭连续区间灯并移动至区间端点,使得总耗电量最小。需考虑灯的功率与位置差异,设计高效的算法求解最优策略。二、解题思路1. 动态规划 +...

洛谷1656题解:基于Tarjan算法求解割边问题(附代码与详细步骤)

洛谷1656题解:基于Tarjan算法求解割边问题(附代码与详细步骤)

一、题目解读洛谷1656题要求在无向图中找出所有割边(即删除后导致图不连通的边)。题目核心在于判断图的连通性,并识别哪些边是“桥”。需理解图论中的连通分量概念,以及如何通过算法高效定位割边。二、解题思...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。