列表

详情


2183. 统计可以被 K 整除的下标对数目

给你一个下标从 0 开始、长度为 n 的整数数组 nums 和一个整数 k ,返回满足下述条件的下标对 (i, j) 的数目:

 

示例 1:

输入:nums = [1,2,3,4,5], k = 2
输出:7
解释:
共有 7 对下标的对应积可以被 2 整除:
(0, 1)、(0, 3)、(1, 2)、(1, 3)、(1, 4)、(2, 3) 和 (3, 4)
它们的积分别是 2、4、6、8、10、12 和 20 。
其他下标对,例如 (0, 2) 和 (2, 4) 的乘积分别是 3 和 15 ,都无法被 2 整除。    

示例 2:

输入:nums = [1,2,3,4], k = 5
输出:0
解释:不存在对应积可以被 5 整除的下标对。

 

提示:

原站题解

去查看

上次编辑到这里,代码来自缓存 点击恢复默认模板
class Solution { public: long long countPairs(vector<int>& nums, int k) { } };

java 解法, 执行用时: 233 ms, 内存消耗: 54.5 MB, 提交时间: 2023-07-01 14:14:28

class Solution {
    public long countPairs(int[] nums, int k) {
        var divisors = new ArrayList<Integer>(); // 预处理 k 的所有因子
        for (var d = 1; d * d <= k; d++) {
            if (k % d == 0) {
                divisors.add(d);
                if (d * d < k) divisors.add(k / d);
            }
        }
        var ans = 0L;
        var cnt = new HashMap<Integer, Integer>();
        for (var v : nums) {
            ans += cnt.getOrDefault(k / gcd(v, k), 0);
            for (var d : divisors)
                if (v % d == 0)
                    cnt.put(d, cnt.getOrDefault(d, 0) + 1);
        }
        return ans;
    }

    static int gcd(int a, int b) {
        return b == 0 ? a : gcd(b, a % b);
    }
}

cpp 解法, 执行用时: 252 ms, 内存消耗: 63.4 MB, 提交时间: 2023-07-01 14:14:17

class Solution {
public:
    long long countPairs(vector<int> &nums, int k) {
        vector<int> divisors; 
        for (int d = 1; d * d <= k; ++d) { // 预处理 k 的所有因子
            if (k % d == 0) {
                divisors.push_back(d);
                if (d * d < k) divisors.push_back(k / d);
            }
        }
        long long ans = 0;
        unordered_map<int, int> cnt;
        for (int v : nums) {
            ans += cnt[k / gcd(v, k)];
            for (int d : divisors)
                if (v % d == 0) ++cnt[d];
        }
        return ans;
    }
};

golang 解法, 执行用时: 204 ms, 内存消耗: 8.5 MB, 提交时间: 2023-07-01 14:14:04

// 统计k的因子
func countPairs(nums []int, k int) (ans int64) {
	divisors := []int{} 
	for d := 1; d*d <= k; d++ { // 预处理 k 的所有因子
		if k%d == 0 {
			divisors = append(divisors, d)
			if d*d < k {
				divisors = append(divisors, k/d)
			}
		}
	}
	cnt := map[int]int{}
	for _, v := range nums {
		ans += int64(cnt[k/gcd(v, k)])
		for _, d := range divisors {
			if v%d == 0 {
				cnt[d]++
			}
		}
	}
	return
}

func gcd(a, b int) int {
	for a != 0 {
		a, b = b%a, a
	}
	return b
}

golang 解法, 执行用时: 432 ms, 内存消耗: 43.5 MB, 提交时间: 2023-07-01 14:13:46

const mx int = 1e5
var divisors [mx + 1][]int

func init() { // 预处理每个数的所有因子,时间复杂度 O(MlogM),M=1e5
	for i := 1; i <= mx; i++ {
		for j := i; j <= mx; j += i {
			divisors[j] = append(divisors[j], i)
		}
	}
}

func countPairs(nums []int, k int) (ans int64) {
	cnt := map[int]int{}
	for _, v := range nums {
		ans += int64(cnt[k/gcd(v, k)])
		for _, d := range divisors[v] {
			cnt[d]++
		}
	}
	return
}

func gcd(a, b int) int {
	for a != 0 {
		a, b = b%a, a
	}
	return b
}

cpp 解法, 执行用时: 688 ms, 内存消耗: 129.4 MB, 提交时间: 2023-07-01 14:13:32

const int mx = 100001;
vector<int> divisors[mx];

int init = []() { // 预处理每个数的所有因子,时间复杂度 O(MlogM),M=1e5
    for (int i = 1; i < mx; ++i)
        for (int j = i; j < mx; j += i)
            divisors[j].push_back(i);
    return 0;
}();

class Solution {
public:
    long long countPairs(vector<int> &nums, int k) {
        long long ans = 0;
        unordered_map<int, int> cnt;
        for (int v : nums) {
            ans += cnt[k / gcd(v, k)];
            for (int d : divisors[v])
                ++cnt[d];
        }
        return ans;
    }
};

java 解法, 执行用时: 499 ms, 内存消耗: 96.9 MB, 提交时间: 2023-07-01 14:13:21

class Solution {
    final static int mx = 100001;
    static ArrayList<ArrayList<Integer>> divisors = new ArrayList<>(mx);
    static {
        for (var i = 0; i < mx; i++)
            divisors.add(new ArrayList<>());
        for (var i = 1; i < mx; ++i) // 预处理每个数的所有因子,时间复杂度 O(MlogM),M=1e5
            for (var j = i; j < mx; j += i)
                divisors.get(j).add(i);
    }

    public long countPairs(int[] nums, int k) {
        var ans = 0L;
        var cnt = new HashMap<Integer, Integer>();
        for (var v : nums) {
            ans += cnt.getOrDefault(k / gcd(v, k), 0);
            for (var d : divisors.get(v))
                cnt.put(d, cnt.getOrDefault(d, 0) + 1);
        }
        return ans;
    }

    static int gcd(int a, int b) {
        return b == 0 ? a : gcd(b, a % b);
    }
}

python3 解法, 执行用时: 1724 ms, 内存消耗: 55 MB, 提交时间: 2023-07-01 14:13:14

# 统计每个数的因子
MX = 100001
divisors = [[] for _ in range(MX)]
for i in range(1, MX):  # 预处理每个数的所有因子,时间复杂度 O(MlogM),M=1e5
    for j in range(i, MX, i):
        divisors[j].append(i)

class Solution:
    def countPairs(self, nums: List[int], k: int) -> int:
        ans = 0
        cnt = Counter()
        for v in nums:
            ans += cnt[k / gcd(v, k)]
            for d in divisors[v]:
                cnt[d] += 1
        return ans

上一题