Skip to content

Commit a1a4b07

Browse files
authored
feat: add solutions to lc problem: No.3574 (#4486)
No.3574.Maximize Subarray GCD Score
1 parent 102ce22 commit a1a4b07

File tree

7 files changed

+533
-8
lines changed

7 files changed

+533
-8
lines changed

solution/3500-3599/3574.Maximize Subarray GCD Score/README.md

Lines changed: 182 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,32 +100,210 @@ tags:
100100

101101
<!-- solution:start -->
102102

103-
### 方法一
103+
### 方法一:枚举 + 数学
104+
105+
我们注意到,题目中数组的长度 $n \leq 1500$,因此,我们可以枚举所有的子数组。对于每个子数组,计算其 GCD 分数,找出最大值即为答案。
106+
107+
由于每个数最多只能翻倍一次,那么子数组的 GCD 最多也只能乘以 $2$,因此,我们需要统计子数组中每个数的因子 $2$ 的个数的最小值,以及这个最小值的出现次数。如果次数大于 $k$,则 GCD 分数为 GCD,否则 GCD 分数为 GCD 乘以 $2$。
108+
109+
因此,我们可以预处理每个数的因子 $2$ 的个数,然后在枚举子数组时,维护当前子数组的 GCD、最小因子 $2$ 的个数以及其出现次数即可。
110+
111+
时间复杂度 $O(n^2 \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 是数组 $\textit{nums}$ 的长度。
104112

105113
<!-- tabs:start -->
106114

107115
#### Python3
108116

109117
```python
110-
118+
class Solution:
119+
def maxGCDScore(self, nums: List[int], k: int) -> int:
120+
n = len(nums)
121+
cnt = [0] * n
122+
for i, x in enumerate(nums):
123+
while x % 2 == 0:
124+
cnt[i] += 1
125+
x //= 2
126+
ans = 0
127+
for l in range(n):
128+
g = 0
129+
mi = inf
130+
t = 0
131+
for r in range(l, n):
132+
g = gcd(g, nums[r])
133+
if cnt[r] < mi:
134+
mi = cnt[r]
135+
t = 1
136+
elif cnt[r] == mi:
137+
t += 1
138+
ans = max(ans, (g if t > k else g * 2) * (r - l + 1))
139+
return ans
111140
```
112141

113142
#### Java
114143

115144
```java
116-
145+
class Solution {
146+
public long maxGCDScore(int[] nums, int k) {
147+
int n = nums.length;
148+
int[] cnt = new int[n];
149+
for (int i = 0; i < n; ++i) {
150+
for (int x = nums[i]; x % 2 == 0; x /= 2) {
151+
++cnt[i];
152+
}
153+
}
154+
long ans = 0;
155+
for (int l = 0; l < n; ++l) {
156+
int g = 0;
157+
int mi = 1 << 30;
158+
int t = 0;
159+
for (int r = l; r < n; ++r) {
160+
g = gcd(g, nums[r]);
161+
if (cnt[r] < mi) {
162+
mi = cnt[r];
163+
t = 1;
164+
} else if (cnt[r] == mi) {
165+
++t;
166+
}
167+
ans = Math.max(ans, (r - l + 1L) * (t > k ? g : g * 2));
168+
}
169+
}
170+
return ans;
171+
}
172+
173+
private int gcd(int a, int b) {
174+
return b == 0 ? a : gcd(b, a % b);
175+
}
176+
}
117177
```
118178

119179
#### C++
120180

121181
```cpp
122-
182+
class Solution {
183+
public:
184+
long long maxGCDScore(vector<int>& nums, int k) {
185+
int n = nums.size();
186+
vector<int> cnt(n);
187+
for (int i = 0; i < n; ++i) {
188+
for (int x = nums[i]; x % 2 == 0; x /= 2) {
189+
++cnt[i];
190+
}
191+
}
192+
193+
long long ans = 0;
194+
for (int l = 0; l < n; ++l) {
195+
int g = 0;
196+
int mi = INT32_MAX;
197+
int t = 0;
198+
for (int r = l; r < n; ++r) {
199+
g = gcd(g, nums[r]);
200+
if (cnt[r] < mi) {
201+
mi = cnt[r];
202+
t = 1;
203+
} else if (cnt[r] == mi) {
204+
++t;
205+
}
206+
long long score = static_cast<long long>(r - l + 1) * (t > k ? g : g * 2);
207+
ans = max(ans, score);
208+
}
209+
}
210+
211+
return ans;
212+
}
213+
};
123214
```
124215

125216
#### Go
126217

127218
```go
219+
func maxGCDScore(nums []int, k int) int64 {
220+
n := len(nums)
221+
cnt := make([]int, n)
222+
for i, x := range nums {
223+
for x%2 == 0 {
224+
cnt[i]++
225+
x /= 2
226+
}
227+
}
228+
229+
ans := 0
230+
for l := 0; l < n; l++ {
231+
g := 0
232+
mi := math.MaxInt32
233+
t := 0
234+
for r := l; r < n; r++ {
235+
g = gcd(g, nums[r])
236+
if cnt[r] < mi {
237+
mi = cnt[r]
238+
t = 1
239+
} else if cnt[r] == mi {
240+
t++
241+
}
242+
length := r - l + 1
243+
score := g * length
244+
if t <= k {
245+
score *= 2
246+
}
247+
ans = max(ans, score)
248+
}
249+
}
250+
251+
return int64(ans)
252+
}
253+
254+
func gcd(a, b int) int {
255+
for b != 0 {
256+
a, b = b, a%b
257+
}
258+
return a
259+
}
260+
```
128261

262+
#### TypeScript
263+
264+
```ts
265+
function maxGCDScore(nums: number[], k: number): number {
266+
const n = nums.length;
267+
const cnt: number[] = Array(n).fill(0);
268+
269+
for (let i = 0; i < n; ++i) {
270+
let x = nums[i];
271+
while (x % 2 === 0) {
272+
cnt[i]++;
273+
x /= 2;
274+
}
275+
}
276+
277+
let ans = 0;
278+
for (let l = 0; l < n; ++l) {
279+
let g = 0;
280+
let mi = Number.MAX_SAFE_INTEGER;
281+
let t = 0;
282+
for (let r = l; r < n; ++r) {
283+
g = gcd(g, nums[r]);
284+
if (cnt[r] < mi) {
285+
mi = cnt[r];
286+
t = 1;
287+
} else if (cnt[r] === mi) {
288+
t++;
289+
}
290+
const len = r - l + 1;
291+
const score = (t > k ? g : g * 2) * len;
292+
ans = Math.max(ans, score);
293+
}
294+
}
295+
296+
return ans;
297+
}
298+
299+
function gcd(a: number, b: number): number {
300+
while (b !== 0) {
301+
const temp = b;
302+
b = a % b;
303+
a = temp;
304+
}
305+
return a;
306+
}
129307
```
130308

131309
<!-- tabs:end -->

0 commit comments

Comments
 (0)