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秒