classSolution { publicintfindValidSplit(int[] nums) { intn= nums.length; varleft=newHashMap<Integer, Integer>(); // left[p] 表示质数 p 首次出现的下标 varright=newint[n]; // right[i] 表示左端点为 i 的区间的右端点的最大值
for (inti=0; i < n; i++) { intx= nums[i]; for (intd=2; d * d <= x; ++d) // 分解质因数 if (x % d == 0) { if (left.containsKey(d)) right[left.get(d)] = i; // 记录左端点对应的右端点的最大值 else left.put(d, i); // 第一次遇到质数 d for (x /= d; x % d == 0; x /= d) ; } if (x > 1) if (left.containsKey(x)) right[left.get(x)] = i; else left.put(x, i); }
classSolution { public: intfindValidSplit(vector<int> &nums){ unordered_map<int, int> left; // left[p] 表示质数 p 首次出现的下标 int n = nums.size(), right[n]; // right[i] 表示左端点为 i 的区间的右端点的最大值 memset(right, 0, sizeof(right)); auto f = [&](int p, int i) { auto it = left.find(p); if (it == left.end()) left[p] = i; // 第一次遇到质数 p else right[it->second] = i; // 记录左端点 l 对应的右端点的最大值 };
for (int i = 0; i < n; ++i) { int x = nums[i]; for (int d = 2; d * d <= x; ++d) { // 分解质因数 if (x % d == 0) { f(d, i); for (x /= d; x % d == 0; x /= d); } } if (x > 1) f(x, i); }
for (int l = 0, max_r = 0; l < n; ++l) { if (l > max_r) // 最远可以遇到 max_r return max_r; // 也可以写 l-1 max_r = max(max_r, right[l]); } return-1; } };
funcfindValidSplit(nums []int)int { left := map[int]int{} // left[p] 表示质数 p 首次出现的下标 right := make([]int, len(nums)) // right[i] 表示左端点为 i 的区间的右端点的最大值 f := func(p, i int) { if l, ok := left[p]; ok { right[l] = i // 记录左端点 l 对应的右端点的最大值 } else { left[p] = i // 第一次遇到质数 p } }
for i, x := range nums { for d := 2; d*d <= x; d++ { // 分解质因数 if x%d == 0 { f(d, i) for x /= d; x%d == 0; x /= d { } } } if x > 1 { f(x, i) } }
maxR := 0 for l, r := range right { if l > maxR { // 最远可以遇到 maxR return maxR // 也可以写 l-1 } maxR = max(maxR, r) } return-1 }
funcmax(a, b int)int { if a < b { return b }; return a }
复杂度分析
时间复杂度:O(n\sqrt U),其中 n 为 nums 的长度,U=\max(\textit{nums})。