You are given a 0-indexed array nums
consisiting of positive integers. You can do the following operation on the array any number of times:
- Select an index
i
such that0 <= i < n - 1
and replace either ofnums[i]
ornums[i+1]
with their gcd value.
Return the minimum number of operations to make all elements of nums
equal to 1
. If it is impossible, return -1
.
The gcd of two integers is the greatest common divisor of the two integers.
Example 1:
Input: nums = [2,6,3,4] Output: 4 Explanation: We can do the following operations: - Choose index i = 2 and replace nums[2] with gcd(3,4) = 1. Now we have nums = [2,6,1,4]. - Choose index i = 1 and replace nums[1] with gcd(6,1) = 1. Now we have nums = [2,1,1,4]. - Choose index i = 0 and replace nums[0] with gcd(2,1) = 1. Now we have nums = [1,1,1,4]. - Choose index i = 2 and replace nums[3] with gcd(1,4) = 1. Now we have nums = [1,1,1,1].
Example 2:
Input: nums = [2,10,6,14] Output: -1 Explanation: It can be shown that it is impossible to make all the elements equal to 1.
Constraints:
2 <= nums.length <= 50
1 <= nums[i] <= 106
Follow-up:
The O(n)
time complexity solution works, but could you find an O(1)
constant time complexity solution?
Related Topics:
Array, Math, Number Theory
- If GCD of all numbers is not 1, impossible.
- If some
A[i]
is already 1, assume there arek
1s, we needN-k
operations to make all 1s. - If GCD of two adjacent numbers is 1, we do one operation here to get a one, then take
N-1
operations to make all 1s. - If no GCD of two adjacent numbers is 1, we find the minimum subarray whose GCD is 1. If this subarray is of length
K
, we takeK-1
operations to get a one, then takeN-1
operations to make all 1s.
// OJ: https://leetcode.com/problems/minimum-number-of-operations-to-make-all-array-elements-equal-to-1
// Author: github.com/lzl124631x
// Time: O(N^2)
// Space: O(1)
class Solution {
public:
int minOperations(vector<int>& A) {
int N = A.size(), mnLen = N, one = 0, all = A[0];
for (int n : A) {
one += n == 1;
all = gcd(all, n);
}
if (one) return N - one;
if (all > 1) return - 1;
for (int i = N - 1; i >= 0; --i) {
int val = A[i], j = i - 1;
for (; j >= 0 && val > 1; --j) {
val = gcd(val, A[j]);
}
if (val == 1) mnLen = min(mnLen, i - j);
else break;
}
return mnLen + N - 2;
}
};