给定一个大小为N的数组arr[]仅由前M 个自然数组成,任务是找到需要替换的子数组的最小长度,使得数组元素的频率为N / M 。
注意: N是M的倍数。
例子:
Input: M = 3, arr[] = {1, 1, 1, 1, 2, 3}
Output: 2
Explanation:
Replace the subarray over the range [2, 3] with the element {2, 3} modifies the array arr[] to {1, 1, 2, 3, 2, 3}. Now, the frequency of each array elements is N / M( = 6 / 3 = 2).
Therefore, the minimum length subarray that needed to be replaced is 2.
Input: M = 6, arr[] = {1, 3, 6, 6, 2, 1, 5, 4, 1, 4, 1, 2, 3, 2, 2, 2, 4, 3}
Output: 4
方法:可以通过使用两个指针方法来解决给定的问题,以找到具有此范围之外的所有数字计数小于或等于N/M的子数组的最小长度。请按照以下步骤解决问题:
- 初始化一个向量,比如大小为M+1 的mapu[]用0来存储每个数组元素的频率。
- 将变量c初始化为0以存储数组中另外存在的元素数。
- 使用变量i迭代范围[0, N]并执行以下任务:
- 将向量mapu[]中arr[i]的值增加1 。
- 如果mapu[arr[i]] 的值等于(N/M) + 1 ,则将c的值增加1 。
- 如果c 的值为0 ,则返回0作为结果。
- 将变量ans初始化为N来存储答案,将L和R两个指针初始化为0和(N – 1)来存储范围的左侧和右侧。
- 在 while 循环中迭代直到R小于N并执行以下任务:
- 如果(mapu[arr[R]] – 1) 的值等于N/M ,则将c的值减去1 。
- 如果c等于0 ,则在 while 循环中迭代直到L小于等于R且c的值等于0并执行以下任务:
- 将ans的值更新为ans或(R – L + 1)的最小值
- 将mapu[arr[L]]的值增加1 ,如果大于N/M ,则将c的值增加1 。
- 将L的值增加1 。
- 将R的值增加1 。
- 完成以上步骤后,打印ans的值作为结果。
下面是上述方法的实现。
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find the minimum length
// of the subarray to be changed.
int minimumSubarray(vector arr,
int n, int m)
{
// Stores the frequencies of array
// elements
vector mapu(m + 1, 0);
// Stores the number of array elements
// that are present more than N/M times
int c = 0;
// Iterate over the range
for (int i = 0; i < n; i++) {
// Increment the frequency
mapu[arr[i]]++;
if (mapu[arr[i]] == (n / m) + 1)
c++;
}
// If the frequency of all array
// elements are already N/M
if (c == 0)
return 0;
// Stores the resultant length of
// the subarray
int ans = n;
// The left and right pointers
int l = 0, r = 0;
// Iterate over the range
while (r < n) {
// If the current element is
if (--mapu[arr[r]] == (n / m))
c--;
// If the value of c is 0, then
// find the possible answer
if (c == 0) {
// Iterate over the range
while (l <= r && c == 0) {
ans = min(ans, r - l + 1);
// If the element at left
// is making it extra
if (++mapu[arr[l]] > (n / m))
c++;
// Update the left pointer
l++;
}
}
// Update the right pointer
r++;
}
// Return the resultant length
return ans;
}
// Driver Code
int main()
{
vector arr = { 1, 1, 2, 1, 1, 2 };
int M = 2;
int N = arr.size();
cout << minimumSubarray(arr, N, M);
return 0;
}
Java
// Java program for the above approach
import java.util.Arrays;
class GFG{
// Function to find the minimum length
// of the subarray to be changed.
public static int minimumSubarray(int[] arr, int n,
int m)
{
// Stores the frequencies of array
// elements
int[] mapu = new int[m + 1];
Arrays.fill(mapu, 0);
// Stores the number of array elements
// that are present more than N/M times
int c = 0;
// Iterate over the range
for(int i = 0; i < n; i++)
{
// Increment the frequency
mapu[arr[i]]++;
if (mapu[arr[i]] == (n / m) + 1)
c++;
}
// If the frequency of all array
// elements are already N/M
if (c == 0)
return 0;
// Stores the resultant length of
// the subarray
int ans = n;
// The left and right pointers
int l = 0, r = 0;
// Iterate over the range
while (r < n)
{
// If the current element is
if (--mapu[arr[r]] == (n / m))
c--;
// If the value of c is 0, then
// find the possible answer
if (c == 0)
{
// Iterate over the range
while (l <= r && c == 0)
{
ans = Math.min(ans, r - l + 1);
// If the element at left
// is making it extra
if (++mapu[arr[l]] > (n / m))
c++;
// Update the left pointer
l++;
}
}
// Update the right pointer
r++;
}
// Return the resultant length
return ans;
}
// Driver Code
public static void main(String args[])
{
int[] arr = { 1, 1, 2, 1, 1, 2 };
int M = 2;
int N = arr.length;
System.out.println(minimumSubarray(arr, N, M));
}
}
// This code is contributed by gfgking
Python3
# Python3 program for the above approach
# Function to find the minimum length
# of the subarray to be changed.
def minimumSubarray(arr, n, m):
# Stores the frequencies of array
# elements
mapu = [0 for i in range(m+1)]
# Stores the number of array elements
# that are present more than N/M times
c = 0
# Iterate over the range
for i in range(n):
# Increment the frequency
mapu[arr[i]] += 1
if (mapu[arr[i]] == (n // m) + 1):
c += 1
# If the frequency of all array
# elements are already N/M
if (c == 0):
return 0
# Stores the resultant length of
# the subarray
ans = n
# The left and right pointers
l = 0
r = 0
# Iterate over the range
while (r < n):
# If the current element is
mapu[arr[r]] -= 1
if (mapu[arr[r]] == (n // m)):
c -= 1
# If the value of c is 0, then
# find the possible answer
if (c == 0):
# Iterate over the range
while (l <= r and c == 0):
ans = min(ans, r - l + 1)
# If the element at left
# is making it extra
mapu[arr[l]] += 1
if (mapu[arr[l]] > (n // m)):
c += 1
# Update the left pointer
l += 1
# Update the right pointer
r += 1
# Return the resultant length
return ans
# Driver Code
if __name__ == '__main__':
arr = [1, 1, 2, 1, 1, 2]
M = 2
N = len(arr)
print(minimumSubarray(arr, N, M))
# This code is contributed by ipg2016107.
C#
// C# program for the above approach
using System;
class GFG{
// Function to find the minimum length
// of the subarray to be changed.
public static int minimumSubarray(int[] arr, int n,
int m)
{
// Stores the frequencies of array
// elements
int[] mapu = new int[m + 1];
Array.Fill(mapu, 0);
// Stores the number of array elements
// that are present more than N/M times
int c = 0;
// Iterate over the range
for(int i = 0; i < n; i++)
{
// Increment the frequency
mapu[arr[i]]++;
if (mapu[arr[i]] == (n / m) + 1)
c++;
}
// If the frequency of all array
// elements are already N/M
if (c == 0)
return 0;
// Stores the resultant length of
// the subarray
int ans = n;
// The left and right pointers
int l = 0, r = 0;
// Iterate over the range
while (r < n)
{
// If the current element is
if (--mapu[arr[r]] == (n / m))
c--;
// If the value of c is 0, then
// find the possible answer
if (c == 0)
{
// Iterate over the range
while (l <= r && c == 0)
{
ans = Math.Min(ans, r - l + 1);
// If the element at left
// is making it extra
if (++mapu[arr[l]] > (n / m))
c++;
// Update the left pointer
l++;
}
}
// Update the right pointer
r++;
}
// Return the resultant length
return ans;
}
// Driver Code
public static void Main(String []args)
{
int[] arr = { 1, 1, 2, 1, 1, 2 };
int M = 2;
int N = arr.Length;
Console.Write(minimumSubarray(arr, N, M));
}
}
// This code is contributed by shivanisinghss2110
Javascript
输出:
1
时间复杂度: O(N)
辅助空间: O(N)