最小化要删除的数组元素的数量,使得至少 K 个元素等于它们的索引值
给定一个由N个整数和一个正整数K组成的数组arr[] (基于 1 的索引) ,任务是找到必须删除的最小数组元素数,以使至少 K个数组元素等于它们的索引值.如果无法这样做,则打印-1 。
例子:
Input: arr[] = {5, 1, 3, 2, 3} K = 2
Output: 2
Explanation:
Following are the removal operations required:
- Removing arr[1] modifies array to {1, 3, 2, 3} -> 1 element is equal to its index value.
- Removing arr[3] modifies array to {1, 2, 3} -> 3 elements are equal to their index value.
After the above operations 3(>= K) elements are equal to their index values and the minimum removals required is 2.
Input: arr[] = {2, 3, 4} K = 1
Output: -1
方法:上述问题可以借助动态规划来解决。请按照以下步骤解决给定的问题。
- 初始化一个二维dp表,使得dp[i][j]将表示当总共有 j 个元素时,其值等于它们的索引的最大元素。
- dp表中的所有值最初都用0s填充。
- 对[0, N-1 ] 范围内的每个i和[0, i]范围内的j进行迭代,有两种选择。
- 删除当前元素, dp 表可以更新为dp[i+1][j] = max(dp[i+1][j], dp[i][j]) 。
- 保留当前元素,则dp表可以更新为: dp[i+1][j+1] = max(dp[i+1][j+1], dp[i][j] + (arr[ i+1] == j+1)) 。
- 现在对于[N, 0]范围内的每个j检查dp[N][j] 的值是否大于或等于 K 。如果找到,则取最小值并返回答案。
- 否则,最后返回-1 。这意味着找不到可能的答案。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to minimize the removals of
// array elements such that atleast K
// elements are equal to their indices
int MinimumRemovals(int a[], int N, int K)
{
// Store the array as 1-based indexing
// Copy of first array
int b[N + 1];
for (int i = 0; i < N; i++) {
b[i + 1] = a[i];
}
// Make a dp-table of (N*N) size
int dp[N + 1][N + 1];
// Fill the dp-table with zeroes
memset(dp, 0, sizeof(dp));
for (int i = 0; i < N; i++) {
for (int j = 0; j <= i; j++) {
// Delete the current element
dp[i + 1][j] = max(
dp[i + 1][j], dp[i][j]);
// Take the current element
dp[i + 1][j + 1] = max(
dp[i + 1][j + 1],
dp[i][j] + ((b[i + 1] == j + 1) ? 1 : 0));
}
}
// Check for the minimum removals
for (int j = N; j >= 0; j--) {
if (dp[N][j] >= K) {
return (N - j);
}
}
return -1;
}
// Driver Code
int main()
{
int arr[] = { 5, 1, 3, 2, 3 };
int K = 2;
int N = sizeof(arr) / sizeof(arr[0]);
cout << MinimumRemovals(arr, N, K);
return 0;
}
Java
// Java program for the above approach
import java.io.*;
class GFG {
// Function to minimize the removals of
// array elements such that atleast K
// elements are equal to their indices
static int MinimumRemovals(int a[], int N, int K)
{
// Store the array as 1-based indexing
// Copy of first array
int b[] = new int[N + 1];
for (int i = 0; i < N; i++) {
b[i + 1] = a[i];
}
// Make a dp-table of (N*N) size
int dp[][] = new int[N + 1][N + 1];
for (int i = 0; i < N; i++) {
for (int j = 0; j <= i; j++) {
// Delete the current element
dp[i + 1][j] = Math.max(dp[i + 1][j], dp[i][j]);
// Take the current element
dp[i + 1][j + 1] = Math.max(
dp[i + 1][j + 1],
dp[i][j]
+ ((b[i + 1] == j + 1) ? 1 : 0));
}
}
// Check for the minimum removals
for (int j = N; j >= 0; j--) {
if (dp[N][j] >= K) {
return (N - j);
}
}
return -1;
}
// Driver Code
public static void main(String[] args)
{
int arr[] = { 5, 1, 3, 2, 3 };
int K = 2;
int N = arr.length;
System.out.println(MinimumRemovals(arr, N, K));
}
}
// This code is contributed by Dharanendra L V.
Python3
# Python 3 program for the above approach
# Function to minimize the removals of
# array elements such that atleast K
# elements are equal to their indices
def MinimumRemovals(a, N, K):
# Store the array as 1-based indexing
# Copy of first array
b = [0 for i in range(N + 1)]
for i in range(N):
b[i + 1] = a[i]
# Make a dp-table of (N*N) size
dp = [[0 for i in range(N+1)] for j in range(N+1)]
for i in range(N):
for j in range(i + 1):
# Delete the current element
dp[i + 1][j] = max(dp[i + 1][j], dp[i][j])
# Take the current element
dp[i + 1][j + 1] = max(dp[i + 1][j + 1],dp[i][j] + (1 if (b[i + 1] == j + 1) else 0))
# Check for the minimum removals
j = N
while(j >= 0):
if(dp[N][j] >= K):
return (N - j)
j -= 1
return -1
# Driver Code
if __name__ == '__main__':
arr = [5, 1, 3, 2, 3]
K = 2
N = len(arr)
print(MinimumRemovals(arr, N, K))
# This code is contributed by SURENDRA_GANGWAR.
C#
// C# code for the above approach
using System;
public class GFG
{
// Function to minimize the removals of
// array elements such that atleast K
// elements are equal to their indices
static int MinimumRemovals(int[] a, int N, int K)
{
// Store the array as 1-based indexing
// Copy of first array
int[] b = new int[N + 1];
for (int i = 0; i < N; i++) {
b[i + 1] = a[i];
}
// Make a dp-table of (N*N) size
int[, ] dp = new int[N + 1, N + 1];
for (int i = 0; i < N; i++) {
for (int j = 0; j <= i; j++) {
// Delete the current element
dp[i + 1, j]
= Math.Max(dp[i + 1, j], dp[i, j]);
// Take the current element
dp[i + 1, j + 1] = Math.Max(
dp[i + 1, j + 1],
dp[i, j]
+ ((b[i + 1] == j + 1) ? 1 : 0));
}
}
// Check for the minimum removals
for (int j = N; j >= 0; j--) {
if (dp[N, j] >= K) {
return (N - j);
}
}
return -1;
}
static public void Main()
{
// Code
int[] arr = { 5, 1, 3, 2, 3 };
int K = 2;
int N = arr.Length;
Console.Write(MinimumRemovals(arr, N, K));
}
}
// This code is contributed by Potta Lokesh
Javascript
输出:
2
时间复杂度: O(N 2 )
辅助空间: O(N 2 )