Skip to content

Commit 652d72b

Browse files
authored
feat: add solutions to lc problem: No.0964 (doocs#1503)
No.0964.Least Operators to Express Number
1 parent ef844b1 commit 652d72b

File tree

11 files changed

+426
-2
lines changed

11 files changed

+426
-2
lines changed
Binary file not shown.
Binary file not shown.
Loading
Loading

solution/0900-0999/0964.Least Operators to Express Number/README.md

+158-1
Original file line numberDiff line numberDiff line change
@@ -57,22 +57,179 @@
5757

5858
<!-- 这里可写通用的实现逻辑 -->
5959

60+
**方法一:记忆化搜索**
61+
62+
我们定义一个函数 $dfs(v)$,表示用 $x$ 凑成数字 $v$ 所需要的最少运算符数量。那么答案就是 $dfs(target)$。
63+
64+
函数 $dfs(v)$ 的执行逻辑如下:
65+
66+
如果 $x \geq v$,那么此时可以用 $v$ 个 $x / x$ 相加来得到 $v$,运算符数量为 $v \times 2 - 1$;也可以用 $x$ 减去 $(x - v)$ 个 $x / x$ 来得到 $v$,运算符数量为 $(x - v) \times 2$。取两者的最小值。
67+
68+
否则,我们从 $k=2$ 开始枚举 $x^k$,找到第一个 $x^k \geq v$ 的 $k$:
69+
70+
- 如果此时 $x^k - v \geq v$,那么只能先得到 $x^{k-1}$,然后再递归计算 $dfs(v - x^{k-1})$,此时运算符数量为 $k - 1 + dfs(v - x^{k-1})$;
71+
- 如果此时 $x^k - v < v$,那么可以按照上面的方式得到 $v$,此时运算符数量为 $k - 1 + dfs(v - x^{k-1})$;也可以先得到 $x^k$,再递归计算 $dfs(x^k - v)$,此时运算符数量为 $k + dfs(x^k - v)$。取两者的最小值。
72+
73+
为了避免重复计算,我们使用记忆化搜索的方式实现 $dfs$ 函数。
74+
75+
时间复杂度 $O(\log_{x}{target})$,空间复杂度 $O(\log_{x}{target})$。
76+
6077
<!-- tabs:start -->
6178

6279
### **Python3**
6380

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

6683
```python
67-
84+
class Solution:
85+
def leastOpsExpressTarget(self, x: int, target: int) -> int:
86+
@cache
87+
def dfs(v: int) -> int:
88+
if x >= v:
89+
return min(v * 2 - 1, 2 * (x - v))
90+
k = 2
91+
while x**k < v:
92+
k += 1
93+
if x**k - v < v:
94+
return min(k + dfs(x**k - v), k - 1 + dfs(v - x ** (k - 1)))
95+
return k - 1 + dfs(v - x ** (k - 1))
96+
97+
return dfs(target)
6898
```
6999

70100
### **Java**
71101

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

74104
```java
105+
class Solution {
106+
private int x;
107+
private Map<Integer, Integer> f = new HashMap<>();
108+
109+
public int leastOpsExpressTarget(int x, int target) {
110+
this.x = x;
111+
return dfs(target);
112+
}
113+
114+
private int dfs(int v) {
115+
if (x >= v) {
116+
return Math.min(v * 2 - 1, 2 * (x - v));
117+
}
118+
if (f.containsKey(v)) {
119+
return f.get(v);
120+
}
121+
int k = 2;
122+
long y = (long) x * x;
123+
while (y < v) {
124+
y *= x;
125+
++k;
126+
}
127+
int ans = k - 1 + dfs(v - (int) (y / x));
128+
if (y - v < v) {
129+
ans = Math.min(ans, k + dfs((int) y - v));
130+
}
131+
f.put(v, ans);
132+
return ans;
133+
}
134+
}
135+
```
136+
137+
### **C++**
138+
139+
```cpp
140+
class Solution {
141+
public:
142+
int leastOpsExpressTarget(int x, int target) {
143+
unordered_map<int, int> f;
144+
function<int(int)> dfs = [&](int v) -> int {
145+
if (x >= v) {
146+
return min(v * 2 - 1, 2 * (x - v));
147+
}
148+
if (f.count(v)) {
149+
return f[v];
150+
}
151+
int k = 2;
152+
long long y = x * x;
153+
while (y < v) {
154+
y *= x;
155+
++k;
156+
}
157+
int ans = k - 1 + dfs(v - y / x);
158+
if (y - v < v) {
159+
ans = min(ans, k + dfs(y - v));
160+
}
161+
f[v] = ans;
162+
return ans;
163+
};
164+
return dfs(target);
165+
}
166+
};
167+
```
168+
169+
### **Go**
170+
171+
```go
172+
func leastOpsExpressTarget(x int, target int) int {
173+
f := map[int]int{}
174+
var dfs func(int) int
175+
dfs = func(v int) int {
176+
if x > v {
177+
return min(v*2-1, 2*(x-v))
178+
}
179+
if val, ok := f[v]; ok {
180+
return val
181+
}
182+
k := 2
183+
y := x * x
184+
for y < v {
185+
y *= x
186+
k++
187+
}
188+
ans := k - 1 + dfs(v-y/x)
189+
if y-v < v {
190+
ans = min(ans, k+dfs(y-v))
191+
}
192+
f[v] = ans
193+
return ans
194+
}
195+
return dfs(target)
196+
}
197+
198+
func min(a, b int) int {
199+
if a < b {
200+
return a
201+
}
202+
return b
203+
}
204+
```
75205

206+
### **TypeScript**
207+
208+
```ts
209+
function leastOpsExpressTarget(x: number, target: number): number {
210+
const f: Map<number, number> = new Map();
211+
const dfs = (v: number): number => {
212+
if (x > v) {
213+
return Math.min(v * 2 - 1, 2 * (x - v));
214+
}
215+
if (f.has(v)) {
216+
return f.get(v)!;
217+
}
218+
let k = 2;
219+
let y = x * x;
220+
while (y < v) {
221+
y *= x;
222+
++k;
223+
}
224+
let ans = k - 1 + dfs(v - Math.floor(y / x));
225+
if (y - v < v) {
226+
ans = Math.min(ans, k + dfs(y - v));
227+
}
228+
f.set(v, ans);
229+
return ans;
230+
};
231+
return dfs(target);
232+
}
76233
```
77234

78235
### **...**

solution/0900-0999/0964.Least Operators to Express Number/README_EN.md

+141-1
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,153 @@ The expression contains 3 operations.
6060
### **Python3**
6161

6262
```python
63-
63+
class Solution:
64+
def leastOpsExpressTarget(self, x: int, target: int) -> int:
65+
@cache
66+
def dfs(v: int) -> int:
67+
if x >= v:
68+
return min(v * 2 - 1, 2 * (x - v))
69+
k = 2
70+
while x**k < v:
71+
k += 1
72+
if x**k - v < v:
73+
return min(k + dfs(x**k - v), k - 1 + dfs(v - x ** (k - 1)))
74+
return k - 1 + dfs(v - x ** (k - 1))
75+
76+
return dfs(target)
6477
```
6578

6679
### **Java**
6780

6881
```java
82+
class Solution {
83+
private int x;
84+
private Map<Integer, Integer> f = new HashMap<>();
85+
86+
public int leastOpsExpressTarget(int x, int target) {
87+
this.x = x;
88+
return dfs(target);
89+
}
90+
91+
private int dfs(int v) {
92+
if (x >= v) {
93+
return Math.min(v * 2 - 1, 2 * (x - v));
94+
}
95+
if (f.containsKey(v)) {
96+
return f.get(v);
97+
}
98+
int k = 2;
99+
long y = (long) x * x;
100+
while (y < v) {
101+
y *= x;
102+
++k;
103+
}
104+
int ans = k - 1 + dfs(v - (int) (y / x));
105+
if (y - v < v) {
106+
ans = Math.min(ans, k + dfs((int) y - v));
107+
}
108+
f.put(v, ans);
109+
return ans;
110+
}
111+
}
112+
```
113+
114+
### **C++**
115+
116+
```cpp
117+
class Solution {
118+
public:
119+
int leastOpsExpressTarget(int x, int target) {
120+
unordered_map<int, int> f;
121+
function<int(int)> dfs = [&](int v) -> int {
122+
if (x >= v) {
123+
return min(v * 2 - 1, 2 * (x - v));
124+
}
125+
if (f.count(v)) {
126+
return f[v];
127+
}
128+
int k = 2;
129+
long long y = x * x;
130+
while (y < v) {
131+
y *= x;
132+
++k;
133+
}
134+
int ans = k - 1 + dfs(v - y / x);
135+
if (y - v < v) {
136+
ans = min(ans, k + dfs(y - v));
137+
}
138+
f[v] = ans;
139+
return ans;
140+
};
141+
return dfs(target);
142+
}
143+
};
144+
```
145+
146+
### **Go**
147+
148+
```go
149+
func leastOpsExpressTarget(x int, target int) int {
150+
f := map[int]int{}
151+
var dfs func(int) int
152+
dfs = func(v int) int {
153+
if x > v {
154+
return min(v*2-1, 2*(x-v))
155+
}
156+
if val, ok := f[v]; ok {
157+
return val
158+
}
159+
k := 2
160+
y := x * x
161+
for y < v {
162+
y *= x
163+
k++
164+
}
165+
ans := k - 1 + dfs(v-y/x)
166+
if y-v < v {
167+
ans = min(ans, k+dfs(y-v))
168+
}
169+
f[v] = ans
170+
return ans
171+
}
172+
return dfs(target)
173+
}
174+
175+
func min(a, b int) int {
176+
if a < b {
177+
return a
178+
}
179+
return b
180+
}
181+
```
69182

183+
### **TypeScript**
184+
185+
```ts
186+
function leastOpsExpressTarget(x: number, target: number): number {
187+
const f: Map<number, number> = new Map();
188+
const dfs = (v: number): number => {
189+
if (x > v) {
190+
return Math.min(v * 2 - 1, 2 * (x - v));
191+
}
192+
if (f.has(v)) {
193+
return f.get(v)!;
194+
}
195+
let k = 2;
196+
let y = x * x;
197+
while (y < v) {
198+
y *= x;
199+
++k;
200+
}
201+
let ans = k - 1 + dfs(v - Math.floor(y / x));
202+
if (y - v < v) {
203+
ans = Math.min(ans, k + dfs(y - v));
204+
}
205+
f.set(v, ans);
206+
return ans;
207+
};
208+
return dfs(target);
209+
}
70210
```
71211

72212
### **...**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
class Solution {
2+
public:
3+
int leastOpsExpressTarget(int x, int target) {
4+
unordered_map<int, int> f;
5+
function<int(int)> dfs = [&](int v) -> int {
6+
if (x >= v) {
7+
return min(v * 2 - 1, 2 * (x - v));
8+
}
9+
if (f.count(v)) {
10+
return f[v];
11+
}
12+
int k = 2;
13+
long long y = x * x;
14+
while (y < v) {
15+
y *= x;
16+
++k;
17+
}
18+
int ans = k - 1 + dfs(v - y / x);
19+
if (y - v < v) {
20+
ans = min(ans, k + dfs(y - v));
21+
}
22+
f[v] = ans;
23+
return ans;
24+
};
25+
return dfs(target);
26+
}
27+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
func leastOpsExpressTarget(x int, target int) int {
2+
f := map[int]int{}
3+
var dfs func(int) int
4+
dfs = func(v int) int {
5+
if x > v {
6+
return min(v*2-1, 2*(x-v))
7+
}
8+
if val, ok := f[v]; ok {
9+
return val
10+
}
11+
k := 2
12+
y := x * x
13+
for y < v {
14+
y *= x
15+
k++
16+
}
17+
ans := k - 1 + dfs(v-y/x)
18+
if y-v < v {
19+
ans = min(ans, k+dfs(y-v))
20+
}
21+
f[v] = ans
22+
return ans
23+
}
24+
return dfs(target)
25+
}
26+
27+
func min(a, b int) int {
28+
if a < b {
29+
return a
30+
}
31+
return b
32+
}

0 commit comments

Comments
 (0)