当前位置:首页 > 单片机 > 后端技术指南针
[导读]1 前言 今天来写一道leetcode的中等难度的题目,声明一下:这不是最优解,就是常规思路。 之所以写出来,是因为我觉得:如果你的想法比较复杂或者比较冗长,那也没关系,写出来ac了它,能绕过层层关卡做出来同样值得。 就好像我们新接手了同事的代码,第一反

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: //将string指定位置的字符转换为数字 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<maxlen;i++){ //开始遍历每一次的结果 int this_sum = 0; this_sum += jinwei; for(int j=0;j<veclen;j++){ if(i<resvec[j].length()){ 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"; //其他情况 /* 1.完全模拟乘法的计算过程 2.使用两个循环 增加每次计算的结果 以及进位 3.由于要求不可直接将输入转换为整数 可以使用ascii来确定单个字符的数值 */ int len1 = num1.length(); int len2 = num2.length(); //存储每次循环的结果 后续的累加 要从其中进行遍历 vector<string> resvec; int maxlen=0; //我们从乘数 nums2开始作为外层循环 即456 并且从个位开始循环 //为了对齐将结果后默认补齐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); //计算两个位的乘积 并取保留值和进位 //eg 8*9=72 上一次进位0 综合得:保留位2 进位7 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); } //累加vector中的数据 calthem(resvec,maxlen,res); return res; }};

代码好像还是比较长,不过本质上就两个部分,第一个是利用两个循环获得临时结果字符串,把字符串存储在vector中,第二部分就是把vector中的临时字符串累加返回。

其中尽量不用api,能自己造的轮子就自己写了,权当一题多练了。

5.优化解

我的糙代码ac之后,惯例打开题解看看同行有什么妙招,其中有一个讲的比较好,是对算数过程的优化,说实话我的算数并不好,所以这个是第一次看到,现场我是想不到, 不过很有用一起看下:

这个优化法是把计算过程中的值的坐标都提前知道了,所以就相当于一步到位,不过我还没来得及实验可以快多少,等下试试。


最后依然是,感谢各位的观摩!

免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: 驱动电源

在工业自动化蓬勃发展的当下,工业电机作为核心动力设备,其驱动电源的性能直接关系到整个系统的稳定性和可靠性。其中,反电动势抑制与过流保护是驱动电源设计中至关重要的两个环节,集成化方案的设计成为提升电机驱动性能的关键。

关键字: 工业电机 驱动电源

LED 驱动电源作为 LED 照明系统的 “心脏”,其稳定性直接决定了整个照明设备的使用寿命。然而,在实际应用中,LED 驱动电源易损坏的问题却十分常见,不仅增加了维护成本,还影响了用户体验。要解决这一问题,需从设计、生...

关键字: 驱动电源 照明系统 散热

根据LED驱动电源的公式,电感内电流波动大小和电感值成反比,输出纹波和输出电容值成反比。所以加大电感值和输出电容值可以减小纹波。

关键字: LED 设计 驱动电源

电动汽车(EV)作为新能源汽车的重要代表,正逐渐成为全球汽车产业的重要发展方向。电动汽车的核心技术之一是电机驱动控制系统,而绝缘栅双极型晶体管(IGBT)作为电机驱动系统中的关键元件,其性能直接影响到电动汽车的动力性能和...

关键字: 电动汽车 新能源 驱动电源

在现代城市建设中,街道及停车场照明作为基础设施的重要组成部分,其质量和效率直接关系到城市的公共安全、居民生活质量和能源利用效率。随着科技的进步,高亮度白光发光二极管(LED)因其独特的优势逐渐取代传统光源,成为大功率区域...

关键字: 发光二极管 驱动电源 LED

LED通用照明设计工程师会遇到许多挑战,如功率密度、功率因数校正(PFC)、空间受限和可靠性等。

关键字: LED 驱动电源 功率因数校正

在LED照明技术日益普及的今天,LED驱动电源的电磁干扰(EMI)问题成为了一个不可忽视的挑战。电磁干扰不仅会影响LED灯具的正常工作,还可能对周围电子设备造成不利影响,甚至引发系统故障。因此,采取有效的硬件措施来解决L...

关键字: LED照明技术 电磁干扰 驱动电源

开关电源具有效率高的特性,而且开关电源的变压器体积比串联稳压型电源的要小得多,电源电路比较整洁,整机重量也有所下降,所以,现在的LED驱动电源

关键字: LED 驱动电源 开关电源

LED驱动电源是把电源供应转换为特定的电压电流以驱动LED发光的电压转换器,通常情况下:LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: LED 隧道灯 驱动电源
关闭