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

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

2个月前 (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),适用于需优化数字序列的算法场景。需特别注意前导零处理以避免结果错误。


原创内容 转载请注明出处

分享给朋友:

相关文章

力扣第1991题:寻找数组的中心索引 如何找到左右和相等的中心索引

力扣第1991题:寻找数组的中心索引 如何找到左右和相等的中心索引

题目解读给定一个整数数组,我们需要找到一个中心索引,使得该索引左侧所有元素的和等于右侧所有元素的和。如果不存在这样的索引,则返回-1。中心索引的定义不包含在左右两侧的和计算中。这个问题考察对数组遍历和...

NOIP2005 普及组 洛谷P1408 背包问题的空间优化技巧与实战应用

NOIP2005 普及组 洛谷P1408 背包问题的空间优化技巧与实战应用

题目重解想象你是一名药师,有t分钟在山上采集m种草药。每种草药需要time分钟采集,价值为num。这就像考试时分配时间做题,要选择收益最大的题目组合。题目要求计算在规定时间内能获得的最大草药价值。解题...

手搓顺序表类代码注释与详解:从零实现动态数组(新手教程)

一、简介和特点顺序表(Sequential List)是数据结构中基础的一种线性表,其特点是将数据元素存储在连续的内存空间中。通过数组实现,支持随机访问(即通过索引直接访问元素),适用于频繁随机读取的...

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

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

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

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

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

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

【洛谷1184题解析】用C++高效解决地点匹配问题(附代码与解题思路)

【洛谷1184题解析】用C++高效解决地点匹配问题(附代码与解题思路)

一、题目解读洛谷1184题要求处理一组地点列表与行程记录,统计其中匹配的天数。题目难点在于高效处理带有空格的字符串输入,以及快速判断每日行程是否在高手可去地点集合中。需要兼顾输入格式解析与算法效率。二...

发表评论

访客

看不清,换一张

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