1. 问题描述:
给你一个整数数组 nums 。请你对数组执行下述操作:
从 nums 中找出任意两个相邻的非互质 。
如果不存在这样的数,终止这一过程。
否则,删除这两个数,并替换为它们的最小公倍数(Least Common Multiple,LCM)。
只要还能找出两个相邻的非互质数就继续重复这一过程。
返回修改后得到的最终数组。可以证明的是,以任意序替换相邻的非互质数都可以得到相同的结果。生成的测试用例可以保证最终数组中的值 小于或者等于 108 。两个数字 x 和 y 满足非互质数 的条件是:GCD(x, y) > 1 ,其中 GCD(x, y) 是 x 和 y 的 最大公约数 。
示例 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 。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/replace-non-coprime-numbers-in-array/
2. 思路分析:
分析题目可以知道以任意顺序替换相邻的两个非质数最终答案是一样的所以我们可以从前往后枚举,可以使用栈来模拟整个过程,判断栈顶元素与枚举的元素是否互质,如果互质那么直接加到栈顶否则将他们的最小公倍数加到栈顶,此时需要注意的是当加入到栈顶之后可能栈顶两个元素此时不互质所以我们需要使用循环将这些相邻的两个数字全部转为互为质数,模拟整个过程即可。
3. 代码如下:
from typing import List
class Solution:
def gcd(self, a: int, b: int):
return a if b == 0 else self.gcd(b, a % b)
def replaceNonCoprimes(self, nums: List[int]) -> List[int]:
# 从前往后枚举
stack = list()
for i in range(len(nums)):
x = nums[i]
if stack:
y = stack[-1]
if self.gcd(x, y) != 1:
stack.pop()
stack.append(x * y // self.gcd(x, y))
# 判断当前栈顶加了数字之后会不会栈中两个元素出现不互质的情况
while len(stack) > 1:
x, y = stack[-1], stack[-2]
if self.gcd(x, y) != 1:
x = stack.pop()
y = stack.pop()
stack.append(x * y // self.gcd(x, y))
else:
break
else:
stack.append(x)
else:
stack.append(x)
return stack