Skip to content

Commit da96ca4

Browse files
authored
feat: add solutions to lcci problem: No.08.05 (#1390)
No.08.05.Recursive Mulitply
1 parent 767bace commit da96ca4

File tree

9 files changed

+179
-91
lines changed

9 files changed

+179
-91
lines changed

lcci/08.05.Recursive Mulitply/README.md

+63-62
Original file line numberDiff line numberDiff line change
@@ -25,54 +25,13 @@
2525

2626
<!-- 这里可写通用的实现逻辑 -->
2727

28-
~~**最佳方案:**~~
29-
~~直接返回 `A * B`~~
30-
正常递归,叠加总和
31-
32-
```txt
33-
MULTIPLY(A, B)
34-
if A == 0 || B == 0
35-
return 0
36-
A + multiply(A, B - 1)
37-
```
38-
39-
优化 1:
40-
由数值较小的数字决定递归层次
41-
42-
```txt
43-
MULTIPLY(A, B)
44-
if A == 0 || B == 0
45-
return 0
46-
return max(A, B) + multiply(max(A, B), min(A, B) - 1)
47-
```
48-
49-
优化 2:
50-
使用位移减少递归层次
51-
52-
```txt
53-
MULTIPLY(A, B)
54-
return (B % 1 == 1 ? A : 0) + (B > 1 ? MULTIPLY(A + A, B >> 1) : 0)
55-
```
28+
**方法一:递归 + 位运算**
5629

57-
可进一步,转换为循环,虽然并不符合递归主题
30+
我们先判断 $B$ 是否为 $1$,如果是,那么直接返回 $A$
5831

59-
> A 与 B 皆为**正整数**,初始值不会为 0,所以终止条件是 `B != 1`
32+
否则,我们判断 $B$ 是否为奇数,如果是,那么我们可以将 $B$ 右移一位,然后递归调用函数,最后将结果左移一位,再加上 $A$。否则,我们可以将 $B$ 右移一位,然后递归调用函数,最后将结果左移一位。
6033

61-
```txt
62-
MULTIPLY(A, B)
63-
T = min(A, B)
64-
A = max(A, B)
65-
B = T
66-
r = 0
67-
while B != 1 {
68-
if B % 2 == 1 {
69-
r = r + A
70-
}
71-
A = A + A
72-
B = B >> 1
73-
}
74-
return res + A
75-
```
34+
时间复杂度 $O(\log n)$,空间复杂度 $O(\log n)$。其中 $n$ 是 $B$ 的大小。
7635

7736
<!-- tabs:start -->
7837

@@ -81,36 +40,75 @@ MULTIPLY(A, B)
8140
<!-- 这里可写当前语言的特殊实现逻辑 -->
8241

8342
```python
84-
43+
class Solution:
44+
def multiply(self, A: int, B: int) -> int:
45+
if B == 1:
46+
return A
47+
if B & 1:
48+
return (self.multiply(A, B >> 1) << 1) + A
49+
return self.multiply(A, B >> 1) << 1
8550
```
8651

8752
### **Java**
8853

8954
<!-- 这里可写当前语言的特殊实现逻辑 -->
9055

9156
```java
92-
57+
class Solution {
58+
public int multiply(int A, int B) {
59+
if (B == 1) {
60+
return A;
61+
}
62+
if ((B & 1) == 1) {
63+
return (multiply(A, B >> 1) << 1) + A;
64+
}
65+
return multiply(A, B >> 1) << 1;
66+
}
67+
}
9368
```
9469

95-
### **TypeScript**
70+
### **C++**
9671

97-
```ts
98-
function multiply(A: number, B: number): number {
99-
if (A === 0 || B === 0) {
100-
return 0;
72+
```cpp
73+
class Solution {
74+
public:
75+
int multiply(int A, int B) {
76+
if (B == 1) {
77+
return A;
78+
}
79+
if ((B & 1) == 1) {
80+
return (multiply(A, B >> 1) << 1) + A;
81+
}
82+
return multiply(A, B >> 1) << 1;
10183
}
102-
const [max, min] = [Math.max(A, B), Math.min(A, B)];
103-
return max + multiply(max, min - 1);
84+
};
85+
```
86+
87+
### **Go**
88+
89+
```go
90+
func multiply(A int, B int) int {
91+
if B == 1 {
92+
return A
93+
}
94+
if B&1 == 1 {
95+
return (multiply(A, B>>1) << 1) + A
96+
}
97+
return multiply(A, B>>1) << 1
10498
}
10599
```
106100

101+
### **TypeScript**
102+
107103
```ts
108104
function multiply(A: number, B: number): number {
109-
const max = Math.max(A, B);
110-
const min = Math.min(A, B);
111-
const helper = (a: number, b: number) =>
112-
(b & 1 ? a : 0) + (b > 1 ? helper(a + a, b >> 1) : 0);
113-
return helper(max, min);
105+
if (B === 1) {
106+
return A;
107+
}
108+
if ((B & 1) === 1) {
109+
return (multiply(A, B >> 1) << 1) + A;
110+
}
111+
return multiply(A, B >> 1) << 1;
114112
}
115113
```
116114

@@ -119,10 +117,13 @@ function multiply(A: number, B: number): number {
119117
```rust
120118
impl Solution {
121119
pub fn multiply(a: i32, b: i32) -> i32 {
122-
if a == 0 || b == 0 {
123-
return 0;
120+
if b == 1 {
121+
return a;
122+
}
123+
if b & 1 == 1 {
124+
return (Self::multiply(a, b >> 1) << 1) + a;
124125
}
125-
a.max(b) + Self::multiply(a.max(b), a.min(b) - 1)
126+
Self::multiply(a, b >> 1) << 1
126127
}
127128
}
128129
```

lcci/08.05.Recursive Mulitply/README_EN.md

+59-17
Original file line numberDiff line numberDiff line change
@@ -33,34 +33,73 @@
3333
### **Python3**
3434

3535
```python
36-
36+
class Solution:
37+
def multiply(self, A: int, B: int) -> int:
38+
if B == 1:
39+
return A
40+
if B & 1:
41+
return (self.multiply(A, B >> 1) << 1) + A
42+
return self.multiply(A, B >> 1) << 1
3743
```
3844

3945
### **Java**
4046

4147
```java
42-
48+
class Solution {
49+
public int multiply(int A, int B) {
50+
if (B == 1) {
51+
return A;
52+
}
53+
if ((B & 1) == 1) {
54+
return (multiply(A, B >> 1) << 1) + A;
55+
}
56+
return multiply(A, B >> 1) << 1;
57+
}
58+
}
4359
```
4460

45-
### **TypeScript**
61+
### **C++**
4662

47-
```ts
48-
function multiply(A: number, B: number): number {
49-
if (A === 0 || B === 0) {
50-
return 0;
63+
```cpp
64+
class Solution {
65+
public:
66+
int multiply(int A, int B) {
67+
if (B == 1) {
68+
return A;
69+
}
70+
if ((B & 1) == 1) {
71+
return (multiply(A, B >> 1) << 1) + A;
72+
}
73+
return multiply(A, B >> 1) << 1;
5174
}
52-
const [max, min] = [Math.max(A, B), Math.min(A, B)];
53-
return max + multiply(max, min - 1);
75+
};
76+
```
77+
78+
### **Go**
79+
80+
```go
81+
func multiply(A int, B int) int {
82+
if B == 1 {
83+
return A
84+
}
85+
if B&1 == 1 {
86+
return (multiply(A, B>>1) << 1) + A
87+
}
88+
return multiply(A, B>>1) << 1
5489
}
5590
```
5691

92+
### **TypeScript**
93+
5794
```ts
5895
function multiply(A: number, B: number): number {
59-
const max = Math.max(A, B);
60-
const min = Math.min(A, B);
61-
const helper = (a: number, b: number) =>
62-
(b & 1 ? a : 0) + (b > 1 ? helper(a + a, b >> 1) : 0);
63-
return helper(max, min);
96+
if (B === 1) {
97+
return A;
98+
}
99+
if ((B & 1) === 1) {
100+
return (multiply(A, B >> 1) << 1) + A;
101+
}
102+
return multiply(A, B >> 1) << 1;
64103
}
65104
```
66105

@@ -69,10 +108,13 @@ function multiply(A: number, B: number): number {
69108
```rust
70109
impl Solution {
71110
pub fn multiply(a: i32, b: i32) -> i32 {
72-
if a == 0 || b == 0 {
73-
return 0;
111+
if b == 1 {
112+
return a;
113+
}
114+
if b & 1 == 1 {
115+
return (Self::multiply(a, b >> 1) << 1) + a;
74116
}
75-
a.max(b) + Self::multiply(a.max(b), a.min(b) - 1)
117+
Self::multiply(a, b >> 1) << 1
76118
}
77119
}
78120
```
+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
class Solution {
2+
public:
3+
int multiply(int A, int B) {
4+
if (B == 1) {
5+
return A;
6+
}
7+
if ((B & 1) == 1) {
8+
return (multiply(A, B >> 1) << 1) + A;
9+
}
10+
return multiply(A, B >> 1) << 1;
11+
}
12+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
func multiply(A int, B int) int {
2+
if B == 1 {
3+
return A
4+
}
5+
if B&1 == 1 {
6+
return (multiply(A, B>>1) << 1) + A
7+
}
8+
return multiply(A, B>>1) << 1
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
class Solution {
2+
public int multiply(int A, int B) {
3+
if (B == 1) {
4+
return A;
5+
}
6+
if ((B & 1) == 1) {
7+
return (multiply(A, B >> 1) << 1) + A;
8+
}
9+
return multiply(A, B >> 1) << 1;
10+
}
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
class Solution:
2+
def multiply(self, A: int, B: int) -> int:
3+
if B == 1:
4+
return A
5+
if B & 1:
6+
return (self.multiply(A, B >> 1) << 1) + A
7+
return self.multiply(A, B >> 1) << 1
+11-8
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
1-
impl Solution {
2-
pub fn multiply(a: i32, b: i32) -> i32 {
3-
if a == 0 || b == 0 {
4-
return 0;
5-
}
6-
a.max(b) + Self::multiply(a.max(b), a.min(b) - 1)
7-
}
8-
}
1+
impl Solution {
2+
pub fn multiply(a: i32, b: i32) -> i32 {
3+
if b == 1 {
4+
return a;
5+
}
6+
if b & 1 == 1 {
7+
return (Self::multiply(a, b >> 1) << 1) + a;
8+
}
9+
Self::multiply(a, b >> 1) << 1
10+
}
11+
}
+6-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
function multiply(A: number, B: number): number {
2-
if (A === 0 || B === 0) {
3-
return 0;
2+
if (B === 1) {
3+
return A;
44
}
5-
const [max, min] = [Math.max(A, B), Math.min(A, B)];
6-
return max + multiply(max, min - 1);
5+
if ((B & 1) === 1) {
6+
return (multiply(A, B >> 1) << 1) + A;
7+
}
8+
return multiply(A, B >> 1) << 1;
79
}

lcci/08.06.Hanota/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
## 题目描述
66

77
<!-- 这里写题目描述 -->
8+
89
<p>在经典汉诺塔问题中,有 3 根柱子及 N 个不同大小的穿孔圆盘,盘子可以滑入任意一根柱子。一开始,所有盘子自上而下按升序依次套在第一根柱子上(即每一个盘子只能放在更大的盘子上面)。移动圆盘时受到以下限制:<br>
910
(1) 每次只能移动一个盘子;<br>
1011
(2) 盘子只能从柱子顶端滑出移到下一根柱子;<br>

0 commit comments

Comments
 (0)