You are given a 0-indexed integer array nums of length n.
A split at an index i where 0 <= i <= n - 2 is called valid if the product of the first i + 1 elements and the product of the remaining elements are coprime.
For example, if nums = [2, 3, 3], then a split at the index i = 0 is valid because 2 and 9 are coprime, while a split at the index i = 1 is not valid because 6 and 3 are not coprime. A split at the index i = 2 is not valid because i == n - 1.
Return the smallest indexiat which the array can be split validly or-1if there is no such split.
Two values val1 and val2 are coprime if gcd(val1, val2) == 1 where
gcd(val1, val2) is the greatest common divisor of val1 and val2.
Input: nums =[4,7,8,15,3,5]Output: 2Explanation: The table above shows the values of the product of the first i +1 elements, the remaining elements, and their gcd at each index i.The only valid split is at index 2.
Input: nums =[4,7,15,8,3,5]Output: -1Explanation: The table above shows the values of the product of the first i +1 elements, the remaining elements, and their gcd at each index i.There is no valid split.
If a prime factor appears in both the prefix and suffix products, the two products cannot be coprime. Track the last occurrence of each prime factor in the array, and find the earliest split where all prime factors in the prefix are not present in the suffix.
classSolution {
public:int findValidSplit(vector<int>& nums) {
int n = nums.size();
unordered_map<int, int> last;
auto factorize = [](int x) {
vector<int> f;
for (int d =2; d * d <= x; ++d) {
if (x % d ==0) {
f.push_back(d);
while (x % d ==0) x /= d;
}
}
if (x >1) f.push_back(x);
return f;
};
for (int i =0; i < n; ++i) {
for (int p : factorize(nums[i])) last[p] = i;
}
int maxLast =0;
for (int i =0; i < n-1; ++i) {
for (int p : factorize(nums[i])) maxLast = max(maxLast, last[p]);
if (maxLast == i) return i;
}
return-1;
}
};
classSolution {
publicintfindValidSplit(int[] nums) {
int n = nums.length;
Map<Integer, Integer> last =new HashMap<>();
for (int i = 0; i < n; ++i) {
for (int p : factorize(nums[i])) last.put(p, i);
}
int maxLast = 0;
for (int i = 0; i < n-1; ++i) {
for (int p : factorize(nums[i])) maxLast = Math.max(maxLast, last.get(p));
if (maxLast == i) return i;
}
return-1;
}
private List<Integer>factorize(int x) {
List<Integer> f =new ArrayList<>();
for (int d = 2; d * d <= x; ++d) {
if (x % d == 0) {
f.add(d);
while (x % d == 0) x /= d;
}
}
if (x > 1) f.add(x);
return f;
}
}
classSolution {
funfindValidSplit(nums: IntArray): Int {
val n = nums.size
val last = mutableMapOf<Int, Int>()
funfactorize(x: Int): List<Int> {
val f = mutableListOf<Int>()
var y = x
var d = 2while (d * d <= y) {
if (y % d ==0) {
f.add(d)
while (y % d ==0) y /= d
}
d++ }
if (y > 1) f.add(y)
return f
}
for (i in0 until n) {
for (p in factorize(nums[i])) last[p] = i
}
var maxLast = 0for (i in0 until n-1) {
for (p in factorize(nums[i])) maxLast = maxOf(maxLast, last[p]!!)
if (maxLast == i) return i
}
return -1 }
}
deffindValidSplit(nums: list[int]) -> int:
deffactorize(x: int) -> list[int]:
f = []
d =2while d * d <= x:
if x % d ==0:
f.append(d)
while x % d ==0:
x //= d
d +=1if x >1:
f.append(x)
return f
n = len(nums)
last = {}
for i, v in enumerate(nums):
for p in factorize(v):
last[p] = i
max_last =0for i in range(n-1):
for p in factorize(nums[i]):
max_last = max(max_last, last[p])
if max_last == i:
return i
return-1
impl Solution {
pubfnfind_valid_split(nums: Vec<i32>) -> i32 {
fnfactorize(x: i32) -> Vec<i32> {
letmut f =vec![];
letmut y = x;
letmut d =2;
while d * d <= y {
if y % d ==0 {
f.push(d);
while y % d ==0 { y /= d; }
}
d +=1;
}
if y >1 { f.push(y); }
f
}
let n = nums.len();
letmut last = std::collections::HashMap::new();
for (i, &v) in nums.iter().enumerate() {
for p in factorize(v) {
last.insert(p, i);
}
}
letmut max_last =0;
for i in0..n-1 {
for p in factorize(nums[i]) {
iflet Some(&idx) = last.get(&p) {
if idx > max_last { max_last = idx; }
}
}
if max_last == i { return i asi32; }
}
-1 }
}