删除k个数字后的最小值

298 阅读2分钟

题目:给出一个整数,从该整数中去掉 k 个数字,要求剩下的新整数尽可能的小

例子:

1593212 删去 3 个数字 新整数的最小情况是 1212

30200 删除1个数字 新整数的最小情况是 200

10 删去2个数字 新整数最小情况是 0

思路:

例如,给出一个 整数 541 270 936 要求删去一个数字,让剩下的整数尽可能小

那么无论删除哪个数字,最后的结果都是从 9 位整数变成 8 位整数,则,同样是八位整数,显然应该优先把高位数字降低,这样对新整数的影响最大

即:把原整数的所有数字,从左到右进行比较,如果发现某一位数字大于它右侧的数字,则删除该数字后,会使该数位的值降低

像这样依次求得局部最优解,最终得到全局最优解的思想,叫做贪心算法

实现代码

    function deleteAfterMinNumV1(num:string, k:number) {
        let numStr = num;
        for (let index = 0; index < k; index++) {
            let hasCut = false
            for (let j = 0; j < numStr.length - 1; j++) {
                if(numStr[j] > numStr[j+1]) {
                    numStr = numStr.slice(0, j) + numStr.slice(j+1);
                    hasCut = true;
                    break;
                }
            }
            // 没有找到要删除的数字,就删除最后一个
            if(!hasCut) {
                numStr = numStr.slice(0, numStr.length - 1)
            }
        }
        // 删除开头的 0 
        while(numStr[0] === '0') {
            numStr = numStr.slice(1, numStr.length)
        }
        if(numStr.length === 0) {
            return '0'
        }
        return numStr
    }

此算法时间复杂度为 O(kn)

此外存在一个问题:内循环每次遍历都从头开始遍历,优化方法为从上次删除的位置开始遍历

优化版本

  function deleteAfterMinNumV2(num:string, k:number) {
      // 创建一个栈  用于接收所有数据
      let stack = [];
      let deleteNum = k
      let newNumLength = num.length - k
      for (let index = 0; index < num.length; index++) {
          // 当当前数组小于栈顶数字是  栈顶出栈  当前数字入栈
          while(stack.length && stack[stack.length -1] > num[index] && deleteNum > 0) {
              stack.pop()
              deleteNum --
          }
          stack.push(num[index])
      }
      // 这里是没有找到删除的数字 把最后的删除
      if(stack.length > newNumLength) {
          stack = stack.slice(0, newNumLength)
      }
      // 除去开头的0
      while(stack[0] === '0') {
          stack.shift()
      }
      if(stack.length === 0) {
          return '0'
      }
      return stack.join('')
  }

利用栈的回溯性,只对原数字遍历了一次,时间复杂度为 O(n),

利用栈来储存数字和删除数字,空间复杂度为 O(n)

摘要总结自: 漫画算法 小灰的算法之旅