一、題目解析
1、計算乘積后,將結果也按字符串返回
2、字符串長度在[1,200]
二、算法原理
為了方便字符串計算,我們將其逆置,符合我們的計算需求,"123"將變為"321"
解法1:模擬小學列豎式計算
但還是有細節需要注意
細節1:在高位相乘時,要補上“0”
我們自己在計算時,不加0,是因為我們知道哪里是有0的,只是懶得寫。但對于我們計算字符串相加時,不加0,會導致計算出錯,所以要補上0
細節2:處理前導“0”
在計算123x0的時候,由于我們對字符串進行處理,所以會出現"000"這樣的結果,所以需要特殊處理一下
細節3:注意計算結果的順序
我們逆序了相乘的字符串,但我們計算的結果也是逆序的,所以我們需要對結果進行逆置
解法2:對解法1的優化
對于解法1,我們需要處理多次進位,計算123*6,123*50,123*400的時候需要處理進位,在計算和的時候也需要處理進位,這就導致了代碼實現十分麻煩,所以在此基礎上提出了優化
將計算完的每一位先不處理進位,將其放入到一個數組tmp中,存放的位置也很好知道,從右往左數3是第0位,2是第1位,1是第2位,對于3*6的結果18應該放在數組下標0+0處,同理6*2的結果12放在數組下標1+0處,如此操作完后我們最后最數組內存存儲的值做進位計算
用ret存儲字符串,記得逆置哦
個人建議第一種解法看看官方代碼就行了,真要好理解好上手,還得看解法2
鏈接:43. 字符串相乘 - 力扣(LeetCode)
三、代碼示例
解法2:
class Solution {
public:int tmp[399];//這里直接開399是因為最長只有200,不超過400,雖然有點浪費string multiply(string num1, string num2){int m = num1.size(),n = num2.size();string ret;reverse(num1.begin(),num1.end());reverse(num2.begin(),num2.end());for(int i = 0;i<n;i++){for(int j = 0;j<m;j++){tmp[i+j] += (num1[j]-'0')*(num2[i]-'0');}}int carry = 0;for(int i = 0;i<m+n-1;i++){ret += to_string((tmp[i]+carry)%10);carry = (tmp[i]+carry)/10;}if(carry) ret += to_string(carry);//需要對保存進位做判斷,不為0則說明字符串不完整reverse(ret.begin(),ret.end());if(ret[0]=='0'&&ret[1]=='0')//前導0特判return "0";return ret;}
};