给定一个由 n 个整数组成的数组。计算具有总不同元素的子数组的总数,与原始数组的总不同元素相同。
例子:
Input : arr[] = {2, 1, 3, 2, 3}
Output : 5
Total distinct elements in array is 3
Total sub-arrays that satisfy the condition
are: Subarray from index 0 to 2
Subarray from index 0 to 3
Subarray from index 0 to 4
Subarray from index 1 to 3
Subarray from index 1 to 4
Input : arr[] = {2, 4, 5, 2, 1}
Output : 2
Input : arr[] = {2, 4, 4, 2, 4}
Output : 9
一种朴素的方法是在另一个内部运行一个循环并考虑所有子数组,对于每个子数组,使用散列计算所有不同的元素,并将它们与原始数组的总不同元素进行比较。这种方法需要 O(n 2 ) 时间。
一种有效的方法是使用滑动窗口在一次迭代中计算所有不同的元素。
- 找出整个数组中不同元素的数量。让这个数字是k <= N 。初始化 Left = 0、Right = 0 和 window = 0。
- 向右递增,直到[Left=0, Right]范围内不同元素的数量等于k (或窗口大小不等于 k),让这个右边为R 1 。现在,由于子数组[Left = 0, R 1 ]有k 个不同的元素,所以所有从Left = 0开始到R 1之后结束的子数组也将有k 个不同的元素。因此,将NR 1 +1添加到答案中,因为[Left.. R 1 ], [Left.. R 1 +1], [Left.. R 1 +2] … [Left.. N-1]包含所有不同的数字。
- 现在保持R 1相同,增加left 。降低前一个元素的频率,即arr[0],如果其频率变为0,则减小窗口大小。现在,子数组是[Left = 1, Right = R 1 ] 。
- 对 Left 和 Right 的其他值重复步骤 2 中的相同过程,直到Left < N 。
C++
// C++ program Count total number of sub-arrays
// having total distinct elements same as that
// original array.
#include
using namespace std;
// Function to calculate distinct sub-array
int countDistictSubarray(int arr[], int n)
{
// Count distinct elements in whole array
unordered_map vis;
for (int i = 0; i < n; ++i)
vis[arr[i]] = 1;
int k = vis.size();
// Reset the container by removing all elements
vis.clear();
// Use sliding window concept to find
// count of subarrays having k distinct
// elements.
int ans = 0, right = 0, window = 0;
for (int left = 0; left < n; ++left)
{
while (right < n && window < k)
{
++vis[ arr[right] ];
if (vis[ arr[right] ] == 1)
++window;
++right;
}
// If window size equals to array distinct
// element size, then update answer
if (window == k)
ans += (n - right + 1);
// Decrease the frequency of previous element
// for next sliding window
--vis[ arr[left] ];
// If frequency is zero then decrease the
// window size
if (vis[ arr[left] ] == 0)
--window;
}
return ans;
}
// Driver code
int main()
{
int arr[] = {2, 1, 3, 2, 3};
int n = sizeof(arr) / sizeof(arr[0]);
cout << countDistictSubarray(arr, n) <<"n";
return 0;
}
Java
// Java program Count total number of sub-arrays
// having total distinct elements same as that
// original array.
import java.util.HashMap;
class Test
{
// Method to calculate distinct sub-array
static int countDistictSubarray(int arr[], int n)
{
// Count distinct elements in whole array
HashMap vis = new HashMap(){
@Override
public Integer get(Object key) {
if(!containsKey(key))
return 0;
return super.get(key);
}
};
for (int i = 0; i < n; ++i)
vis.put(arr[i], 1);
int k = vis.size();
// Reset the container by removing all elements
vis.clear();
// Use sliding window concept to find
// count of subarrays having k distinct
// elements.
int ans = 0, right = 0, window = 0;
for (int left = 0; left < n; ++left)
{
while (right < n && window < k)
{
vis.put(arr[right], vis.get(arr[right]) + 1);
if (vis.get(arr[right])== 1)
++window;
++right;
}
// If window size equals to array distinct
// element size, then update answer
if (window == k)
ans += (n - right + 1);
// Decrease the frequency of previous element
// for next sliding window
vis.put(arr[left], vis.get(arr[left]) - 1);
// If frequency is zero then decrease the
// window size
if (vis.get(arr[left]) == 0)
--window;
}
return ans;
}
// Driver method
public static void main(String args[])
{
int arr[] = {2, 1, 3, 2, 3};
System.out.println(countDistictSubarray(arr, arr.length));
}
}
Python3
# Python3 program Count total number of
# sub-arrays having total distinct elements
# same as that original array.
# Function to calculate distinct sub-array
def countDistictSubarray(arr, n):
# Count distinct elements in whole array
vis = dict()
for i in range(n):
vis[arr[i]] = 1
k = len(vis)
# Reset the container by removing
# all elements
vid = dict()
# Use sliding window concept to find
# count of subarrays having k distinct
# elements.
ans = 0
right = 0
window = 0
for left in range(n):
while (right < n and window < k):
if arr[right] in vid.keys():
vid[ arr[right] ] += 1
else:
vid[ arr[right] ] = 1
if (vid[ arr[right] ] == 1):
window += 1
right += 1
# If window size equals to array distinct
# element size, then update answer
if (window == k):
ans += (n - right + 1)
# Decrease the frequency of previous
# element for next sliding window
vid[ arr[left] ] -= 1
# If frequency is zero then decrease
# the window size
if (vid[ arr[left] ] == 0):
window -= 1
return ans
# Driver code
arr = [2, 1, 3, 2, 3]
n = len(arr)
print(countDistictSubarray(arr, n))
# This code is contributed by
# mohit kumar 29
C#
// C# program Count total number of sub-arrays
// having total distinct elements same as that
// original array.
using System;
using System.Collections.Generic;
class Test
{
// Method to calculate distinct sub-array
static int countDistictSubarray(int []arr, int n)
{
// Count distinct elements in whole array
Dictionary vis = new Dictionary();
for (int i = 0; i < n; ++i)
if(!vis.ContainsKey(arr[i]))
vis.Add(arr[i], 1);
int k = vis.Count;
// Reset the container by removing all elements
vis.Clear();
// Use sliding window concept to find
// count of subarrays having k distinct
// elements.
int ans = 0, right = 0, window = 0;
for (int left = 0; left < n; ++left)
{
while (right < n && window < k)
{
if(vis.ContainsKey(arr[right]))
vis[arr[right]] = vis[arr[right]] + 1;
else
vis.Add(arr[right], 1);
if (vis[arr[right]] == 1)
++window;
++right;
}
// If window size equals to array distinct
// element size, then update answer
if (window == k)
ans += (n - right + 1);
// Decrease the frequency of previous element
// for next sliding window
if(vis.ContainsKey(arr[left]))
vis[arr[left]] = vis[arr[left]] - 1;
// If frequency is zero then decrease the
// window size
if (vis[arr[left]] == 0)
--window;
}
return ans;
}
// Driver method
public static void Main(String []args)
{
int []arr = {2, 1, 3, 2, 3};
Console.WriteLine(countDistictSubarray(arr, arr.Length));
}
}
// This code is contributed by PrinciRaj1992
Javascript
输出:
5
时间复杂度: O(n)
辅助空间: O(n)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。