Skip to content

Commit 1d5b363

Browse files
add a solution for 43
1 parent f64721e commit 1d5b363

File tree

2 files changed

+133
-42
lines changed

2 files changed

+133
-42
lines changed

src/main/java/com/fishercoder/solutions/_43.java

Lines changed: 106 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,50 +2,123 @@
22

33
public class _43 {
44

5-
/**Inspired by https://discuss.leetcode.com/topic/30508/easiest-java-solution-with-graph-explanation
6-
* Basically, the rule we can find is that products of each two digits will land in this position in the final product:
7-
* i+j and i+j+1*/
8-
public String multiply(String num1, String num2) {
9-
if (isZero(num1) || isZero(num2)) {
10-
return "0";
11-
}
12-
int[] a1 = new int[num1.length()];
13-
int[] a2 = new int[num2.length()];
14-
int[] product = new int[num1.length() + num2.length()];
15-
16-
for (int i = a1.length - 1; i >= 0; i--) {
17-
for (int j = a2.length - 1; j >= 0; j--) {
18-
int thisProduct = Character.getNumericValue(num1.charAt(i)) * Character.getNumericValue(num2.charAt(j));
19-
product[i + j + 1] += thisProduct % 10;
20-
if (product[i + j + 1] >= 10) {
21-
product[i + j + 1] %= 10;
22-
product[i + j]++;
5+
public static class Solution1 {
6+
/**
7+
* Inspired by https://discuss.leetcode.com/topic/30508/easiest-java-solution-with-graph-explanation
8+
* Basically, the rule we can find is that products of each two digits will land in this position in the final product:
9+
* i+j and i+j+1
10+
*/
11+
public String multiply(String num1, String num2) {
12+
if (isZero(num1) || isZero(num2)) {
13+
return "0";
14+
}
15+
int[] a1 = new int[num1.length()];
16+
int[] a2 = new int[num2.length()];
17+
int[] product = new int[num1.length() + num2.length()];
18+
19+
for (int i = a1.length - 1; i >= 0; i--) {
20+
for (int j = a2.length - 1; j >= 0; j--) {
21+
int thisProduct = Character.getNumericValue(num1.charAt(i)) * Character.getNumericValue(num2.charAt(j));
22+
product[i + j + 1] += thisProduct % 10;
23+
if (product[i + j + 1] >= 10) {
24+
product[i + j + 1] %= 10;
25+
product[i + j]++;
26+
}
27+
product[i + j] += thisProduct / 10;
28+
if (product[i + j] >= 10) {
29+
product[i + j] %= 10;
30+
product[i + j - 1]++;
31+
}
2332
}
24-
product[i + j] += thisProduct / 10;
25-
if (product[i + j] >= 10) {
26-
product[i + j] %= 10;
27-
product[i + j - 1]++;
33+
}
34+
35+
StringBuilder stringBuilder = new StringBuilder();
36+
for (int i = 0; i < product.length; i++) {
37+
if (i == 0 && product[i] == 0) {
38+
continue;
2839
}
40+
stringBuilder.append(product[i]);
2941
}
42+
return stringBuilder.toString();
3043
}
3144

32-
StringBuilder stringBuilder = new StringBuilder();
33-
for (int i = 0; i < product.length; i++) {
34-
if (i == 0 && product[i] == 0) {
35-
continue;
45+
46+
private boolean isZero(String num) {
47+
for (char c : num.toCharArray()) {
48+
if (c != '0') {
49+
return false;
50+
}
3651
}
37-
stringBuilder.append(product[i]);
52+
return true;
3853
}
39-
return stringBuilder.toString();
4054
}
4155

42-
private boolean isZero(String num) {
43-
for (char c : num.toCharArray()) {
44-
if (c != '0') {
45-
return false;
56+
public static class Solution2 {
57+
/**
58+
* My completely original solution on 10/14/2021.
59+
*
60+
* Gist: just use string instead of integers for times variable, otherwise guaranteed to overflow/underflow!
61+
* Also: using a pen and paper to visualize how this works out helps a great deal!
62+
*/
63+
public String multiply(String num1, String num2) {
64+
String previous = "";
65+
String j = "";
66+
for (int i = num2.length() - 1; i >= 0; i--, j += "0") {
67+
String intermediate = multiplyBySingleDigit(num1, Character.getNumericValue(num2.charAt(i)), j);
68+
String result = add(intermediate, previous);
69+
previous = result;
70+
}
71+
int i = 0;
72+
for (; i < previous.length(); i++) {
73+
if (previous.charAt(i) != '0') {
74+
break;
75+
}
76+
}
77+
return i == previous.length() ? "0" : previous.substring(i);
78+
}
79+
80+
private String add(String num1, String num2) {
81+
int i = num1.length() - 1;
82+
int j = num2.length() - 1;
83+
int carry = 0;
84+
StringBuilder sb = new StringBuilder();
85+
while (i >= 0 || j >= 0) {
86+
int sum = carry;
87+
if (i >= 0) {
88+
sum += Character.getNumericValue(num1.charAt(i));
89+
}
90+
if (j >= 0) {
91+
sum += Character.getNumericValue(num2.charAt(j));
92+
}
93+
sb.append(sum % 10);
94+
carry = sum / 10;
95+
i--;
96+
j--;
97+
}
98+
if (carry > 0) {
99+
sb.append(carry);
100+
}
101+
return sb.reverse().toString();
102+
}
103+
104+
private String multiplyBySingleDigit(String num, int multiplier, String times) {
105+
if (multiplier == 0) {
106+
return "0";
107+
}
108+
StringBuilder sb = new StringBuilder();
109+
int carry = 0;
110+
for (int i = num.length() - 1; i >= 0; i--) {
111+
int val = Character.getNumericValue(num.charAt(i));
112+
int product = val * multiplier;
113+
product += carry;
114+
sb.append(product % 10);
115+
carry = product / 10;
116+
}
117+
if (carry > 0) {
118+
sb.append(carry);
46119
}
120+
return sb.reverse() + times;
47121
}
48-
return true;
49122
}
50123

51124
}

src/test/java/com/fishercoder/_43Test.java

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,34 +6,52 @@
66

77
import static org.junit.Assert.assertEquals;
88

9-
/**
10-
* Created by fishercoder on 5/28/17.
11-
*/
129
public class _43Test {
13-
private static _43 test;
10+
private static _43.Solution1 solution1;
11+
private static _43.Solution2 solution2;
12+
private static String expected;
13+
private static String num1;
14+
private static String num2;
1415

1516
@BeforeClass
1617
public static void setup() {
17-
test = new _43();
18+
solution1 = new _43.Solution1();
19+
solution2 = new _43.Solution2();
1820
}
1921

2022
@Test
2123
public void test1() {
22-
assertEquals("5535", test.multiply("123", "45"));
24+
num1 = "123";
25+
num2 = "45";
26+
expected = "5535";
27+
assertEquals(expected, solution1.multiply(num1, num2));
28+
assertEquals(expected, solution2.multiply(num1, num2));
2329
}
2430

2531
@Test
2632
public void test2() {
27-
assertEquals("0", test.multiply("9133", "0"));
33+
num1 = "9133";
34+
num2 = "0";
35+
expected = "0";
36+
assertEquals(expected, solution1.multiply(num1, num2));
37+
assertEquals(expected, solution2.multiply(num1, num2));
2838
}
2939

3040
@Test
3141
public void test3() {
32-
assertEquals("491555843274052692", test.multiply("6913259244", "71103343"));
42+
num1 = "6913259244";
43+
num2 = "71103343";
44+
expected = "491555843274052692";
45+
assertEquals(expected, solution1.multiply(num1, num2));
46+
assertEquals(expected, solution2.multiply(num1, num2));
3347
}
3448

3549
@Test
3650
public void test4() {
37-
assertEquals("67143675422804947379429215144664313370120390398055713625298709447", test.multiply("401716832807512840963", "167141802233061013023557397451289113296441069"));
51+
num1 = "401716832807512840963";
52+
num2 = "167141802233061013023557397451289113296441069";
53+
expected = "67143675422804947379429215144664313370120390398055713625298709447";
54+
assertEquals(expected, solution1.multiply(num1, num2));
55+
assertEquals(expected, solution2.multiply(num1, num2));
3856
}
3957
}

0 commit comments

Comments
 (0)