摘要:因為被乘數每一位數字和乘數相乘的結果是依次錯開的,所以就沒問題。判斷兩個數的大小的方法,是先判斷其長度,如果長度不一樣,則較長的較大,如果長度一樣,則需要比較每一位。
Multiply Strings
模擬乘法 復雜度Given two numbers represented as strings, return multiplication of the numbers as a string.
Note: The numbers can be arbitrarily large and are non-negative.
時間 O(NM) 空間 O(N+M)
思路這題的技巧在于復用同一個結果數組存放上次的計算結果。因為被乘數每一位數字和乘數相乘的結果是依次錯開的,所以就沒問題。
注意轉換回String前要先把前面的0去掉,但第一位的0不去掉
代碼public class Solution { public String multiply(String num1, String num2) { if(num1 == null || num2 == null) return null; int len1 = num1.length(), len2 = num2.length(); // 結果的位數最多可能是兩個乘數位數之和 int len3 = len1 + len2; int[] res = new int[len3]; int carry = 0, i = 0, j = 0; for(i = len1 - 1; i >= 0; i--){ // 先置carry位為0 carry = 0; for(j = len2 - 1; j >= 0; j--){ // 每一位的乘積,等于之前這一位的結果,加上carry,再加上這一位和乘數的乘積 int product = carry + res[i + j + 1] + (num1.charAt(i) - "0")*(num2.charAt(j) - "0"); res[i + j + 1] = product % 10; carry = product / 10; } // 把最后的carry位加上 res[i + j + 1] = carry; } StringBuilder resstr = new StringBuilder(); i = 0; // 跳過前面無用的0 while(i < len3 - 1 && res[i] == 0){ i++; } for(; i < len3; i++){ resstr.append(res[i]); } return resstr.toString(); } }Add Two Strings 模擬加法 復雜度
時間 O(N) 空間 O(N)
思路從后向前模擬加法
代碼private String addString(String num1, String num2){ int i = num1.length() - 1, j = num2.length() - 1; int k = Math.max(i, j); int[] num3 = new int[k + 1]; int sum = 0, carry = 0; while(i >= 0 || j >= 0){ // 加數的位 int d1 = i >= 0 ? (num1.charAt(i) - "0") : 0; // 被加數的位 int d2 = j >= 0 ? (num2.charAt(j) - "0") : 0; sum = d1 + d2 + carry; num3[k] = sum % 10; carry = sum / 10; k--; i--; j--; } StringBuilder sb = new StringBuilder(); // 如果最后還有進位要加上 if(carry != 0) sb.append(carry); for(int digit : num3){ sb.append(digit); } return sb.toString(); }有符號加法 思路
有符號的話,就要根據符合判斷具體的操作
如果都是負數,則結果是兩個絕對值相加再取負
如果一個是負數一個正數,則結果是(正數)減去(負數的絕對值),這里要用到減法
如果都是正數則直接相加
代碼private static String addSignedString(String num1, String num2){ int sign1 = 1, sign2 = 1; if(num1.charAt(0) == "-"){ sign1 = -1; num1 = num1.substring(1); } if(num2.charAt(0) == "-"){ sign2 = -1; num2 = num2.substring(1); } if(sign1 == sign2){ String res = addString(num1, num2); return sign1 == -1 ? "-" + res : res; } else { if(sign1 == 1){ return subString(num1, num2); } else { return subString(num2, num1); } } }Substract Two Strings 模擬減法 復雜度
時間 O(N) 空間 O(N)
思路從后向前模擬減法,計算每一位的值時,用減數的位減去被減數,再加上10,再減去借位,結果模上10就行了。借位則是看之前的結果是否小于10,如果小于10說明借位了。不過要注意的是,我們要用較大的數減去較小的數,如果減數反而較大,我們要用減數減去被減數,然后結果加上負號。判斷兩個數的大小的方法,是先判斷其長度,如果長度不一樣,則較長的較大,如果長度一樣,則需要比較每一位。
代碼private static String subString(String num1, String num2){ int len1 = num1.length(), len2 = num2.length(); // 根據兩數的大小關系,決定是直接相減,還是反過來相減取負 if(len1 > len2){ return coreSub(num1, num2); } else if (len1 < len2){ return "-"+coreSub(num2, num1); } else { int compare = num1.compareTo(num2); if(compare > 0){ return coreSub(num1, num2); } else if(compare < 0){ return "-"+coreSub(num2, num1); } else { return "0"; } } } private static String coreSub(String num1, String num2){ int i = num1.length() - 1, j = num2.length() - 1; int[] num3 = new int[i + 1]; int diff = 0, borrow = 0; while(i >= 0){ int d1 = num1.charAt(i) - "0"; int d2 = j >= 0? num2.charAt(j) - "0": 0; // 計算差值時要先加上10 diff = d1 + 10 - borrow - d2; num3[i] = diff % 10; borrow = diff < 10 ? 1 : 0; i--; j--; } i = 0; while(num3[i] == 0){ i++; } StringBuilder sb = new StringBuilder(); while(i < num3.length){ sb.append(num3[i]); i++; } return sb.toString(); }有符號減法 代碼
private static String subSignedString(String num1, String num2){ int sign1 = 1, sign2 = 1; if(num1.charAt(0) == "-"){ sign1 = -1; num1 = num1.substring(1); } if(num2.charAt(0) == "-"){ sign2 = -1; num2 = num2.substring(1); } if(sign1 == sign2){ // 都是正數則直接相減 if(sign1 == 1){ return subString(num1, num2); // 都是負數則后面減去前面 } else { return subString(num2, num1); } } else { // 前正后負則相加 if(sign1 == 1){ return addString(num1, num2); // 前負后正則相加后取負 } else { return "-"+addString(num1, num2); } } }
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/64710.html
摘要:題目詳情題目要求輸入兩個以字符串形式表示的正整數,要求我們求出它們的乘積,同樣也是字符串形式表示。要求不能直接將字符串轉換為整數進行乘法運算。想法這道題的思路就是將我們平時手算多位數乘法的計算方法,轉換成程序語言。 題目詳情 Given two non-negative integers num1 and num2 represented as strings, return the ...
摘要:題目要求將兩個形式的數字相乘的結果用的形式返回。不準使用以外的形式來記錄數字。假設,則將結果的十位和個位分別放在數組下標為和的位置上。存儲的位置等同于上一思路。然后再通過一輪遍歷將進位處理一下。 題目要求 Given two non-negative integers num1 and num2 represented as strings, return the product of...
摘要:一個來自于程序設計的經典問題。注意事項負數問題。和上一點是一樣的問題,要確定方式是屬于具體的對象,還是屬于一個類。 一個來自于C++程序設計的經典問題。如何定義一個分數類,實現分數的約分化簡,分數之間的加法、減法、乘法、除法四則運算? 1.初見 剛看到這道題的時候,第一感覺是挺簡單的啊,就是基本的面向對象,定義對應的加減乘除類就可以了啊,然而到了實現的時候才發現許多問題是說起來容易做起...
摘要:是分布式任務隊列,能實時處理任務,同時支持官方文檔工作原理如下發送給從中消費消息,并將結果存儲在中本文中使用的是,使用的是現在有兩個,分別是加法運算和乘法運算。假定乘法運算的事件優先級高事件也很多,對于加法運算,要求每分鐘最多處理個事件。 Celery是分布式任務隊列,能實時處理任務, 同時支持task scheduling. 官方文檔Celery工作原理如下: celery cli...
閱讀 2270·2021-09-30 09:48
閱讀 3639·2021-09-24 10:27
閱讀 1797·2021-09-22 15:32
閱讀 2030·2021-08-09 13:44
閱讀 3582·2019-08-30 15:55
閱讀 1050·2019-08-29 17:12
閱讀 2010·2019-08-29 17:05
閱讀 2926·2019-08-29 13:43