leetcode 2654
2654: 使数组所有元素变成1 的最少操作次数
首先,如果所有数的 GCD(最大公约数)大于 1,那么无论如何都无法操作出 1,我们返回 −1。如果 nums 中有一个 1,那么从 1 向左向右不断替换就能把所有数变成 1。
如果 nums 中没有 1,想办法花费尽量少的操作得出一个 1。由于只能操作相邻的数,所以这个 1 必然是一个连续子数组的 GCD。(如果在不连续的情况下得到了 1,那么这个 1 只能属于其中某个连续子数组,其余的操作是多余的。)那么找到最短的 GCD 为 1 的子数组,设其长度为 minSize,那么我们需要操作 minSize−1 次得到 1。例如 [2,6,3,4] 中的 [3,4] 可以操作 2−1=1 次得到 1。

然后就转化成提示 1 中的情况了,最终答案为(minSize−1)+(n−1)=minSize+n−2
gcd_all=gcd(gcd_all,x);
数学上规定:gcd(0, x) = |x| (任何整数与 0 的最大公约数都是它自身的绝对值)
class Solution {
public:int minOperations(vector<int>& nums) {int n=nums.size();int gcd_all=0,cnt1=0; //数学上规定:gcd(0, x) = |x|for(int x :nums){gcd_all=gcd(gcd_all,x);if(x==1) cnt1++;}if(gcd_all>1) return -1;//如果 nums 中存在 1if(cnt1) return n-cnt1;int minSize=n;for(int i=0;i<n;i++){ //找最短的 GCD 为 1 的子数组int g=0;for(int j=i;j<n;j++){g=gcd(g,nums[j]);if(g==1){minSize=min(minSize,j-i+1); //需要操作 minSize−1 次得到 1break;}}}return minSize+n-2;}
};