【一看就会一写就废 指间算法】替换数组中的非互质数 —— 栈

43 阅读2分钟

指尖划过的轨迹,藏着最细腻的答案~

题目:

给你一个整数数组 nums 。请你对数组执行下述操作:

  1. nums 中找出任意两个相邻的非互质数。
  2. 如果不存在这样的数,终止这一过程。
  3. 否则,删除这两个数,并替换为它们的最小公倍数(Least Common Multiple,LCM)。
  4. 只要还能找出两个相邻的非互质数就继续重复这一过程。

返回修改后得到的最终数组。可以证明的是,以任意顺序替换相邻的非互质数都可以得到相同的结果。

生成的测试用例可以保证最终数组中的值小于或者等于 (10^8) 。

两个数字 xy 满足非互质数的条件是:GCD(x, y) > 1 ,其中 GCD(x, y)xy 的最大公约数。

示例 1 :

输入:nums = [6,4,3,2,7,6,2] 输出:[12,7,6] 解释:

  • (6, 4) 是一组非互质数,且 LCM(6, 4) = 12 。得到 nums = [12,3,2,7,6,2]
  • (12, 3) 是一组非互质数,且 LCM(12, 3) = 12 。得到 nums = [12,2,7,6,2]
  • (12, 2) 是一组非互质数,且 LCM(12, 2) = 12 。得到 nums = [12,7,6,2]
  • (6, 2) 是一组非互质数,且 LCM(6, 2) = 6 。得到 nums = [12,7,6] 。 现在,nums 中不存在相邻的非互质数。 因此,修改后得到的最终数组是 [12,7,6] 。 注意,存在其他方法可以获得相同的最终数组。

示例 2 :

输入:nums = [2,2,1,1,3,3,3] 输出:[2,1,1,3] 解释:

  • (3, 3) 是一组非互质数,且 LCM(3, 3) = 3 。得到 nums = [2,2,1,1,3,3]
  • (3, 3) 是一组非互质数,且 LCM(3, 3) = 3 。得到 nums = [2,2,1,1,3]
  • (2, 2) 是一组非互质数,且 LCM(2, 2) = 2 。得到 nums = [2,1,1,3] 。 现在,nums 中不存在相邻的非互质数。 因此,修改后得到的最终数组是 [2,1,1,3] 。 注意,存在其他方法可以获得相同的最终数组。

提示:

  • (1 ≤ nums.length ≤10^5)
  • (1 ≤ nums[i] ≤ 10^5)
  • 生成的测试用例可以保证最终数组中的值小于或者等于 (10^8) 。

分析:

题目中说了:以任意顺序替换相邻的非互质数都可以得到相同的结果。因此我们从前往后遍历nums数组,设x=nums[i]。如果栈不为空且 x 与栈顶不互质,那么弹出栈顶 y,更新 x 为 LCM(x,y)。循环直到栈为空或者 x 与栈顶互质。 把 x 入栈。

AC代码:

class Solution {
public:
    vector<int> replaceNonCoprimes(vector<int>& nums) {
        vector<int> st;
        for (int x : nums) {
            while(!st.empty() && gcd(x, st.back()) > 1) {
                x = lcm(x, st.back());
                st.pop_back();
            }

            st.push_back(x);
        }

        return st;
    }
};