zoukankan      html  css  js  c++  java
  • [leetcode-402-Remove K Digits]

    Given a non-negative integer num represented as a string, remove k digits from the number so that the new number is the smallest possible.

    Note:

    • The length of num is less than 10002 and will be ≥ k.
    • The given num does not contain any leading zero.

    Example 1:

    Input: num = "1432219", k = 3
    Output: "1219"
    Explanation: Remove the three digits 4, 3, and 2 to form the new number 1219 which is the smallest.
    

    Example 2:

    Input: num = "10200", k = 1
    Output: "200"
    Explanation: Remove the leading 1 and the number is 200. Note that the output must not contain leading zeroes.
    

    Example 3:

    Input: num = "10", k = 2
    Output: "0"
    Explanation: Remove all the digits from the number and it is left with nothing which is 0.
    

    思路:

    观察得到,当一个数字序列是增序的时候,删除最大那个数字即满足余下数字最小,比如1254,删除5得到124是最小的。

    那么问题转化为,求递增序列,然后将连续递增序列的最大字符删除,k-1,余下的字符串继续刚才的过程。

    思路比较简单,但是。。递归写法太耗空间和时间,没法通过最后一个字符串比较长的测试用例。

     string removeKdigits(string num, int k) 
     { 
       if(k==0)
       {
         if(num == ""||num.length() == 0) return "0";
        // if( num[0]!='0')return num;
         int i =0;
         while(num[i]=='0')i++;
         if(i >= num.length())return "0";
         return num.substr(i);
      }
      int index =0;
      while(index+1<num.length() && num[index]<=num[index+1] )index++;//找到最大的
      string left = num.substr(0,index);
      string right ;
      if(index+1<num.length()) right = num.substr(index+1);
      else right ="";
      return removeKdigits(left+right,k-1);
    }

    又学习了大牛的方案:

    参考自:https://discuss.leetcode.com/topic/59871/two-algorithms-with-detailed-explaination

    he first algorithm is straight-forward. Let's think about the simplest case: how to remove 1 digit from the number so that the new number is the smallest possible? Well, one can simply scan from left to right, and remove the first "peak" digit; the peak digit is larger than its right neighbor. One can repeat this procedure k times, and obtain the first algorithm:

    string removeKdigits(string num, int k) {
            while (k > 0) {
                int n = num.size();
                int i = 0;
                while (i+1<n && num[i]<=num[i+1])  i++;
                num.erase(i, 1);
                k--;
            }
            // trim leading zeros
            int s = 0;
            while (s<(int)num.size()-1 && num[s]=='0')  s++;
            num.erase(0, s);
            
            return num=="" ? "0" : num;
        }

    The above algorithm is a bit inefficient because it frequently remove a particular element from a string and has complexity O(k*n).

    One can simulate the above procedure by using a stack, and obtain a O(n) algorithm. Note, when the result stack (i.e. res) pop a digit, it is equivalent as remove that "peak" digit.

    string removeKdigits(string num, int k) {
            string res;
            int keep = num.size() - k;
            for (int i=0; i<num.size(); i++) {
                while (res.size()>0 && res.back()>num[i] && k>0) {
                    res.pop_back();
                    k--;
                }
                res.push_back(num[i]);
            }
            res.erase(keep, string::npos);
            
            // trim leading zeros
            int s = 0;
            while (s<(int)res.size()-1 && res[s]=='0')  s++;
            res.erase(0, s);
            
            return res=="" ? "0" : res;
        }
  • 相关阅读:
    快速排序
    jenkins 升级
    JAVA中的Random()函数
    拦截器
    两个链表合并不加入新的链表空间
    统计字符 比如aaabbcca----3a2b1c1a
    折半查找两种实现
    字符串偏移
    java值传递
    基于zookeeper实现配置集中管理【转】
  • 原文地址:https://www.cnblogs.com/hellowooorld/p/7101971.html
Copyright © 2011-2022 走看看