• Unreal is funny !!!

leetcode 402. Remove K Digits

刷题 站长 5年前 (2020-05-01) 1087次浏览 已收录 0个评论
文章目录[隐藏]

5月1日,劳动节第一天,花了大半个下午思考这道题,独立思考解决的感觉很爽。

题干

https://leetcode.com/problems/remove-k-digits/

对一个数字num删掉k个字符,求怎么删使留下字符组成的数字是最小的?

思考过程

好吧,一个很费脑的感觉,又是一个掉脑细胞的问题。 解决这种问题,其实考的就是观察能力和直觉。怎么删使留下的数字最小?本帅脑子里并没有相关的知识模型,学了十几年的数学里也没有这玩意啊,那就自己总结吧。

第一步就是在纸上多演示几个例子,感受这种过程,只有熟悉过程才能总结。

经历了多种猜想,先从简单的开始,删一个怎么删?写几遍就会发现,被删掉的数字 是这样被找到的: 从最左边开始找,第一个峰值,所谓峰值,就是 大于等于左边的数,大于右边的数,为什么是这个呢? 如果你删峰值左边的数,其实数字是变大了,不如删峰值呢,如果你删右边的,还是不如删峰值。

好啦,那删两个怎么删? 设数列 (x1,x2,x3….xl),删掉 第 m 和 n 个数是最小的,设删掉后的数字是 f(m,n), 我们能不能转化成删掉一个使最小,再删掉一个使最小呢 ? 验证一下,的确是的,于是我们得出一个结论:

如果 f(m,n) 是随意删掉两个的后最小的,则我们一个一个删,第一次删1 个 ,f(x)是删掉第x个的最小值,第二次删 是在第一次删掉的基础上,删掉 第y个后最小,为 f(x,y) ,则 f(x,y) = f(m,n)

证明:

f(x,n)<=f(m,n) 因为x是删掉第n个后删一个最小的,

f(m,n) <=f (x,y) 因为这是 f(m,n)的定义

f (x,y)<=f(x,n) , 这是 题目要求,

于是

f(x,n)<=f(m,n) <=f (x,y)<=f(x,n)

也就是说,我们可以把删两次最小 转化成 一次删一个,使其最小。那对于多个,其实也是一样的,只要把y改成多维的就好啦。

代码

我们求删掉k个最小,只需求删 k次一个的,只要让按删一个最小的算法 进行k次就好啦

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

class Solution {
    public static String removeKdigits(String num, int k) {
        //对特殊情况处理
        if (k == 0 || num.length() == 0) {
            return num;
        }
        if (k == num.length()) {
            return "0";
        }
        //转换成int数组
        List<Integer> list = new ArrayList<>();
        char[] chars = num.toCharArray();
        for (char c : chars) {
            list.add(c - '0');
        }
        for (int i = 0; i < k; i++) {
            //找到一个峰值然后删掉
            int shoudRemoveIndex = 0;//应该删掉的数的下标
            do {
                if (shoudRemoveIndex == list.size() - 1) {
                    break;
                }
                if (list.get(shoudRemoveIndex) > list.get(shoudRemoveIndex + 1)) {
                    //找到了一个峰值
                    break;
                }
                shoudRemoveIndex++;
            } while (shoudRemoveIndex <= list.size() - 1);
            list.remove(shoudRemoveIndex);
        }
        //删掉开头的0
        Iterator<Integer> iterator = list.iterator();
        while (iterator.hasNext()) {
            if (iterator.next() == 0) {
                iterator.remove();
            } else {
                break;
            }
        }
        StringBuilder res = new StringBuilder();
        iterator = list.iterator();
        while (iterator.hasNext()) {
            res.append(iterator.next());
        }
        String resString = res.toString();
        return resString.isEmpty() ? "0" : resString;
    }
}

 

总结

每次解决一次看起来自己做不出来的题的时候都很开心,成就感很爽


本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:leetcode 402. Remove K Digits
喜欢 (0)
[]
分享 (0)
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址