点击上方
蓝字
设为星标
1 前言
今天来写一道leetcode的中等难度的题目,声明一下:
这不是最优解,就是常规思路
。
之所以写出来,是因为我觉得:如果你的想法比较复杂或者比较冗长,那也没关系,写出来ac了它,能绕过层层关卡做出来同样值得。
就好像我们新接手了同事的代码,第一反应可能是这么复杂,但是竟然还能跑,所以尽管很绕,但是没有把他绕晕,那么我觉得他也挺厉害的了。
工作中我就遇到过这样的代码,同事的开发能力比较强,但是代码风格跟我差别很大,期间接过他一点代码,可能是过设计了,但是运行得很好。
在我们没有做那么多题目的前提下,
第一想法很重要
,面试的时候往往很紧张,把握住你的第一想法去实现它,最终做出来足够让面试官觉得你还不错,在此基础上优化就是加分。
有些题目的最优解或者优化解并不好想,如果不是acm打手或者天资异禀的高手还是有难度的。
所以不要嫌弃这不是最优解,最起码这是最容易想到的解法,当然你们也可以觉得不是最优解没有意义,非要嫌弃鄙视一下,那也么得办法,啊哈哈。
废话不说,开车开车!
2.题目描述
给定两个以字符串形式表示的非负整数 num1 和 num2,
返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。
示例 1:
输入: num1 = "2", num2 = "3"
输出: "6"
示例 2:
输入: num1 = "123", num2 = "456"
输出: "56088"
说明:
num1 和 num2 的长度小于110。
num1 和 num2 只包含数字 0-9。
num1 和 num2 均不以零开头,除非是数字 0 本身。
不能使用任何标准库的大数类型(比如 BigInteger)或直接将输入转换为整数来处理。
3.题目分析
这个题目描述也比较清晰了,就是给了两个字符串格式的数字,让返回两个数的乘积字符串。
题目限定了不要使用bigint和输入转整数这种系统的机制,并且给定了num1和num2的长度小于110,这也说明了长度可能是100那么长,110位就已经非常大了,所以不要考虑转换整数的想法了。
其实这个问题很熟悉,这就是个计算器嘛,我们要把很长的两个字符串相乘。
第一想法就是那模拟一下两个数相乘的具体过程,再转换为代码,是的,这个想法就足够了。
4.手动模拟
来吧,有了第一想法,那就开始在纸上划拉划拉。
在纸上大致模拟了一下之后,基本上就能把握几个点了:
-
乘数和被乘数的两个循环
在计算循环过程中,涉及到一个默认补0的过程,因为数字所在的位不一样,这样是要注意的,这样我们得到三个字符串,这三个字符串本质上是逆序的,因为我们是先从低位开始计算的。
-
各个临时结果的累加
也就是图中的第二部分,这里是把多个临时结果累加就可以了,最开始我把第一部分的结果做了reverse,但是在第二部分累加时发现没有必要,最后把结果reverse一下即可。
-
细节问题
在基本了解流程之后,肯定会有一些需要注意的致错细节,这个很多时候是debug时发现的,这道题我代码写完之后debug出两个错误的点,反过来想是细节考虑不周全。
4.我的糙代码
代码提交了几次才通过,看下时间和空间:
无奈同行们太优秀,被80%的同行大败了,不过就算反面教材也可以看看吧:
class Solution {
public:
int getvalue (string &num, int index){
return num[index]-'0';
}
void calthem(vector<string> &resvec, int maxlen, string &resstr){
int veclen = resvec.size();
int jinwei = 0;
for(int i=0;i
int this_sum = 0;
this_sum += jinwei;
for(int j=0;j
if(i
this_sum+=getvalue(resvec[j],i);
}
}
jinwei = this_sum/10;
int remain = this_sum%10;
resstr+=to_string(remain);
}
if(jinwei!=0)
resstr+=to_string(jinwei);
reverse(resstr.begin(),resstr.end());
}
string multiply(string num1, string num2) {
string res("");
if(num1=="0"||num2=="0")
return "0";
int len1 = num1.length();
int len2 = num2.length();
vector<string> resvec;
int maxlen=0;
for(int i=len2-1;i>=0;i--){
int jinwei = 0;
int outer = getvalue(num2,i);
int zero_cnt = len2-1-i;
string this_round_res="";
this_round_res.append(zero_cnt,'0');
for(int j=len1-1;j>=0;j--){
int inner = getvalue(num1,j);
int calres = inner*outer+jinwei;
jinwei = calres/10;
int remain = calres%10;
this_round_res+=to_string(remain);
}
if(jinwei!=0)
this_round_res+=to_string(jinwei);
maxlen = maxlen>=this_round_res.length()?maxlen:this_round_res.length();
resvec.push_back(this_round_res);
}
calthem(resvec,maxlen,res);
return res;
}