Skip to content

Commit ab21931

Browse files
committedJun 16, 2023
feat: add solutions to lc problem: No.1262
No.1262.Greatest Sum Divisible by Three
1 parent f6a3131 commit ab21931

File tree

7 files changed

+344
-82
lines changed

7 files changed

+344
-82
lines changed
 

Diff for: ‎solution/1200-1299/1262.Greatest Sum Divisible by Three/README.md

+153-24
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,24 @@
4848

4949
**方法一:动态规划**
5050

51-
我们定义 $f[j]$ 表示前 $i-1$ 个数中,余数为 $j$ 的最大和。那么对于当前的数 $x$,我们可以将其加入到前面的数中,得到的和为 $f[j] + x$,其中 $j$ 为 $(f[j] + x) \bmod 3$。
51+
我们定义 $f[i][j]$ 表示前 $i$ 个数中选取若干个数,使得这若干个数的和模 $3$ 余 $j$ 的最大值。初始时 $f[0][0]=0$,其余为 $-\infty$。
5252

53-
最后,我们返回 $f[0]$ 即可。
53+
对于 $f[i][j]$,我们可以考虑第 $i$ 个数 $x$ 的状态:
5454

55-
时间复杂度 $O(n)$,空间复杂度 $O(1)$。其中 $n$ 为数组 `nums` 的长度。
55+
- 如果我们不选 $x$,那么 $f[i][j]=f[i-1][j]$;
56+
- 如果我们选 $x$,那么 $f[i][j]=f[i-1][(j-x \bmod 3 + 3)\bmod 3]+x$。
57+
58+
因此我们可以得到状态转移方程:
59+
60+
$$
61+
f[i][j]=\max\{f[i-1][j],f[i-1][(j-x \bmod 3 + 3)\bmod 3]+x\}
62+
$$
63+
64+
最终答案为 $f[n][0]$。
65+
66+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 $nums$ 的长度。
67+
68+
注意到 $f[i][j]$ 的值只与 $f[i-1][j]$ 和 $f[i-1][(j-x \bmod 3 + 3)\bmod 3]$ 有关,因此我们可以使用滚动数组优化空间复杂度,使空间复杂度降低为 $O(1)$。
5669

5770
<!-- tabs:start -->
5871

@@ -63,12 +76,24 @@
6376
```python
6477
class Solution:
6578
def maxSumDivThree(self, nums: List[int]) -> int:
66-
f = [0] * 3
79+
n = len(nums)
80+
f = [[-inf] * 3 for _ in range(n + 1)]
81+
f[0][0] = 0
82+
for i, x in enumerate(nums, 1):
83+
for j in range(3):
84+
f[i][j] = max(f[i - 1][j], f[i - 1][(j - x) % 3] + x)
85+
return f[n][0]
86+
```
87+
88+
```python
89+
class Solution:
90+
def maxSumDivThree(self, nums: List[int]) -> int:
91+
f = [0, -inf, -inf]
6792
for x in nums:
68-
a, b, c = f[0] + x, f[1] + x, f[2] + x
69-
f[a % 3] = max(f[a % 3], a)
70-
f[b % 3] = max(f[b % 3], b)
71-
f[c % 3] = max(f[c % 3], c)
93+
g = f[:]
94+
for j in range(3):
95+
g[j] = max(f[j], f[(j - x) % 3] + x)
96+
f = g
7297
return f[0]
7398
```
7499

@@ -79,12 +104,32 @@ class Solution:
79104
```java
80105
class Solution {
81106
public int maxSumDivThree(int[] nums) {
82-
int[] f = new int[3];
107+
int n = nums.length;
108+
final int inf = 1 << 30;
109+
int[][] f = new int[n + 1][3];
110+
f[0][1] = f[0][2] = -inf;
111+
for (int i = 1; i <= n; ++i) {
112+
int x = nums[i - 1];
113+
for (int j = 0; j < 3; ++j) {
114+
f[i][j] = Math.max(f[i - 1][j], f[i - 1][(j - x % 3 + 3) % 3] + x);
115+
}
116+
}
117+
return f[n][0];
118+
}
119+
}
120+
```
121+
122+
```java
123+
class Solution {
124+
public int maxSumDivThree(int[] nums) {
125+
final int inf = 1 << 30;
126+
int[] f = new int[] {0, -inf, -inf};
83127
for (int x : nums) {
84-
int a = f[0] + x, b = f[1] + x, c = f[2] + x;
85-
f[a % 3] = Math.max(f[a % 3], a);
86-
f[b % 3] = Math.max(f[b % 3], b);
87-
f[c % 3] = Math.max(f[c % 3], c);
128+
int[] g = f.clone();
129+
for (int j = 0; j < 3; ++j) {
130+
g[j] = Math.max(f[j], f[(j - x % 3 + 3) % 3] + x);
131+
}
132+
f = g;
88133
}
89134
return f[0];
90135
}
@@ -97,12 +142,34 @@ class Solution {
97142
class Solution {
98143
public:
99144
int maxSumDivThree(vector<int>& nums) {
100-
int f[3]{};
101-
for (int x : nums) {
102-
int a = f[0] + x, b = f[1] + x, c = f[2] + x;
103-
f[a % 3] = max(f[a % 3], a);
104-
f[b % 3] = max(f[b % 3], b);
105-
f[c % 3] = max(f[c % 3], c);
145+
int n = nums.size();
146+
const int inf = 1 << 30;
147+
int f[n + 1][3];
148+
f[0][0] = 0;
149+
f[0][1] = f[0][2] = -inf;
150+
for (int i = 1; i <= n; ++i) {
151+
int x = nums[i - 1];
152+
for (int j = 0; j < 3; ++j) {
153+
f[i][j] = max(f[i - 1][j], f[i - 1][(j - x % 3 + 3) % 3] + x);
154+
}
155+
}
156+
return f[n][0];
157+
}
158+
};
159+
```
160+
161+
```cpp
162+
class Solution {
163+
public:
164+
int maxSumDivThree(vector<int>& nums) {
165+
const int inf = 1 << 30;
166+
vector<int> f = {0, -inf, -inf};
167+
for (int& x : nums) {
168+
vector<int> g = f;
169+
for (int j = 0; j < 3; ++j) {
170+
g[j] = max(f[j], f[(j - x % 3 + 3) % 3] + x);
171+
}
172+
f = move(g);
106173
}
107174
return f[0];
108175
}
@@ -113,12 +180,37 @@ public:
113180

114181
```go
115182
func maxSumDivThree(nums []int) int {
116-
f := [3]int{}
183+
n := len(nums)
184+
const inf = 1 << 30
185+
f := make([][3]int, n+1)
186+
f[0] = [3]int{0, -inf, -inf}
187+
for i, x := range nums {
188+
i++
189+
for j := 0; j < 3; j++ {
190+
f[i][j] = max(f[i-1][j], f[i-1][(j-x%3+3)%3]+x)
191+
}
192+
}
193+
return f[n][0]
194+
}
195+
196+
func max(a, b int) int {
197+
if a > b {
198+
return a
199+
}
200+
return b
201+
}
202+
```
203+
204+
```go
205+
func maxSumDivThree(nums []int) int {
206+
const inf = 1 << 30
207+
f := [3]int{0, -inf, -inf}
117208
for _, x := range nums {
118-
a, b, c := f[0]+x, f[1]+x, f[2]+x
119-
f[a%3] = max(f[a%3], a)
120-
f[b%3] = max(f[b%3], b)
121-
f[c%3] = max(f[c%3], c)
209+
g := [3]int{}
210+
for j := range f {
211+
g[j] = max(f[j], f[(j-x%3+3)%3]+x)
212+
}
213+
f = g
122214
}
123215
return f[0]
124216
}
@@ -131,6 +223,43 @@ func max(a, b int) int {
131223
}
132224
```
133225

226+
### **TypeScript**
227+
228+
```ts
229+
function maxSumDivThree(nums: number[]): number {
230+
const n = nums.length;
231+
const inf = 1 << 30;
232+
const f: number[][] = Array(n + 1)
233+
.fill(0)
234+
.map(() => Array(3).fill(-inf));
235+
f[0][0] = 0;
236+
for (let i = 1; i <= n; ++i) {
237+
const x = nums[i - 1];
238+
for (let j = 0; j < 3; ++j) {
239+
f[i][j] = Math.max(
240+
f[i - 1][j],
241+
f[i - 1][(j - (x % 3) + 3) % 3] + x,
242+
);
243+
}
244+
}
245+
return f[n][0];
246+
}
247+
```
248+
249+
```ts
250+
function maxSumDivThree(nums: number[]): number {
251+
const inf = 1 << 30;
252+
const f: number[] = [0, -inf, -inf];
253+
for (const x of nums) {
254+
const g = [...f];
255+
for (let j = 0; j < 3; ++j) {
256+
f[j] = Math.max(g[j], g[(j - (x % 3) + 3) % 3] + x);
257+
}
258+
}
259+
return f[0];
260+
}
261+
```
262+
134263
### **...**
135264

136265
```

0 commit comments

Comments
 (0)
Please sign in to comment.