Input: nums =[2,6,3,4,3]Output: 2Explanation: We can create a valid split in the following way:[2,6]|[3,4,3].- The starting element of the 1st subarray is2 and the ending is6. Their greatest common divisor is2, which is greater than 1.- The starting element of the 2nd subarray is3 and the ending is3. Their greatest common divisor is3, which is greater than 1.It can be proved that 2is the minimum number of subarrays that we can obtain in a valid split.
Example 2:
1
2
3
4
5
6
Input: nums =[3,5]Output: 2Explanation: We can create a valid split in the following way:[3]|[5].- The starting element of the 1st subarray is3 and the ending is3. Their greatest common divisor is3, which is greater than 1.- The starting element of the 2nd subarray is5 and the ending is5. Their greatest common divisor is5, which is greater than 1.It can be proved that 2is the minimum number of subarrays that we can obtain in a valid split.
Example 3:
1
2
3
Input: nums =[1,2,1]Output: -1Explanation: It is impossible to create valid split.
We want to split the array into the minimum number of contiguous subarrays such that the GCD of the first and last element of each subarray is greater than 1. We can use DP: for each position, try to extend the current subarray as far as possible, and split only when necessary.
Let dp[i] be the minimum number of subarrays for nums[0..i]. For each j < i, if gcd(nums[j], nums[i]) > 1, we can split at j. We initialize dp[0] = 1, and for each i, check all possible splits.
classSolution {
privatefungcd(a: Int, b: Int): Int {
var x = a; var y = b
while (y !=0) { val t = y; y = x % y; x = t }
return x
}
funminimumSubarrays(nums: IntArray): Int {
val n = nums.size
val dp = IntArray(n) { Int.MAX_VALUE }
for (i in0 until n) {
for (j in0..i) {
if (gcd(nums[j], nums[i]) > 1) {
val prev = if (j > 0) dp[j-1] else0 dp[i] = minOf(dp[i], prev+1)
}
}
}
returnif (dp[n-1] ==Int.MAX_VALUE) -1else dp[n-1]
}
}
1
2
3
4
5
6
7
8
9
10
11
from math import gcd
classSolution:
defminimumSubarrays(self, nums: list[int]) -> int:
n = len(nums)
dp = [float('inf')] * n
for i in range(n):
for j in range(i+1):
if gcd(nums[j], nums[i]) >1:
prev = dp[j-1] if j >0else0 dp[i] = min(dp[i], prev+1)
return-1if dp[-1] == float('inf') else dp[-1]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
impl Solution {
pubfnminimum_subarrays(nums: Vec<i32>) -> i32 {
fngcd(mut a: i32, mut b: i32) -> i32 {
while b !=0 { let t = b; b = a % b; a = t; } a
}
let n = nums.len();
letmut dp =vec![i32::MAX; n];
for i in0..n {
for j in0..=i {
if gcd(nums[j], nums[i]) >1 {
let prev =if j >0 { dp[j-1] } else { 0 };
dp[i] = dp[i].min(prev+1);
}
}
}
if dp[n-1] ==i32::MAX { -1 } else { dp[n-1] }
}
}