LeetCode——字串相乘
阿新 • • 發佈:2020-08-09
Q:給定兩個以字串形式表示的非負整數 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)或直接將輸入轉換為整數來處理。
A:
1.暴力模擬豎式
public String multiply(String num1, String num2) { if (num1.length() == 0 || num2.length() == 0) return ""; if(num1.equals("0")||num2.equals("0")) return "0"; int n1 = num1.length(); StringBuilder res = new StringBuilder(); int count = 0; for (int i = n1 - 1; i >= 0; i--) { int currNum = num1.charAt(i) - '0'; StringBuilder curr = compute(currNum, num2); curr.append("0".repeat(Math.max(0, count))); res = numAdd(res, curr); count++; } return res.toString(); } private StringBuilder numAdd(StringBuilder res, StringBuilder curr) { int decade = 0; int n1 = res.length(); int n2 = curr.length(); int i = n1 - 1, j = n2 - 1; StringBuilder result = new StringBuilder(); while (i >= 0 && j >= 0) { int curr1 = res.charAt(i) - '0'; int curr2 = curr.charAt(j) - '0'; int currTemp = curr1 + curr2 + decade; decade = currTemp / 10; result.insert(0, currTemp % 10); i--; j--; } while (i >= 0) { int curr1 = res.charAt(i) - '0' + decade; decade = curr1 / 10; result.insert(0, curr1 % 10); i--; } while (j >= 0) { int curr2 = curr.charAt(j) - '0' + decade; decade = curr2 / 10; result.insert(0, curr2 % 10); j--; } if (decade != 0) { result.insert(0, decade); } return result; } private StringBuilder compute(int currNum, String num2) { int n2 = num2.length(); int decade = 0; StringBuilder res = new StringBuilder(); for (int i = n2 - 1; i >= 0; i--) { int curr = num2.charAt(i) - '0'; int temp = curr * currNum + decade; decade = temp / 10; res.insert(0, temp % 10); } if (decade != 0) { res.insert(0, decade); } return res; }
- 優化豎式
該演算法是通過兩數相乘時,乘數某位與被乘數某位相乘,與產生結果的位置的規律來完成。具體規律如下:
- 乘數 num1 位數為 MM,被乘數 num2 位數為 NN, num1 x num2 結果 res 最大總位數為 M+N
- num1[i] x num2[j] 的結果為 tmp(位數為兩位,"0x","xy"的形式),其第一位位於 res[i+j],第二位位於 res[i+j+1]。
結合下圖更容易理解
public String multiply(String num1, String num2) { if (num1.length() == 0 || num2.length() == 0) return ""; if (num1.equals("0") || num2.equals("0")) return "0"; //res最長為num1.length() + num2.length() int[] res = new int[num1.length() + num2.length()]; for (int i = num1.length() - 1; i >= 0; i--) { int n1 = num1.charAt(i) - '0'; for (int j = num2.length() - 1; j >= 0; j--) { int n2 = num2.charAt(j) - '0'; int sum = (res[i + j + 1] + n1 * n2); res[i + j + 1] = sum % 10; res[i + j] = sum / 10; } } StringBuilder result = new StringBuilder(); for (int i = 0; i < res.length; i++) { //如果最頂位為0,忽略 if (i == 0 && res[i] == 0) continue; result.append(res[i]); } return result.toString(); }