Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit c2c11c9

Browse files
committed
feat: add solutions to lc problem: No.0483
No.0483.Smallest Good Base
1 parent ab2ddaf commit c2c11c9

File tree

4 files changed

+316
-1
lines changed

4 files changed

+316
-1
lines changed

‎solution/0400-0499/0483.Smallest Good Base/README.md‎

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,22 +49,215 @@
4949

5050
<!-- 这里可写通用的实现逻辑 -->
5151

52+
**方法一:数学**
53+
54+
假设 $n$ 在 $k$ 进制下的所有位数均为 1ドル,ドル且位数为 $m+1,ドル那么有式子 1:
55+
56+
$$
57+
n=k^0+k^1+k^2+...+k^m
58+
$$
59+
60+
当 $m=0$ 时,上式 $n=1,ドル而题目 $n$ 取值范围为 $[3, 10^{18}],ドル因此 $m>0$。
61+
62+
当 $m=1$ 时,上式 $n=k^0+k^1=1+k,ドル即 $k=n-1>=2$。
63+
64+
我们来证明一般情况下的两个结论,以帮助解决本题。
65+
66+
**结论一:** $m<\log _{k} n$
67+
68+
注意到式子 1 是个首项为 1ドル,ドル且公比为 $k$ 的等比数列。利用等比数列求和公式,我们可以得出:
69+
70+
$$
71+
n=\frac{1-k^{m+1}}{1-k}
72+
$$
73+
74+
变形得:
75+
76+
$$
77+
k^{m+1}=k \times n-n+1 < k \times n
78+
$$
79+
80+
移项得:
81+
82+
$$
83+
m<\log _{k} n
84+
$$
85+
86+
题目 $n$ 取值范围为 $[3, 10^{18}],ドル又因为 $k>=2,ドル因此 $m<\log _{k} n<\log _{2} 10^{18}<60$。
87+
88+
**结论二:** $k=\left \lfloor \sqrt[m]{n} \right \rfloor $
89+
90+
$$
91+
n=k^0+k^1+k^2+...+k^m>k^m
92+
$$
93+
94+
根据二项式定理:
95+
96+
$$
97+
(a+b)^{n}=\sum_{k=0}^{n}\left(\begin{array}{l}
98+
n \\
99+
k
100+
\end{array}\right) a^{n-k} b^{k}
101+
$$
102+
103+
整合,可得:
104+
105+
$$
106+
(k+1)^{m}=\left(\begin{array}{c}
107+
m \\
108+
0
109+
\end{array}\right) k^{0}+\left(\begin{array}{c}
110+
m \\
111+
1
112+
\end{array}\right) k^{1}+\left(\begin{array}{c}
113+
m \\
114+
2
115+
\end{array}\right) k^{2}+\cdots+\left(\begin{array}{c}
116+
m \\
117+
m
118+
\end{array}\right) k^{m}
119+
$$
120+
121+
当 $m>1$ 时,满足:
122+
123+
$$
124+
\forall i \in[1, m-1],\left(\begin{array}{c}
125+
m \\
126+
i
127+
\end{array}\right)>1
128+
$$
129+
130+
所以有:
131+
132+
$$
133+
\begin{aligned}
134+
(k+1)^{m} &=\left(\begin{array}{c}
135+
m \\
136+
0
137+
\end{array}\right) k^{0}+\left(\begin{array}{c}
138+
m \\
139+
1
140+
\end{array}\right) k^{1}+\left(\begin{array}{c}
141+
m \\
142+
2
143+
\end{array}\right) k^{2}+\cdots+\left(\begin{array}{c}
144+
m \\
145+
m
146+
\end{array}\right) k^{m} \\
147+
&>k^{0}+k^{1}+k^{2}+\cdots+k^{m}=n
148+
\end{aligned}
149+
$$
150+
151+
即:
152+
153+
$$
154+
k < \sqrt[m]{n} < k+1
155+
$$
156+
157+
由于 $k$ 是整数,因此 $k=\left \lfloor \sqrt[m]{n} \right \rfloor $。
158+
159+
综上,依据结论一,我们知道 $m$ 的取值范围为 $[1,log_{k}n),ドル且 $m=1$ 时必然有解。随着 $m$ 的增大,进制 $k$ 不断减小。所以我们只需要从大到小检查每一个 $m$ 可能的取值,利用结论二快速算出对应的 $k$ 值,然后校验计算出的 $k$ 值是否有效即可。如果 $k$ 值有效,我们即可返回结果。
160+
161+
时间复杂度 $O(log^{2}n)$。
162+
52163
<!-- tabs:start -->
53164

54165
### **Python3**
55166

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

58169
```python
170+
class Solution:
171+
def smallestGoodBase(self, n: str) -> str:
172+
def cal(k, m):
173+
p = s = 1
174+
for i in range(m):
175+
p *= k
176+
s += p
177+
return s
59178

179+
num = int(n)
180+
for m in range(63, 1, -1):
181+
l, r = 2, num - 1
182+
while l < r:
183+
mid = (l + r) >> 1
184+
if cal(mid, m) >= num:
185+
r = mid
186+
else:
187+
l = mid + 1
188+
if cal(l, m) == num:
189+
return str(l)
190+
return str(num - 1)
60191
```
61192

62193
### **Java**
63194

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

66197
```java
198+
class Solution {
199+
public String smallestGoodBase(String n) {
200+
long num = Long.parseLong(n);
201+
for (int len = 63; len >= 2; --len) {
202+
long radix = getRadix(len, num);
203+
if (radix != -1) {
204+
return String.valueOf(radix);
205+
}
206+
}
207+
return String.valueOf(num - 1);
208+
}
209+
210+
private long getRadix(int len, long num) {
211+
long l = 2, r = num - 1;
212+
while (l < r) {
213+
long mid = l + r >>> 1;
214+
if (calc(mid, len) >= num) r = mid;
215+
else l = mid + 1;
216+
}
217+
return calc(r, len) == num ? r : -1;
218+
}
219+
220+
private long calc(long radix, int len) {
221+
long p = 1;
222+
long sum = 0;
223+
for (int i = 0; i < len; ++i) {
224+
if (Long.MAX_VALUE - sum < p) {
225+
return Long.MAX_VALUE;
226+
}
227+
sum += p;
228+
if (Long.MAX_VALUE / p < radix) {
229+
p = Long.MAX_VALUE;
230+
} else {
231+
p *= radix;
232+
}
233+
}
234+
return sum;
235+
}
236+
}
237+
```
238+
239+
### **C++**
67240

241+
```cpp
242+
class Solution {
243+
public:
244+
string smallestGoodBase(string n) {
245+
long v = stol(n);
246+
int mx = floor(log(v) / log(2));
247+
for (int m = mx; m > 1; --m) {
248+
int k = pow(v, 1.0 / m);
249+
long mul = 1, s = 1;
250+
for (int i = 0; i < m; ++i) {
251+
mul *= k;
252+
s += mul;
253+
}
254+
if (s == v) {
255+
return to_string(k);
256+
}
257+
}
258+
return to_string(v - 1);
259+
}
260+
};
68261
```
69262
70263
### **...**

‎solution/0400-0499/0483.Smallest Good Base/README_EN.md‎

Lines changed: 83 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,13 +48,95 @@
4848
### **Python3**
4949

5050
```python
51-
51+
class Solution:
52+
def smallestGoodBase(self, n: str) -> str:
53+
def cal(k, m):
54+
p = s = 1
55+
for i in range(m):
56+
p *= k
57+
s += p
58+
return s
59+
60+
num = int(n)
61+
for m in range(63, 1, -1):
62+
l, r = 2, num - 1
63+
while l < r:
64+
mid = (l + r) >> 1
65+
if cal(mid, m) >= num:
66+
r = mid
67+
else:
68+
l = mid + 1
69+
if cal(l, m) == num:
70+
return str(l)
71+
return str(num - 1)
5272
```
5373

5474
### **Java**
5575

5676
```java
77+
class Solution {
78+
public String smallestGoodBase(String n) {
79+
long num = Long.parseLong(n);
80+
for (int len = 63; len >= 2; --len) {
81+
long radix = getRadix(len, num);
82+
if (radix != -1) {
83+
return String.valueOf(radix);
84+
}
85+
}
86+
return String.valueOf(num - 1);
87+
}
88+
89+
private long getRadix(int len, long num) {
90+
long l = 2, r = num - 1;
91+
while (l < r) {
92+
long mid = l + r >>> 1;
93+
if (calc(mid, len) >= num) r = mid;
94+
else l = mid + 1;
95+
}
96+
return calc(r, len) == num ? r : -1;
97+
}
98+
99+
private long calc(long radix, int len) {
100+
long p = 1;
101+
long sum = 0;
102+
for (int i = 0; i < len; ++i) {
103+
if (Long.MAX_VALUE - sum < p) {
104+
return Long.MAX_VALUE;
105+
}
106+
sum += p;
107+
if (Long.MAX_VALUE / p < radix) {
108+
p = Long.MAX_VALUE;
109+
} else {
110+
p *= radix;
111+
}
112+
}
113+
return sum;
114+
}
115+
}
116+
```
57117

118+
### **C++**
119+
120+
```cpp
121+
class Solution {
122+
public:
123+
string smallestGoodBase(string n) {
124+
long v = stol(n);
125+
int mx = floor(log(v) / log(2));
126+
for (int m = mx; m > 1; --m) {
127+
int k = pow(v, 1.0 / m);
128+
long mul = 1, s = 1;
129+
for (int i = 0; i < m; ++i) {
130+
mul *= k;
131+
s += mul;
132+
}
133+
if (s == v) {
134+
return to_string(k);
135+
}
136+
}
137+
return to_string(v - 1);
138+
}
139+
};
58140
```
59141
60142
### **...**
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
class Solution {
2+
public:
3+
string smallestGoodBase(string n) {
4+
long v = stol(n);
5+
int mx = floor(log(v) / log(2));
6+
for (int m = mx; m > 1; --m) {
7+
int k = pow(v, 1.0 / m);
8+
long mul = 1, s = 1;
9+
for (int i = 0; i < m; ++i) {
10+
mul *= k;
11+
s += mul;
12+
}
13+
if (s == v) {
14+
return to_string(k);
15+
}
16+
}
17+
return to_string(v - 1);
18+
}
19+
};
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
class Solution:
2+
def smallestGoodBase(self, n: str) -> str:
3+
def cal(k, m):
4+
p = s = 1
5+
for i in range(m):
6+
p *= k
7+
s += p
8+
return s
9+
10+
num = int(n)
11+
for m in range(63, 1, -1):
12+
l, r = 2, num - 1
13+
while l < r:
14+
mid = (l + r) >> 1
15+
if cal(mid, m) >= num:
16+
r = mid
17+
else:
18+
l = mid + 1
19+
if cal(l, m) == num:
20+
return str(l)
21+
return str(num - 1)

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /