返回介绍

solution / 2500-2599 / 2584.Split the Array to Make Coprime Products / README

发布于 2024-06-17 01:03:03 字数 5306 浏览 0 评论 0 收藏 0

2584. 分割数组使乘积互质

English Version

题目描述

给你一个长度为 n 的整数数组 nums ,下标从 0 开始。

如果在下标 i分割 数组,其中 0 <= i <= n - 2 ,使前 i + 1 个元素的乘积和剩余元素的乘积互质,则认为该分割 有效

  • 例如,如果 nums = [2, 3, 3] ,那么在下标 i = 0 处的分割有效,因为 29 互质,而在下标 i = 1 处的分割无效,因为 63 不互质。在下标 i = 2 处的分割也无效,因为 i == n - 1

返回可以有效分割数组的最小下标 i ,如果不存在有效分割,则返回 -1

当且仅当 gcd(val1, val2) == 1 成立时,val1val2 这两个值才是互质的,其中 gcd(val1, val2) 表示 val1val2 的最大公约数。

 

示例 1:

输入:nums = [4,7,8,15,3,5]
输出:2
解释:上表展示了每个下标 i 处的前 i + 1 个元素的乘积、剩余元素的乘积和它们的最大公约数的值。
唯一一个有效分割位于下标 2 。

示例 2:

输入:nums = [4,7,15,8,3,5]
输出:-1
解释:上表展示了每个下标 i 处的前 i + 1 个元素的乘积、剩余元素的乘积和它们的最大公约数的值。
不存在有效分割。

 

提示:

  • n == nums.length
  • 1 <= n <= 104
  • 1 <= nums[i] <= 106

解法

方法一:质因数分解

class Solution:
  def findValidSplit(self, nums: List[int]) -> int:
    first = {}
    n = len(nums)
    last = list(range(n))
    for i, x in enumerate(nums):
      j = 2
      while j <= x // j:
        if x % j == 0:
          if j in first:
            last[first[j]] = i
          else:
            first[j] = i
          while x % j == 0:
            x //= j
        j += 1
      if x > 1:
        if x in first:
          last[first[x]] = i
        else:
          first[x] = i
    mx = last[0]
    for i, x in enumerate(last):
      if mx < i:
        return mx
      mx = max(mx, x)
    return -1
class Solution {
  public int findValidSplit(int[] nums) {
    Map<Integer, Integer> first = new HashMap<>();
    int n = nums.length;
    int[] last = new int[n];
    for (int i = 0; i < n; ++i) {
      last[i] = i;
    }
    for (int i = 0; i < n; ++i) {
      int x = nums[i];
      for (int j = 2; j <= x / j; ++j) {
        if (x % j == 0) {
          if (first.containsKey(j)) {
            last[first.get(j)] = i;
          } else {
            first.put(j, i);
          }
          while (x % j == 0) {
            x /= j;
          }
        }
      }
      if (x > 1) {
        if (first.containsKey(x)) {
          last[first.get(x)] = i;
        } else {
          first.put(x, i);
        }
      }
    }
    int mx = last[0];
    for (int i = 0; i < n; ++i) {
      if (mx < i) {
        return mx;
      }
      mx = Math.max(mx, last[i]);
    }
    return -1;
  }
}
class Solution {
public:
  int findValidSplit(vector<int>& nums) {
    unordered_map<int, int> first;
    int n = nums.size();
    vector<int> last(n);
    iota(last.begin(), last.end(), 0);
    for (int i = 0; i < n; ++i) {
      int x = nums[i];
      for (int j = 2; j <= x / j; ++j) {
        if (x % j == 0) {
          if (first.count(j)) {
            last[first[j]] = i;
          } else {
            first[j] = i;
          }
          while (x % j == 0) {
            x /= j;
          }
        }
      }
      if (x > 1) {
        if (first.count(x)) {
          last[first[x]] = i;
        } else {
          first[x] = i;
        }
      }
    }
    int mx = last[0];
    for (int i = 0; i < n; ++i) {
      if (mx < i) {
        return mx;
      }
      mx = max(mx, last[i]);
    }
    return -1;
  }
};
func findValidSplit(nums []int) int {
  first := map[int]int{}
  n := len(nums)
  last := make([]int, n)
  for i := range last {
    last[i] = i
  }
  for i, x := range nums {
    for j := 2; j <= x/j; j++ {
      if x%j == 0 {
        if k, ok := first[j]; ok {
          last[k] = i
        } else {
          first[j] = i
        }
        for x%j == 0 {
          x /= j
        }
      }
    }
    if x > 1 {
      if k, ok := first[x]; ok {
        last[k] = i
      } else {
        first[x] = i
      }
    }
  }
  mx := last[0]
  for i, x := range last {
    if mx < i {
      return mx
    }
    mx = max(mx, x)
  }
  return -1
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文