给定一个由N 个元素组成的数组arr[] ,任务是找到最小子数组的长度,该子数组的子序列为{0, 1, 2, 3, 4} 。
例子:
Input: arr[] = {0, 1, 2, 3, 4, 2, 0, 3, 4}
Output: 5
The required Subarray is {0, 1, 2, 3, 4} with minimum length.
The entire array also includes the sequence
but it is not minimum in length.
Input: arr[] = {0, 1, 1, 0, 1, 2, 0, 3, 4}
Output: 6
方法:
- 维护一个大小为5 (等于序列的大小)的数组pref[] ,其中pref[i]存储给定数组中i的计数,直到现在。
- 只有当pref[Array[i] – 1] > 0 时,我们才可以增加任何数字的 pref 计数。这是因为,为了将完整序列作为数组的子序列,所有前面的元素序列必须发生在电流之前。此外,存储到目前为止找到的这些元素的索引。
- 每当我们看到4 时,即子序列的可能结尾和pref[3] > 0意味着我们已经在数组中找到了该序列。现在将该索引标记为结束点和起点,以及从3到0 的所有其他数字。应用二分搜索来找到最接近序列下一个元素的索引,这将为我们提供当前有效子数组的大小。
- 答案是在上一步中找到的所有有效子数组的最小大小。
下面是上述方法的实现:
C++
// C++ implementation of the approach
#include
using namespace std;
#define MAX_INT 1000000
// Function to return the minimum length
// of a sub-array which contains
// {0, 1, 2, 3, 4} as a sub-sequence
int solve(int Array[], int N)
{
// To store the indices where 0, 1, 2,
// 3 and 4 are present
vector pos[5];
// To store if there exist a valid prefix
// of sequence in array
int pref[5] = { 0 };
// Base Case
if (Array[0] == 0) {
pref[0] = 1;
pos[0].push_back(0);
}
int ans = MAX_INT;
for (int i = 1; i < N; i++) {
// If current element is 0
if (Array[i] == 0) {
// Update the count of 0s till now
pref[0]++;
// Push the index of the new 0
pos[0].push_back(i);
}
else {
// To check if previous element of the
// given sequence is found till now
if (pref[Array[i] - 1] > 0) {
pref[Array[i]]++;
pos[Array[i]].push_back(i);
// If it is the end of sequence
if (Array[i] == 4) {
int end = i;
int start = i;
// Iterate for other elements of the sequence
for (int j = 3; j >= 0; j--) {
int s = 0;
int e = pos[j].size() - 1;
int temp = -1;
// Binary Search to find closest occurrence
// less than equal to starting point
while (s <= e) {
int m = (s + e) / 2;
if (pos[j][m] <= start) {
temp = pos[j][m];
s = m + 1;
}
else {
e = m - 1;
}
}
// Update the starting point
start = temp;
}
ans = min(ans, end - start + 1);
}
}
}
}
return ans;
}
// Driver code
int main()
{
int Array[] = { 0, 1, 2, 3, 4, 2, 0, 3, 4 };
int N = sizeof(Array) / sizeof(Array[0]);
cout << solve(Array, N);
return 0;
}
Java
// Java implementation of the approach
class GFG
{
static int MAX_INT = 1000000;
// Function to return the minimum length
// of a sub-array which contains
// {0, 1, 2, 3, 4} as a sub-sequence
static int solve(int[] array, int N)
{
// To store the indices where 0, 1, 2,
// 3 and 4 are present
int[][] pos = new int[5][10000];
// To store if there exist a valid prefix
// of sequence in array
int[] pref = new int[5];
// Base Case
if (array[0] == 0)
{
pref[0] = 1;
pos[0][pos[0].length - 1] = 0;
}
int ans = MAX_INT;
for (int i = 1; i < N; i++)
{
// If current element is 0
if (array[i] == 0)
{
// Update the count of 0s till now
pref[0]++;
// Push the index of the new 0
pos[0][pos[0].length - 1] = i;
}
else
{
// To check if previous element of the
// given sequence is found till now
if (pref[array[i] - 1] > 0)
{
pref[array[i]]++;
pos[array[i]][pos[array[i]].length - 1] = i;
// If it is the end of sequence
if (array[i] == 4)
{
int end = i;
int start = i;
// Iterate for other elements of the sequence
for (int j = 3; j >= 0; j--)
{
int s = 0;
int e = pos[j].length - 1;
int temp = -1;
// Binary Search to find closest occurrence
// less than equal to starting point
while (s <= e)
{
int m = (s + e) / 2;
if (pos[j][m] <= start)
{
temp = pos[j][m];
s = m + 1;
}
else
e = m - 1;
}
// Update the starting point
start = temp;
}
ans = Math.min(ans, end - start + 1);
}
}
}
}
return ans;
}
// Driver Code
public static void main(String[] args)
{
int[] array = { 0, 1, 2, 3, 4, 2, 0, 3, 4 };
int N = array.length;
System.out.println(solve(array, N));
}
}
// This code is contributed by
// sanjeev2552
Python3
# Python3 implementation of the approach
MAX_INT=1000000
# Function to return the minimum length
# of a sub-array which contains
# 0, 1, 2, 3, 4 as a sub-sequence
def solve(Array, N):
# To store the indices where 0, 1, 2,
# 3 and 4 are present
pos=[[] for i in range(5)]
# To store if there exist a valid prefix
# of sequence in array
pref=[0 for i in range(5)]
# Base Case
if (Array[0] == 0):
pref[0] = 1
pos[0].append(0)
ans = MAX_INT
for i in range(N):
# If current element is 0
if (Array[i] == 0):
# Update the count of 0s till now
pref[0]+=1
# Push the index of the new 0
pos[0].append(i)
else :
# To check if previous element of the
# given sequence is found till now
if (pref[Array[i] - 1] > 0):
pref[Array[i]]+=1
pos[Array[i]].append(i)
# If it is the end of sequence
if (Array[i] == 4) :
end = i
start = i
# Iterate for other elements of the sequence
for j in range(3,-1,-1):
s = 0
e = len(pos[j]) - 1
temp = -1
# Binary Search to find closest occurrence
# less than equal to starting point
while (s <= e):
m = (s + e) // 2
if (pos[j][m] <= start) :
temp = pos[j][m]
s = m + 1
else :
e = m - 1
# Update the starting point
start = temp
ans = min(ans, end - start + 1)
return ans
# Driver code
Array = [ 0, 1, 2, 3, 4, 2, 0, 3, 4]
N = len(Array)
print(solve(Array, N))
# This code is contributed by mohit kumar 29
C#
// C# implementation of the approach
using System;
class GFG
{
static int MAX_INT = 1000000;
// Function to return the minimum length
// of a sub-array which contains
// {0, 1, 2, 3, 4} as a sub-sequence
static int solve(int[] array, int N)
{
// To store the indices where 0, 1, 2,
// 3 and 4 are present
int[,] pos = new int[5,10000];
// To store if there exist a valid prefix
// of sequence in array
int[] pref = new int[5];
// Base Case
if (array[0] == 0)
{
pref[0] = 1;
pos[0,pos.GetLength(0)- 1] = 0;
}
int ans = MAX_INT;
for (int i = 1; i < N; i++)
{
// If current element is 0
if (array[i] == 0)
{
// Update the count of 0s till now
pref[0]++;
// Push the index of the new 0
pos[0,pos.GetLength(0) - 1] = i;
}
else
{
// To check if previous element of the
// given sequence is found till now
if (pref[array[i] - 1] > 0)
{
pref[array[i]]++;
pos[array[i],pos.GetLength(1) - 1] = i;
// If it is the end of sequence
if (array[i] == 4)
{
int end = i;
int start = i;
// Iterate for other elements of the sequence
for (int j = 3; j >= 0; j--)
{
int s = 0;
int e = pos.GetLength(1) - 1;
int temp = -1;
// Binary Search to find closest occurrence
// less than equal to starting point
while (s <= e)
{
int m = (s + e) / 2;
if (pos[j,m] <= start)
{
temp = pos[j,m];
s = m + 1;
}
else
e = m - 1;
}
// Update the starting point
start = temp;
}
ans = Math.Min(ans, end - start + 1);
}
}
}
}
return ans;
}
// Driver Code
public static void Main(String[] args)
{
int[] array = { 0, 1, 2, 3, 4, 2, 0, 3, 4 };
int N = array.Length;
Console.WriteLine(solve(array, N));
}
}
// This code is contributed by PrinciRaj1992
Javascript
输出:
5
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。