top1编程
← 返回题目
题解

【基础】删数问题

1 条题解

  • 0
    @ 2026-7-31 18:13:56

    解题思路

    从一个高精度整数里删掉 s 个数字,剩下的数要最小。

    思路:贪心 — 每次删掉第一个比后面大的数字。

    1. 重复 s 次:
      • 从左到右找第一个 s[j] > s[j+1] 的位置
      • 删掉 s[j](因为高位的较大数被删后,数变得更小)
      • 如果找不到(整个数递增),就删最后一个
    2. 去掉前导 0,输出剩下的数

    为什么要删第一个比后面大的? 拿 153748 为例:

    • 从左看,1<5, 5>3(找到了)删 5 → 13748
    • 再找,1<3, 3<7, 7>4(找到了)删 7 → 1348

    从高位往低位,遇到一个山峰(前比后大),删掉前面的,就能让这一位变小,后面的跟着变小。

    参考代码

    #include <iostream>
    #include <string>
    using namespace std;
    
    int main() {
        string s;
        int n;
        cin >> s >> n;
    
        for (int i = 1; i <= n; i++) {
            int p = s.size() - 1;  // 默认删最后一个
            for (int j = 0; j < s.size() - 1; j++) {
                if (s[j] > s[j + 1]) {  // 找到山峰
                    p = j;
                    break;
                }
            }
            s.erase(p, 1);
        }
    
        // 去掉前导 0
        int x = 0;
        for (int i = 0; i < s.size(); i++) {
            if (s[i] != '0') { x = i; break; }
        }
        for (int i = x; i < s.size(); i++) cout << s[i];
        return 0;
    }
    

    复杂度分析

    • 时间复杂度:O(S×N),S 为删除次数
    • 空间复杂度:O(N)
    • 1