Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add solutions to lc problem: No.1363 #1637

Merged
merged 1 commit into from
Sep 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
185 changes: 184 additions & 1 deletion solution/1300-1399/1363.Largest Multiple of Three/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,22 +53,205 @@

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

**方法一:贪心 + 动态规划 + 逆推**

我们定义 $f[i][j]$ 表示在前 $i$ 个数中选取若干个数,使得选取的数的和模 $3$ 为 $j$ 的最大长度。为了使得选取的数最大,我们需要尽可能选取更多的数,因此我们需要使得 $f[i][j]$ 尽可能大。我们初始化 $f[0][0] = 0$,其余的 $f[0][j] = -\infty$。

考虑 $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$ 个数的值。因此我们有如下的状态转移方程:

$$
f[i][j] = \max \{ f[i - 1][j], f[i - 1][(j - x_i \bmod 3 + 3) \bmod 3] + 1 \}
$$

如果 $f[n][0] \le 0$,那么我们无法选取任何数,因此答案字符串为空。否则我们可以通过 $f$ 数组进行逆推,找出选取的数。

定义 $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$ 不变。为了使得同等长度的数最大,我们应该优先选取较大的数,因此,我们在前面首先对数组进行排序。

时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 为数组的长度。

<!-- tabs:start -->

### **Python3**

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

```python

class Solution:
def largestMultipleOfThree(self, digits: List[int]) -> str:
digits.sort()
n = len(digits)
f = [[-inf] * 3 for _ in range(n + 1)]
f[0][0] = 0
for i, x in enumerate(digits, 1):
for j in range(3):
f[i][j] = max(f[i - 1][j], f[i - 1][(j - x % 3 + 3) % 3] + 1)
if f[n][0] <= 0:
return ""
arr = []
j = 0
for i in range(n, 0, -1):
k = (j - digits[i - 1] % 3 + 3) % 3
if f[i - 1][k] + 1 == f[i][j]:
arr.append(digits[i - 1])
j = k
i = 0
while i < len(arr) - 1 and arr[i] == 0:
i += 1
return "".join(map(str, arr[i:]))
```

### **Java**

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

```java
class Solution {
public String largestMultipleOfThree(int[] digits) {
Arrays.sort(digits);
int n = digits.length;
int[][] f = new int[n + 1][3];
final int inf = 1 << 30;
for (var g : f) {
Arrays.fill(g, -inf);
}
f[0][0] = 0;
for (int i = 1; i <= n; ++i) {
for (int j = 0; j < 3; ++j) {
f[i][j] = Math.max(f[i - 1][j], f[i - 1][(j - digits[i - 1] % 3 + 3) % 3] + 1);
}
}
if (f[n][0] <= 0) {
return "";
}
StringBuilder sb = new StringBuilder();
for (int i = n, j = 0; i > 0; --i) {
int k = (j - digits[i - 1] % 3 + 3) % 3;
if (f[i - 1][k] + 1 == f[i][j]) {
sb.append(digits[i - 1]);
j = k;
}
}
int i = 0;
while (i < sb.length() - 1 && sb.charAt(i) == '0') {
++i;
}
return sb.substring(i);
}
}
```

### **C++**

```cpp
class Solution {
public:
string largestMultipleOfThree(vector<int>& digits) {
sort(digits.begin(), digits.end());
int n = digits.size();
int f[n + 1][3];
memset(f, -0x3f, sizeof(f));
f[0][0] = 0;
for (int i = 1; i <= n; ++i) {
for (int j = 0; j < 3; ++j) {
f[i][j] = max(f[i - 1][j], f[i - 1][(j - digits[i - 1] % 3 + 3) % 3] + 1);
}
}
if (f[n][0] <= 0) {
return "";
}
string ans;
for (int i = n, j = 0; i; --i) {
int k = (j - digits[i - 1] % 3 + 3) % 3;
if (f[i - 1][k] + 1 == f[i][j]) {
ans += digits[i - 1] + '0';
j = k;
}
}
int i = 0;
while (i < ans.size() - 1 && ans[i] == '0') {
++i;
}
return ans.substr(i);
}
};
```

### **Go**

```go
func largestMultipleOfThree(digits []int) string {
sort.Ints(digits)
n := len(digits)
const inf = 1 << 30
f := make([][]int, n+1)
for i := range f {
f[i] = make([]int, 3)
for j := range f[i] {
f[i][j] = -inf
}
}
f[0][0] = 0
for i := 1; i <= n; i++ {
for j := 0; j < 3; j++ {
f[i][j] = max(f[i-1][j], f[i-1][(j-digits[i-1]%3+3)%3]+1)
}
}
if f[n][0] <= 0 {
return ""
}
ans := []byte{}
for i, j := n, 0; i > 0; i-- {
k := (j - digits[i-1]%3 + 3) % 3
if f[i][j] == f[i-1][k]+1 {
ans = append(ans, byte('0'+digits[i-1]))
j = k
}
}
i := 0
for i < len(ans)-1 && ans[i] == '0' {
i++
}
return string(ans[i:])
}

func max(a, b int) int {
if a > b {
return a
}
return b
}
```

### **TypeScript**

```ts
function largestMultipleOfThree(digits: number[]): string {
digits.sort((a, b) => a - b);
const n = digits.length;
const f: number[][] = new Array(n + 1).fill(0).map(() => new Array(3).fill(-Infinity));
f[0][0] = 0;
for (let i = 1; i <= n; ++i) {
for (let j = 0; j < 3; ++j) {
f[i][j] = Math.max(f[i - 1][j], f[i - 1][(j - (digits[i - 1] % 3) + 3) % 3] + 1);
}
}
if (f[n][0] <= 0) {
return '';
}
const arr: number[] = [];
for (let i = n, j = 0; i; --i) {
const k = (j - (digits[i - 1] % 3) + 3) % 3;
if (f[i - 1][k] + 1 === f[i][j]) {
arr.push(digits[i - 1]);
j = k;
}
}
let i = 0;
while (i < arr.length - 1 && arr[i] === 0) {
++i;
}
return arr.slice(i).join('');
}
```

### **...**
Expand Down
169 changes: 168 additions & 1 deletion solution/1300-1399/1363.Largest Multiple of Three/README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,180 @@
### **Python3**

```python

class Solution:
def largestMultipleOfThree(self, digits: List[int]) -> str:
digits.sort()
n = len(digits)
f = [[-inf] * 3 for _ in range(n + 1)]
f[0][0] = 0
for i, x in enumerate(digits, 1):
for j in range(3):
f[i][j] = max(f[i - 1][j], f[i - 1][(j - x % 3 + 3) % 3] + 1)
if f[n][0] <= 0:
return ""
arr = []
j = 0
for i in range(n, 0, -1):
k = (j - digits[i - 1] % 3 + 3) % 3
if f[i - 1][k] + 1 == f[i][j]:
arr.append(digits[i - 1])
j = k
i = 0
while i < len(arr) - 1 and arr[i] == 0:
i += 1
return "".join(map(str, arr[i:]))
```

### **Java**

```java
class Solution {
public String largestMultipleOfThree(int[] digits) {
Arrays.sort(digits);
int n = digits.length;
int[][] f = new int[n + 1][3];
final int inf = 1 << 30;
for (var g : f) {
Arrays.fill(g, -inf);
}
f[0][0] = 0;
for (int i = 1; i <= n; ++i) {
for (int j = 0; j < 3; ++j) {
f[i][j] = Math.max(f[i - 1][j], f[i - 1][(j - digits[i - 1] % 3 + 3) % 3] + 1);
}
}
if (f[n][0] <= 0) {
return "";
}
StringBuilder sb = new StringBuilder();
for (int i = n, j = 0; i > 0; --i) {
int k = (j - digits[i - 1] % 3 + 3) % 3;
if (f[i - 1][k] + 1 == f[i][j]) {
sb.append(digits[i - 1]);
j = k;
}
}
int i = 0;
while (i < sb.length() - 1 && sb.charAt(i) == '0') {
++i;
}
return sb.substring(i);
}
}
```

### **C++**

```cpp
class Solution {
public:
string largestMultipleOfThree(vector<int>& digits) {
sort(digits.begin(), digits.end());
int n = digits.size();
int f[n + 1][3];
memset(f, -0x3f, sizeof(f));
f[0][0] = 0;
for (int i = 1; i <= n; ++i) {
for (int j = 0; j < 3; ++j) {
f[i][j] = max(f[i - 1][j], f[i - 1][(j - digits[i - 1] % 3 + 3) % 3] + 1);
}
}
if (f[n][0] <= 0) {
return "";
}
string ans;
for (int i = n, j = 0; i; --i) {
int k = (j - digits[i - 1] % 3 + 3) % 3;
if (f[i - 1][k] + 1 == f[i][j]) {
ans += digits[i - 1] + '0';
j = k;
}
}
int i = 0;
while (i < ans.size() - 1 && ans[i] == '0') {
++i;
}
return ans.substr(i);
}
};
```

### **Go**

```go
func largestMultipleOfThree(digits []int) string {
sort.Ints(digits)
n := len(digits)
const inf = 1 << 30
f := make([][]int, n+1)
for i := range f {
f[i] = make([]int, 3)
for j := range f[i] {
f[i][j] = -inf
}
}
f[0][0] = 0
for i := 1; i <= n; i++ {
for j := 0; j < 3; j++ {
f[i][j] = max(f[i-1][j], f[i-1][(j-digits[i-1]%3+3)%3]+1)
}
}
if f[n][0] <= 0 {
return ""
}
ans := []byte{}
for i, j := n, 0; i > 0; i-- {
k := (j - digits[i-1]%3 + 3) % 3
if f[i][j] == f[i-1][k]+1 {
ans = append(ans, byte('0'+digits[i-1]))
j = k
}
}
i := 0
for i < len(ans)-1 && ans[i] == '0' {
i++
}
return string(ans[i:])
}

func max(a, b int) int {
if a > b {
return a
}
return b
}
```

### **TypeScript**

```ts
function largestMultipleOfThree(digits: number[]): string {
digits.sort((a, b) => a - b);
const n = digits.length;
const f: number[][] = new Array(n + 1).fill(0).map(() => new Array(3).fill(-Infinity));
f[0][0] = 0;
for (let i = 1; i <= n; ++i) {
for (let j = 0; j < 3; ++j) {
f[i][j] = Math.max(f[i - 1][j], f[i - 1][(j - (digits[i - 1] % 3) + 3) % 3] + 1);
}
}
if (f[n][0] <= 0) {
return '';
}
const arr: number[] = [];
for (let i = n, j = 0; i; --i) {
const k = (j - (digits[i - 1] % 3) + 3) % 3;
if (f[i - 1][k] + 1 === f[i][j]) {
arr.push(digits[i - 1]);
j = k;
}
}
let i = 0;
while (i < arr.length - 1 && arr[i] === 0) {
++i;
}
return arr.slice(i).join('');
}
```

### **...**
Expand Down
Loading