Skip to content

Commit 4f89e08

Browse files
authored
feat: add solutions to lc problem: No.1363 (#1637)
No.1363.Largest Multiple of Three
1 parent 710f737 commit 4f89e08

File tree

7 files changed

+506
-2
lines changed

7 files changed

+506
-2
lines changed

solution/1300-1399/1363.Largest Multiple of Three/README.md

+184-1
Original file line numberDiff line numberDiff line change
@@ -53,22 +53,205 @@
5353

5454
<!-- 这里可写通用的实现逻辑 -->
5555

56+
**方法一:贪心 + 动态规划 + 逆推**
57+
58+
我们定义 $f[i][j]$ 表示在前 $i$ 个数中选取若干个数,使得选取的数的和模 $3$ 为 $j$ 的最大长度。为了使得选取的数最大,我们需要尽可能选取更多的数,因此我们需要使得 $f[i][j]$ 尽可能大。我们初始化 $f[0][0] = 0$,其余的 $f[0][j] = -\infty$。
59+
60+
考虑 $f[i][j]$ 如何进行状态转移。我们可以不选取第 $i$ 个数,此时 $f[i][j] = f[i - 1][j]$;我们也可以选取第 $i$ 个数,此时 $f[i][j] = f[i - 1][(j - x_i \bmod 3 + 3) \bmod 3] + 1$,其中 $x_i$ 表示第 $i$ 个数的值。因此我们有如下的状态转移方程:
61+
62+
$$
63+
f[i][j] = \max \{ f[i - 1][j], f[i - 1][(j - x_i \bmod 3 + 3) \bmod 3] + 1 \}
64+
$$
65+
66+
如果 $f[n][0] \le 0$,那么我们无法选取任何数,因此答案字符串为空。否则我们可以通过 $f$ 数组进行逆推,找出选取的数。
67+
68+
定义 $i = n$, $j = 0$,从 $f[i][j]$ 开始逆推,记 $k = (j - x_i \bmod 3 + 3) \bmod 3$,如果 $f[i - 1][k] + 1 = f[i][j]$,那么我们选取了第 $i$ 个数,否则我们没有选取第 $i$ 个数。如果我们选取了第 $i$ 个数,那么我们将 $j$ 更新为 $k$,否则我们保持 $j$ 不变。为了使得同等长度的数最大,我们应该优先选取较大的数,因此,我们在前面首先对数组进行排序。
69+
70+
时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 为数组的长度。
71+
5672
<!-- tabs:start -->
5773

5874
### **Python3**
5975

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

6278
```python
63-
79+
class Solution:
80+
def largestMultipleOfThree(self, digits: List[int]) -> str:
81+
digits.sort()
82+
n = len(digits)
83+
f = [[-inf] * 3 for _ in range(n + 1)]
84+
f[0][0] = 0
85+
for i, x in enumerate(digits, 1):
86+
for j in range(3):
87+
f[i][j] = max(f[i - 1][j], f[i - 1][(j - x % 3 + 3) % 3] + 1)
88+
if f[n][0] <= 0:
89+
return ""
90+
arr = []
91+
j = 0
92+
for i in range(n, 0, -1):
93+
k = (j - digits[i - 1] % 3 + 3) % 3
94+
if f[i - 1][k] + 1 == f[i][j]:
95+
arr.append(digits[i - 1])
96+
j = k
97+
i = 0
98+
while i < len(arr) - 1 and arr[i] == 0:
99+
i += 1
100+
return "".join(map(str, arr[i:]))
64101
```
65102

66103
### **Java**
67104

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

70107
```java
108+
class Solution {
109+
public String largestMultipleOfThree(int[] digits) {
110+
Arrays.sort(digits);
111+
int n = digits.length;
112+
int[][] f = new int[n + 1][3];
113+
final int inf = 1 << 30;
114+
for (var g : f) {
115+
Arrays.fill(g, -inf);
116+
}
117+
f[0][0] = 0;
118+
for (int i = 1; i <= n; ++i) {
119+
for (int j = 0; j < 3; ++j) {
120+
f[i][j] = Math.max(f[i - 1][j], f[i - 1][(j - digits[i - 1] % 3 + 3) % 3] + 1);
121+
}
122+
}
123+
if (f[n][0] <= 0) {
124+
return "";
125+
}
126+
StringBuilder sb = new StringBuilder();
127+
for (int i = n, j = 0; i > 0; --i) {
128+
int k = (j - digits[i - 1] % 3 + 3) % 3;
129+
if (f[i - 1][k] + 1 == f[i][j]) {
130+
sb.append(digits[i - 1]);
131+
j = k;
132+
}
133+
}
134+
int i = 0;
135+
while (i < sb.length() - 1 && sb.charAt(i) == '0') {
136+
++i;
137+
}
138+
return sb.substring(i);
139+
}
140+
}
141+
```
142+
143+
### **C++**
144+
145+
```cpp
146+
class Solution {
147+
public:
148+
string largestMultipleOfThree(vector<int>& digits) {
149+
sort(digits.begin(), digits.end());
150+
int n = digits.size();
151+
int f[n + 1][3];
152+
memset(f, -0x3f, sizeof(f));
153+
f[0][0] = 0;
154+
for (int i = 1; i <= n; ++i) {
155+
for (int j = 0; j < 3; ++j) {
156+
f[i][j] = max(f[i - 1][j], f[i - 1][(j - digits[i - 1] % 3 + 3) % 3] + 1);
157+
}
158+
}
159+
if (f[n][0] <= 0) {
160+
return "";
161+
}
162+
string ans;
163+
for (int i = n, j = 0; i; --i) {
164+
int k = (j - digits[i - 1] % 3 + 3) % 3;
165+
if (f[i - 1][k] + 1 == f[i][j]) {
166+
ans += digits[i - 1] + '0';
167+
j = k;
168+
}
169+
}
170+
int i = 0;
171+
while (i < ans.size() - 1 && ans[i] == '0') {
172+
++i;
173+
}
174+
return ans.substr(i);
175+
}
176+
};
177+
```
178+
179+
### **Go**
180+
181+
```go
182+
func largestMultipleOfThree(digits []int) string {
183+
sort.Ints(digits)
184+
n := len(digits)
185+
const inf = 1 << 30
186+
f := make([][]int, n+1)
187+
for i := range f {
188+
f[i] = make([]int, 3)
189+
for j := range f[i] {
190+
f[i][j] = -inf
191+
}
192+
}
193+
f[0][0] = 0
194+
for i := 1; i <= n; i++ {
195+
for j := 0; j < 3; j++ {
196+
f[i][j] = max(f[i-1][j], f[i-1][(j-digits[i-1]%3+3)%3]+1)
197+
}
198+
}
199+
if f[n][0] <= 0 {
200+
return ""
201+
}
202+
ans := []byte{}
203+
for i, j := n, 0; i > 0; i-- {
204+
k := (j - digits[i-1]%3 + 3) % 3
205+
if f[i][j] == f[i-1][k]+1 {
206+
ans = append(ans, byte('0'+digits[i-1]))
207+
j = k
208+
}
209+
}
210+
i := 0
211+
for i < len(ans)-1 && ans[i] == '0' {
212+
i++
213+
}
214+
return string(ans[i:])
215+
}
216+
217+
func max(a, b int) int {
218+
if a > b {
219+
return a
220+
}
221+
return b
222+
}
223+
```
71224

225+
### **TypeScript**
226+
227+
```ts
228+
function largestMultipleOfThree(digits: number[]): string {
229+
digits.sort((a, b) => a - b);
230+
const n = digits.length;
231+
const f: number[][] = new Array(n + 1).fill(0).map(() => new Array(3).fill(-Infinity));
232+
f[0][0] = 0;
233+
for (let i = 1; i <= n; ++i) {
234+
for (let j = 0; j < 3; ++j) {
235+
f[i][j] = Math.max(f[i - 1][j], f[i - 1][(j - (digits[i - 1] % 3) + 3) % 3] + 1);
236+
}
237+
}
238+
if (f[n][0] <= 0) {
239+
return '';
240+
}
241+
const arr: number[] = [];
242+
for (let i = n, j = 0; i; --i) {
243+
const k = (j - (digits[i - 1] % 3) + 3) % 3;
244+
if (f[i - 1][k] + 1 === f[i][j]) {
245+
arr.push(digits[i - 1]);
246+
j = k;
247+
}
248+
}
249+
let i = 0;
250+
while (i < arr.length - 1 && arr[i] === 0) {
251+
++i;
252+
}
253+
return arr.slice(i).join('');
254+
}
72255
```
73256

74257
### **...**

solution/1300-1399/1363.Largest Multiple of Three/README_EN.md

+168-1
Original file line numberDiff line numberDiff line change
@@ -45,13 +45,180 @@
4545
### **Python3**
4646

4747
```python
48-
48+
class Solution:
49+
def largestMultipleOfThree(self, digits: List[int]) -> str:
50+
digits.sort()
51+
n = len(digits)
52+
f = [[-inf] * 3 for _ in range(n + 1)]
53+
f[0][0] = 0
54+
for i, x in enumerate(digits, 1):
55+
for j in range(3):
56+
f[i][j] = max(f[i - 1][j], f[i - 1][(j - x % 3 + 3) % 3] + 1)
57+
if f[n][0] <= 0:
58+
return ""
59+
arr = []
60+
j = 0
61+
for i in range(n, 0, -1):
62+
k = (j - digits[i - 1] % 3 + 3) % 3
63+
if f[i - 1][k] + 1 == f[i][j]:
64+
arr.append(digits[i - 1])
65+
j = k
66+
i = 0
67+
while i < len(arr) - 1 and arr[i] == 0:
68+
i += 1
69+
return "".join(map(str, arr[i:]))
4970
```
5071

5172
### **Java**
5273

5374
```java
75+
class Solution {
76+
public String largestMultipleOfThree(int[] digits) {
77+
Arrays.sort(digits);
78+
int n = digits.length;
79+
int[][] f = new int[n + 1][3];
80+
final int inf = 1 << 30;
81+
for (var g : f) {
82+
Arrays.fill(g, -inf);
83+
}
84+
f[0][0] = 0;
85+
for (int i = 1; i <= n; ++i) {
86+
for (int j = 0; j < 3; ++j) {
87+
f[i][j] = Math.max(f[i - 1][j], f[i - 1][(j - digits[i - 1] % 3 + 3) % 3] + 1);
88+
}
89+
}
90+
if (f[n][0] <= 0) {
91+
return "";
92+
}
93+
StringBuilder sb = new StringBuilder();
94+
for (int i = n, j = 0; i > 0; --i) {
95+
int k = (j - digits[i - 1] % 3 + 3) % 3;
96+
if (f[i - 1][k] + 1 == f[i][j]) {
97+
sb.append(digits[i - 1]);
98+
j = k;
99+
}
100+
}
101+
int i = 0;
102+
while (i < sb.length() - 1 && sb.charAt(i) == '0') {
103+
++i;
104+
}
105+
return sb.substring(i);
106+
}
107+
}
108+
```
109+
110+
### **C++**
111+
112+
```cpp
113+
class Solution {
114+
public:
115+
string largestMultipleOfThree(vector<int>& digits) {
116+
sort(digits.begin(), digits.end());
117+
int n = digits.size();
118+
int f[n + 1][3];
119+
memset(f, -0x3f, sizeof(f));
120+
f[0][0] = 0;
121+
for (int i = 1; i <= n; ++i) {
122+
for (int j = 0; j < 3; ++j) {
123+
f[i][j] = max(f[i - 1][j], f[i - 1][(j - digits[i - 1] % 3 + 3) % 3] + 1);
124+
}
125+
}
126+
if (f[n][0] <= 0) {
127+
return "";
128+
}
129+
string ans;
130+
for (int i = n, j = 0; i; --i) {
131+
int k = (j - digits[i - 1] % 3 + 3) % 3;
132+
if (f[i - 1][k] + 1 == f[i][j]) {
133+
ans += digits[i - 1] + '0';
134+
j = k;
135+
}
136+
}
137+
int i = 0;
138+
while (i < ans.size() - 1 && ans[i] == '0') {
139+
++i;
140+
}
141+
return ans.substr(i);
142+
}
143+
};
144+
```
145+
146+
### **Go**
147+
148+
```go
149+
func largestMultipleOfThree(digits []int) string {
150+
sort.Ints(digits)
151+
n := len(digits)
152+
const inf = 1 << 30
153+
f := make([][]int, n+1)
154+
for i := range f {
155+
f[i] = make([]int, 3)
156+
for j := range f[i] {
157+
f[i][j] = -inf
158+
}
159+
}
160+
f[0][0] = 0
161+
for i := 1; i <= n; i++ {
162+
for j := 0; j < 3; j++ {
163+
f[i][j] = max(f[i-1][j], f[i-1][(j-digits[i-1]%3+3)%3]+1)
164+
}
165+
}
166+
if f[n][0] <= 0 {
167+
return ""
168+
}
169+
ans := []byte{}
170+
for i, j := n, 0; i > 0; i-- {
171+
k := (j - digits[i-1]%3 + 3) % 3
172+
if f[i][j] == f[i-1][k]+1 {
173+
ans = append(ans, byte('0'+digits[i-1]))
174+
j = k
175+
}
176+
}
177+
i := 0
178+
for i < len(ans)-1 && ans[i] == '0' {
179+
i++
180+
}
181+
return string(ans[i:])
182+
}
183+
184+
func max(a, b int) int {
185+
if a > b {
186+
return a
187+
}
188+
return b
189+
}
190+
```
54191

192+
### **TypeScript**
193+
194+
```ts
195+
function largestMultipleOfThree(digits: number[]): string {
196+
digits.sort((a, b) => a - b);
197+
const n = digits.length;
198+
const f: number[][] = new Array(n + 1).fill(0).map(() => new Array(3).fill(-Infinity));
199+
f[0][0] = 0;
200+
for (let i = 1; i <= n; ++i) {
201+
for (let j = 0; j < 3; ++j) {
202+
f[i][j] = Math.max(f[i - 1][j], f[i - 1][(j - (digits[i - 1] % 3) + 3) % 3] + 1);
203+
}
204+
}
205+
if (f[n][0] <= 0) {
206+
return '';
207+
}
208+
const arr: number[] = [];
209+
for (let i = n, j = 0; i; --i) {
210+
const k = (j - (digits[i - 1] % 3) + 3) % 3;
211+
if (f[i - 1][k] + 1 === f[i][j]) {
212+
arr.push(digits[i - 1]);
213+
j = k;
214+
}
215+
}
216+
let i = 0;
217+
while (i < arr.length - 1 && arr[i] === 0) {
218+
++i;
219+
}
220+
return arr.slice(i).join('');
221+
}
55222
```
56223

57224
### **...**

0 commit comments

Comments
 (0)