Skip to content

Latest commit

 

History

History

2261.K Divisible Elements Subarrays

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 

English Version

题目描述

给你一个整数数组 nums 和两个整数 kp ,找出并返回满足要求的不同的子数组数,要求子数组中最多 k 个可被 p 整除的元素。

如果满足下述条件之一,则认为数组 nums1nums2不同 数组:

  • 两数组长度 不同 ,或者
  • 存在 至少 一个下标 i 满足 nums1[i] != nums2[i]

子数组 定义为:数组中的连续元素组成的一个 非空 序列。

 

示例 1:

输入:nums = [2,3,3,2,2], k = 2, p = 2
输出:11
解释:
位于下标 0、3 和 4 的元素都可以被 p = 2 整除。
共计 11 个不同子数组都满足最多含 k = 2 个可以被 2 整除的元素:
[2]、[2,3]、[2,3,3]、[2,3,3,2]、[3]、[3,3]、[3,3,2]、[3,3,2,2]、[3,2]、[3,2,2] 和 [2,2] 。
注意,尽管子数组 [2] 和 [3] 在 nums 中出现不止一次,但统计时只计数一次。
子数组 [2,3,3,2,2] 不满足条件,因为其中有 3 个元素可以被 2 整除。

示例 2:

输入:nums = [1,2,3,4], k = 4, p = 1
输出:10
解释:
nums 中的所有元素都可以被 p = 1 整除。
此外,nums 中的每个子数组都满足最多 4 个元素可以被 1 整除。
因为所有子数组互不相同,因此满足所有限制条件的子数组总数为 10 。

 

提示:

  • 1 <= nums.length <= 200
  • 1 <= nums[i], p <= 200
  • 1 <= k <= nums.length

 

进阶:

你可以设计并实现时间复杂度为 O(n2) 的算法解决此问题吗?

解法

方法一:哈希表 + 枚举

我们可以枚举子数组的左右端点 $i$$j$,其中 $0 \leq i \leq j &lt; n$。对于每个子数组 $nums[i,..j]$,我们可以统计其中可以被 $p$ 整除的元素的个数 $cnt$,如果 $cnt \leq k$,则该子数组满足条件。我们将所有满足条件的子数组的元素序列作为字符串存入哈希表中,最后哈希表中的元素个数即为答案。

时间复杂度 $O(n^3)$,空间复杂度 $O(n^2)$。其中 $n$ 为数组 $nums$ 的长度。

Python3

class Solution:
    def countDistinct(self, nums: List[int], k: int, p: int) -> int:
        n = len(nums)
        s = set()
        for i in range(n):
            cnt = 0
            for j in range(i, n):
                cnt += nums[j] % p == 0
                if cnt > k:
                    break
                s.add(tuple(nums[i : j + 1]))
        return len(s)
class Solution:
    def countDistinct(self, nums: List[int], k: int, p: int) -> int:
        n = len(nums)
        s = set()
        for i in range(n):
            cnt = 0
            t = ""
            for x in nums[i:]:
                cnt += x % p == 0
                if cnt > k:
                    break
                t += str(x) + ","
                s.add(t)
        return len(s)

Java

class Solution {
    public int countDistinct(int[] nums, int k, int p) {
        int n = nums.length;
        Set<String> s = new HashSet<>();
        for (int i = 0; i < n; ++i) {
            int cnt = 0;
            String t = "";
            for (int j = i; j < n; ++j) {
                if (nums[j] % p == 0 && ++cnt > k) {
                    break;
                }
                t += nums[j] + ",";
                s.add(t);
            }
        }
        return s.size();
    }
}

C++

class Solution {
public:
    int countDistinct(vector<int>& nums, int k, int p) {
        unordered_set<string> s;
        int n = nums.size();
        for (int i = 0; i < n; ++i) {
            int cnt = 0;
            string t;
            for (int j = i; j < n; ++j) {
                if (nums[j] % p == 0 && ++cnt > k) {
                    break;
                }
                t += to_string(nums[j]) + ",";
                s.insert(t);
            }
        }
        return s.size();
    }
};

Go

func countDistinct(nums []int, k int, p int) int {
	s := map[string]struct{}{}
	for i := range nums {
		cnt, t := 0, ""
		for _, x := range nums[i:] {
			if x%p == 0 {
				cnt++
				if cnt > k {
					break
				}
			}
			t += string(x) + ","
			s[t] = struct{}{}
		}
	}
	return len(s)
}

TypeScript

function countDistinct(nums: number[], k: number, p: number): number {
    const n = nums.length;
    const s = new Set();
    for (let i = 0; i < n; ++i) {
        let cnt = 0;
        let t = '';
        for (let j = i; j < n; ++j) {
            if (nums[j] % p === 0 && ++cnt > k) {
                break;
            }
            t += nums[j].toString() + ',';
            s.add(t);
        }
    }
    return s.size;
}

...