LC 2584. 分割数组使乘积互质
https://leetcode.cn/contest/weekly-contest-335/problems/split-the-array-to-make-coprime-products/
这题最粗俗的解法就是分解因子,然后记录每个位置上可能的因子个数,然后不断往前推,使得某个点上所有因子的个数都涵盖到了。
我看了这个解法觉得特别有意思 https://leetcode.cn/problems/split-the-array-to-make-coprime-products/solution/ben-zhi-shi-tiao-yue-you-xi-by-endlessch-8chd/
大致思想是,记录每个位置上这个数,它所有的可能因子最远距离。一旦我选择了这个数,那么我就需要选择这个因子,那么就必须跳跃到这个因子的最远位置。
这里面数据结构也非常有意义:
- left[p] 表示p因子第一次出现的位置
- right[i] 表示位置i包含因子的最远位置
from typing import List def get_primes(M): P = [0] * (M + 1) for i in range(2, M + 1): if P[i] == 1: continue for j in range(2, M + 1): if i * j > M: break P[i * j] = 1 primes = [] for i in range(2, M + 1): if P[i] == 0: primes.append(i) return primes class Solution: def findValidSplit(self, nums: List[int]) -> int: M = min(max(nums), 10 ** 3) primes = get_primes(M) left = {} right = [0] * (len(nums)) def update(p, idx): if p not in left: pos = idx left[p] = idx else: pos = left[p] right[pos] = idx for idx, x in enumerate(nums): for p in primes: if x % p == 0: while x % p == 0: x = x // p update(p, idx) if x > 1: update(x, idx) ans = 0 # 假设当前最远位置 for idx, r in enumerate(right): if idx > ans: return ans ans = max(ans, r) return -1