Leetcode_402_移掉k个数字_贪心

本文记录了作者在解决一个数值最小化问题时,使用C++和Java两种语言实现算法的过程。作者首先分享了自己的C++解决方案,然后对比了一个高效的O(1)空间复杂度的解法,并将其翻译为Java代码。文章通过代码对比展示了两种语言在编写效率和安全性上的差异,并提供了性能测试结果,C++代码耗时24秒,而Java代码仅耗时4秒。
摘要由CSDN通过智能技术生成

11/15

杂记:

daily_algorithm的第一天
在用一个很蠢的思路写完程序后,心血来潮的去看了看耗时最短的题解,然后按照它的思路仿写了一下。
接着又心血来潮(我也不知道为啥这么多心血来潮)地写了写java版本的代码。
就纯对着我自己写的c艹代码翻译的
写了快一个小时
算是深刻体会到了Java与c艹的不同之处吧。
Java的代码写起来极其繁琐,但相对应的,安全性要高的多。
对比下面JAVA和c艹的代码就能很明显的发现二者之间的区别。
这也是我第一次用markdown写东西QAQ

题目

给定一个以字符串表示的非负整数 num,移除这个数中的 k 位数字,使得剩下的数字最小。

注意:

num 的长度小于 10002 且 ≥ k。
num 不会包含任何前导零。

我的代码:

思路的话贪心很容易想,贪心首位。
因为最高位的权重在整个数中最大 即10^(n-1)
所以如果第一个数比第二个数大,那么就删除第一个数,让第二个数成为首位

特殊情况1:第一个数和第二个数一样大

举个例子:119 k=1,明显应该删除9而不是1
所以第一个数和第二个数相同的情况下,应该跳过不处理

特殊情况2:最后只剩下一位数 k=1

直接返回“0”

特殊情况3:最后删得只剩下一个0

不要把这个0当作前导0删除,特判一下
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
    string removeKdigits(string num, int k) {
        int st=0;
        while(k!=0)
        {
            if(num.size()<=1)
                    return "0";
            if(num[st]>num[st+1])
            {
                num.erase(st,1);
                k--;
                st--;
                if(st==-1) st=0;
            }
            else st++;
            while(num[0]=='0'&&num.size()!=1)
            {
                num.erase(0,1);
            }
        }
        return num;
    }
};

最佳代码:

O(1)处理
设定一个答案串,遍历字符串,如果字符串的当前位比答案串的最后位要小,则将答案串最后一位删去,k--。
最后删除前导0以及特判删光的情况
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
    string removeKdigits(string num, int k) {
        string ans;
        ans.push_back(num[0]);
        for (int i = 1; i < num.size();i++)
        {
            while(ans.back()>num[i]&&k!=0)
            {
                ans.pop_back();
                k--;
            }
            ans.push_back(num[i]);
        }
        while(k--!=0)
            ans.pop_back();
        int pos = 0;
        while(ans[pos]=='0')
            pos++;
        ans=ans.substr(pos);
        return ans=="" ? "0" : ans;
    }
};

最佳代码JAVA:

class Solution {
    public String removeKdigits(String num, int k) {
        StringBuilder ans=new StringBuilder();
        ans.append(num.charAt(0));
        for (int i = 1; i < num.length();i++)
        {
            while(ans.length()-1>=0&&ans.charAt(ans.length()-1)>num.charAt(i)&&k!=0)
            {
                ans.deleteCharAt(ans.length()-1);
                k--;
            }
            ans.append(num.charAt(i));
        }
        while(ans.length()-1>=0&&k--!=0)
            ans.deleteCharAt(ans.length()-1);
        while(ans.length()>=2&&ans.charAt(0)=='0')
            ans.deleteCharAt(0);
        return (ans.length()==0) ? "0" : ans.toString();
    }
}

耗时

我的代码:24秒
最佳代码:0秒
最佳代码JAVA:4秒
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值