使用哈希映射计算每个 window 中的不同元素
Count distinct elements in every window using hash map
给定一个大小为 N 的数组 A[] 和一个整数 K。您的任务是完成函数 countDistinct(),它打印数组 A 中大小为 k 的所有 windows 中不同数字的计数[].
Constraints:
1 <= T <= 100
1 <= N <= K <= 105
1 <= A[i] <= 105 , for each valid i
Input:
The first line of input contains an integer T denoting the number of test cases. Then T test cases follow. Each test case contains two integers N and K. Then in the next line are N space separated values of the array A[].
Output:
For each test case in a new line print the space separated values denoting counts of distinct numbers in all windows of size k in the array A[].
Example(To be used only for expected output):
Input:
2
7 4
1 2 1 3 4 2 3
3 2
4 1 1
Output:
3 4 4 3
2 1
解决方案:
void countDistinct(int A[], int k, int n) {
map<int, int> hash;
int cnt=0;
for(int i=0;i<n;i++) {
if(i<k){
hash[A[i]]++;
}
if(i==k-1) {
cout<<hash.size()<<" ";
}
if(i>=k){
if(hash[A[i-k]]==1){
hash.erase(A[i-k]);
} else {
hash[A[i-k]]--;
}
hash[A[i]]++;
cout<<hash.size()<<" ";
}
}
}
其中A[]是数组,n是数组的大小,k是window的大小。
算法:
1. 使用哈希映射存储元素计数,直到 i==k。
2.当i==k时,递减或擦除map中的A[i-k]计数;也增加了 A[i] 的数量。
3. 打印 window k.
中不同计数的 hashmap 大小
我用过的算法是O(n),但是geeksforgeeks给出了Time Limit Exceeded错误。
我哪里出错了吗?
这可能是因为使用了map,因为在map中插入和搜索需要O(log N)时间,而在unordered_map中,这些操作平均需要O(1)时间。另外我认为 N 和 K 在所有测试用例中都接近 10^5,所以通过使用 map 它需要 O(T * N * O(log K)) 使得时间复杂度在 O(100 * 100000 * 17) 即 O(1.7*10^8).
因此使用unordered_map如下:
void countDistinct(int A[], int k, int n) {
unordered_map<int, int> hash;
int cnt=0;
for(int i=0;i<n;i++) {
if(i<k){
hash[A[i]]++;
}
if(i==k-1) {
cout<<hash.size()<<" ";
}
if(i>=k){
if(hash[A[i-k]]==1){
hash.erase(A[i-k]);
} else {
hash[A[i-k]]--;
}
hash[A[i]]++;
cout<<hash.size()<<" ";
}
}
}
极客对极客的判决
给定一个大小为 N 的数组 A[] 和一个整数 K。您的任务是完成函数 countDistinct(),它打印数组 A 中大小为 k 的所有 windows 中不同数字的计数[].
Constraints:
1 <= T <= 100
1 <= N <= K <= 105
1 <= A[i] <= 105 , for each valid i
Input:
The first line of input contains an integer T denoting the number of test cases. Then T test cases follow. Each test case contains two integers N and K. Then in the next line are N space separated values of the array A[].
Output:
For each test case in a new line print the space separated values denoting counts of distinct numbers in all windows of size k in the array A[].
Example(To be used only for expected output):
Input:
2
7 4
1 2 1 3 4 2 3
3 2
4 1 1
Output:
3 4 4 3
2 1
解决方案:
void countDistinct(int A[], int k, int n) {
map<int, int> hash;
int cnt=0;
for(int i=0;i<n;i++) {
if(i<k){
hash[A[i]]++;
}
if(i==k-1) {
cout<<hash.size()<<" ";
}
if(i>=k){
if(hash[A[i-k]]==1){
hash.erase(A[i-k]);
} else {
hash[A[i-k]]--;
}
hash[A[i]]++;
cout<<hash.size()<<" ";
}
}
}
其中A[]是数组,n是数组的大小,k是window的大小。 算法: 1. 使用哈希映射存储元素计数,直到 i==k。 2.当i==k时,递减或擦除map中的A[i-k]计数;也增加了 A[i] 的数量。 3. 打印 window k.
中不同计数的 hashmap 大小我用过的算法是O(n),但是geeksforgeeks给出了Time Limit Exceeded错误。 我哪里出错了吗?
这可能是因为使用了map,因为在map中插入和搜索需要O(log N)时间,而在unordered_map中,这些操作平均需要O(1)时间。另外我认为 N 和 K 在所有测试用例中都接近 10^5,所以通过使用 map 它需要 O(T * N * O(log K)) 使得时间复杂度在 O(100 * 100000 * 17) 即 O(1.7*10^8).
因此使用unordered_map如下:
void countDistinct(int A[], int k, int n) {
unordered_map<int, int> hash;
int cnt=0;
for(int i=0;i<n;i++) {
if(i<k){
hash[A[i]]++;
}
if(i==k-1) {
cout<<hash.size()<<" ";
}
if(i>=k){
if(hash[A[i-k]]==1){
hash.erase(A[i-k]);
} else {
hash[A[i-k]]--;
}
hash[A[i]]++;
cout<<hash.size()<<" ";
}
}
}
极客对极客的判决