43. Multiply Strings
2016-09-15 05:18
337 查看
模拟乘法运算的,楞算的话(grade school algorithm ?)肯定会TLE...
每位分别相乘是免不了的,但是累加的过程我们可以手动操纵。
AB:
A的m位 B的n位, 得出的结果只会 直接 影响(m+n)位和(m+n+1)位。前者是当前位,后者是进位。有没有可能让进的位再进位?
不可能,因为是从低位到高位遍历,进位(m+n+1) is initialized as 0 and it will be so the first time you meet her. 初次邂逅的她只会是一尘不染的0。
思路知道了,剩下的就是跟编程有关的具体操作。
1个是倒转数位,1个是int char之间的转换。
m位数 * n位数,长度最大是m乘以n,以防万一我们初始数组长度为m*n+1.
最后返还的时候不一定有几位,就导致有可能有很多leading 0s...,记得跳过。
还有印象。
回头看一刷是有问题的,数组定义应该是m+n就可以了,我写了个m*n+1也不知道为毛。。
乘法写竖式是用一个数的每一位去乘另一个数的每一位,最后所有结果加起来。
这里可以确定长为M和N的两个数,最终结果的长度不会超过M+N。
一个数的第i位乘以另一个数的第j位,他们的结果最终会影响i+j位和i+j+1位(如果进位),题里是i+j+1和i+j,因为是反过来的。。。
这样以来就模拟乘法的算法,2个loop分别用num1的每位去乘num2的每位,中间的过程和string1 + string2如出一辙。 2个数组相加是a+b+carry,这里除了这3个还有这一位原来的值,也就是在上一轮计算中可能进位的地方,a + b + carry + res[i + j + 1].
然后是corner cases,其中1个数是0,最后的结果要消除leading Os..
Time Complexity: O(n^2)
Space: O(n)
没面试,惨,今年这么难找,找不到我该怎么办。。
不想就这么回去见父母呀。。好压抑。
每位分别相乘是免不了的,但是累加的过程我们可以手动操纵。
AB:
A的m位 B的n位, 得出的结果只会 直接 影响(m+n)位和(m+n+1)位。前者是当前位,后者是进位。有没有可能让进的位再进位?
不可能,因为是从低位到高位遍历,进位(m+n+1) is initialized as 0 and it will be so the first time you meet her. 初次邂逅的她只会是一尘不染的0。
思路知道了,剩下的就是跟编程有关的具体操作。
1个是倒转数位,1个是int char之间的转换。
public class Solution { public String multiply(String num1, String num2) { if(num1.length() == 0 || num2.length() == 0) return ""; if((num1.length() == 1 && num1.charAt(0) == '0') || (num2.length() == 1 && num2.charAt(0) == '0')) return "0"; StringBuilder sb = new StringBuilder(num1); String s1 = sb.reverse().toString(); sb = new StringBuilder(num2); String s2 = sb.reverse().toString(); char[] res = new char[num1.length() * num2.length()+1]; Arrays.fill(res,'0'); for(int i = 0; i < s1.length();i++) { for(int j = 0; j < s2.length();j++) { int tempVal = (s1.charAt(i) -'0')*(s2.charAt(j)-'0'); res[j+i+1] = (char)(((res[i+j+1]-'0') + ((res[i+j]-'0'+tempVal)/10)) +'0'); res[i+j] = (char)((res[i+j]-'0' + tempVal) %10 +'0'); } } int i = 0; sb = new StringBuilder(new String(res)); String str = sb.reverse().toString(); while(i < str.length() && str.charAt(i) == '0') i++; return str.substring(i); } }
m位数 * n位数,长度最大是m乘以n,以防万一我们初始数组长度为m*n+1.
最后返还的时候不一定有几位,就导致有可能有很多leading 0s...,记得跳过。
----
二刷。还有印象。
回头看一刷是有问题的,数组定义应该是m+n就可以了,我写了个m*n+1也不知道为毛。。
乘法写竖式是用一个数的每一位去乘另一个数的每一位,最后所有结果加起来。
这里可以确定长为M和N的两个数,最终结果的长度不会超过M+N。
一个数的第i位乘以另一个数的第j位,他们的结果最终会影响i+j位和i+j+1位(如果进位),题里是i+j+1和i+j,因为是反过来的。。。
这样以来就模拟乘法的算法,2个loop分别用num1的每位去乘num2的每位,中间的过程和string1 + string2如出一辙。 2个数组相加是a+b+carry,这里除了这3个还有这一位原来的值,也就是在上一轮计算中可能进位的地方,a + b + carry + res[i + j + 1].
然后是corner cases,其中1个数是0,最后的结果要消除leading Os..
Time Complexity: O(n^2)
Space: O(n)
public class Solution { public String multiply(String num1, String num2) { if (num1.length() == 0 || num2.length() == 0) return ""; if (num1.length() == 1 && num1.charAt(0) == '0') return "0"; if (num2.length() == 1 && num2.charAt(0) == '0') return "0"; int[] res = new int[num1.length() + num2.length()]; for (int i = num1.length() - 1; i >= 0; i--) { int carry = 0; for (int j = num2.length() - 1; j >= 0; j--) { int val = (num1.charAt(i) - '0') * (num2.charAt(j) - '0') + carry + res[i + j + 1]; carry = val / 10; res[i + j + 1] = val % 10; } res[i] = carry; // which is actually res[i + j + 1]. } StringBuilder sb = new StringBuilder(); int i = 0; while (i < res.length && res[i] == 0) i++; while (i < res.length) sb.append(res[i++]); return sb.toString(); } }
没面试,惨,今年这么难找,找不到我该怎么办。。
不想就这么回去见父母呀。。好压抑。
相关文章推荐
- 43. Multiply Strings
- LeetCode.415(43) Add Strings&&Multiply Strings
- 43. Multiply Strings
- 43. Multiply Strings
- 43. Multiply Strings
- 415/43 Add Strings/Multiply Strings
- 43. Multiply Strings
- leetcode || 43、Multiply Strings
- Java [Leetcode 43]Multiply Strings
- leetcode43 Multiply Strings
- Medium 43题 Multiply Strings
- LeetCode43_Multiply Strings
- LeetCode(43) Multiply Strings
- 43 - Multiply Strings
- 43. Multiply Strings
- 43. Multiply Strings
- 43. Multiply Strings
- 43. Multiply Strings
- LeetCode 43 Multiply Strings(高精度乘法)
- 43. Multiply Strings