2023-07-14力扣今日二题-好题

链接:

402. 移掉 K 位数字

题意:

一个非负整数,求删除k位数字后的最小值

解:

要想数字最小,核心就是先让高位的最小,然后在考虑后面的数字

解1 原型:(TLE LG=1E5 num=“5E4个1 append 5E4个2” K=5E4)

维护一个剩余可选择的数字数量和一个还需要的数字数量,可以得到一个可选择的范围,每次从可选择范围内获取最小的数字作为最高位,然后更新剩余可选择的数字数量和还需要的数字数量

解1 优化:

超时主要原因是获取范围内最小数字需要遍历整个范围,一旦最小数字的位置太靠前,就要返回到很前面的位置(有点像是字符串暴力匹配的缺点,蛤蛤),所以写了一个前缀,这样就可以在10次只内判断出最小数字,然后遍历的时候直接遇到这个数字就更新剩余可选择的数字数量和还需要的数字数量,找下一位数字

解2 单调栈:

按滑动窗口思路,案例1:num1432219 k3 所以保留7-3=4位数

1432 + 2 -> 1322 + 1 -> 1221 + 9 -> 1219 每次删除窗的最大数字,如果每次都在窗内搜索,就变成和解法1一样了

所以要点在于,如果有删除次数,且后面一位比前一位小,就先删除前面的(同时由于遍历过程是从前往后,所以前面的数字是高位,相当于高位的数字由大的换为小的),即从小到大的单调栈

最后如果还有剩余删除次数,就要从后面删去,因为这个步骤是要删除超过所需位数的数字,且越后面数字越大

实际代码:

解1 含原型:

#include
#include
using namespace std;
const int Nmax=1E5+7;
int arr[10][Nmax];
char get_mao(int left,int right)
{
    //cout<<"left:"<=lg) return string("0");
    for(int i=0;i>num;
    int k;cin>>k;
    
    string ans=removeKdigits(num,k);
    cout<=lg) return string("0");
    int last=lg,need=lg-k,mao=0;//last 剩余数字 need 所需数字 mao所选最小数字位置 
    for(int i=0;i

解2:

#include
#include
using namespace std;
string removeKdigits(string num, int k)
{
    string temp,ans;int lg=num.length();
    if(k>=lg) return string("0");
    for(int i=1;i>num;
    int k;cin>>k;
    
    string ans=removeKdigits(num,k);
    cout<

限制:

  • 1 <= k <= num.length <= 105
  • num 仅由若干位数字(0 - 9)组成
  • 除了 0 本身之外,num 不含任何前导零

你可能感兴趣的:(力扣每日一题,leetcode,数据结构)