给定长度为N的数组arr ,任务是通过执行以下操作来最小化其长度:
- 删除所有相邻的相等对(即,如果arr [i] = arr [i + 1] ),然后将其替换为arr [i] + 1的单个实例。
- 每个操作将数组的长度减1。
- 重复该操作,直到无法再进行减少。
例子:
Input: arr = {3, 3, 4, 4, 4, 3, 3}
Output: 2
Explanation:
Merge the first two 3s and replace them by 4. Updated array: {4, 4, 4, 4, 3, 3}
Merge the first two 4s and replace them by 5. Updated array: {5, 4, 4, 3, 3}
Merge the two 4s and replace them by 5. Updated array: {5, 5, 3, 3}
Merge the two 5s and replace them by 6. Updated array: {6, 3, 3}
Merge the two 3s and replace them by 4. Updated array: {6, 4}
Hence, the minimum length of the reduced array = 2
Input: arr = {4, 3, 2, 2, 3}
Output: 2
Explanation:
Merge the two 2s and replace them by 3. Updated array: {4, 3, 3, 3}
Merge the first two 3s and replace them by 4. Updated array: {4, 4, 3}
Merge the two 4s and replace them by 5. Updated array: {5, 3}
Hence, the minimum length of the reduced array = 2
方法:上述问题可以使用动态编程解决。可以看出,最终数组中的每个元素都是相应段上多个元素替换的结果。因此,我们的目标是在段上找到数组的最小分区,其中每个段可以通过一系列操作转换为单个元素。
让我们定义以下动态编程表状态:
dp[i][j] = value of the single remaining element
when the subarray from index i to j is reduced by a series of operations or is equal to -1 when the subarray can’t be reduced to a single element.
为了计算dp [i] [j]:
- 如果i = j,则dp [i] [j] = a [i]
- 从[i,j-1]进行迭代,令遍历索引为k(i <= k
dp [i] [k] = dp [k + 1] [j] ,这意味着子数组[i,j]可以分为两部分,并且这两部分具有相同的最终值,因此这两部分可以组合,即dp [i] [j] = dp [i] [k] + 1 。
为了计算最小分区,我们将创建另一个dp表,其中存储了最终结果。该表具有以下状态:
dp1[i] = minimum partition of subarray [1: i]
which is the minimal size of array till i after above operations are performed.
下面是上述方法的实现:
CPP
// C++ implementation to find the
// minimum length of the array
#include
using namespace std;
// Function to find the
// length of minimized array
int minimalLength(int a[], int n)
{
// Creating the required dp tables
int dp[n + 1][n + 1], dp1[n];
int i, j, k;
// Initialising the dp table by -1
memset(dp, -1, sizeof(dp));
for (int size = 1; size <= n; size++) {
for (i = 0; i < n - size + 1; i++) {
j = i + size - 1;
// base case
if (i == j)
dp[i][j] = a[i];
else {
for (k = i; k < j; k++) {
// Check if the two subarray
// can be combined
if (dp[i][k] != -1
&& dp[i][k] == dp[k + 1][j])
dp[i][j] = dp[i][k] + 1;
}
}
}
}
// Intialising dp1 table with max value
for (i = 0; i < n; i++)
dp1[i] = 1e7;
for (i = 0; i < n; i++) {
for (j = 0; j <= i; j++) {
// Check if the subarray can be
// reduced to a single element
if (dp[j][i] != -1) {
if (j == 0)
dp1[i] = 1;
// Minimal partition
// of [1: j-1] + 1
else
dp1[i] = min(
dp1[i],
dp1[j - 1] + 1);
}
}
}
return dp1[n - 1];
}
// Driver code
int main()
{
int n = 7;
int a[n] = { 3, 3, 4, 4, 4, 3, 3 };
cout << minimalLength(a, n);
return 0;
}
Java
// Java implementation to find the
// minimum length of the array
import java.util.*;
class GFG{
// Function to find the
// length of minimized array
static int minimalLength(int a[], int n)
{
// Creating the required dp tables
int [][]dp = new int[n + 1][n + 1];
int []dp1 = new int[n];
int i, j, k;
// Initialising the dp table by -1
for (i = 0; i < n + 1; i++) {
for (j = 0; j < n + 1; j++) {
dp[i][j] = -1;
}
}
for (int size = 1; size <= n; size++) {
for (i = 0; i < n - size + 1; i++) {
j = i + size - 1;
// base case
if (i == j)
dp[i][j] = a[i];
else {
for (k = i; k < j; k++) {
// Check if the two subarray
// can be combined
if (dp[i][k] != -1
&& dp[i][k] == dp[k + 1][j])
dp[i][j] = dp[i][k] + 1;
}
}
}
}
// Intialising dp1 table with max value
for (i = 0; i < n; i++)
dp1[i] = (int) 1e7;
for (i = 0; i < n; i++) {
for (j = 0; j <= i; j++) {
// Check if the subarray can be
// reduced to a single element
if (dp[j][i] != -1) {
if (j == 0)
dp1[i] = 1;
// Minimal partition
// of [1: j-1] + 1
else
dp1[i] = Math.min(
dp1[i],
dp1[j - 1] + 1);
}
}
}
return dp1[n - 1];
}
// Driver code
public static void main(String[] args)
{
int n = 7;
int a[] = { 3, 3, 4, 4, 4, 3, 3 };
System.out.print(minimalLength(a, n));
}
}
// This code contributed by Princi Singh
Python3
# Python3 implementation to find the
# minimum length of the array
import numpy as np
# Function to find the
# length of minimized array
def minimalLength(a, n) :
# Creating the required dp tables
# Initialising the dp table by -1
dp = np.ones((n + 1,n + 1)) * -1;
dp1 = [0]*n;
for size in range(1, n + 1) :
for i in range( n - size + 1) :
j = i + size - 1;
# base case
if (i == j) :
dp[i][j] = a[i];
else :
for k in range(i,j) :
# Check if the two subarray
# can be combined
if (dp[i][k] != -1 and dp[i][k] == dp[k + 1][j]) :
dp[i][j] = dp[i][k] + 1;
# Intialising dp1 table with max value
for i in range(n) :
dp1[i] = int(1e7);
for i in range(n) :
for j in range(i + 1) :
# Check if the subarray can be
# reduced to a single element
if (dp[j][i] != -1) :
if (j == 0) :
dp1[i] = 1;
# Minimal partition
# of [1: j-1] + 1
else :
dp1[i] = min(
dp1[i],
dp1[j - 1] + 1);
return dp1[n - 1];
# Driver code
if __name__ == "__main__" :
n = 7;
a = [ 3, 3, 4, 4, 4, 3, 3 ];
print(minimalLength(a, n));
# This code is contributed by Yash_R
C#
// C# implementation to find the
// minimum length of the array
using System;
class GFG{
// Function to find the
// length of minimized array
static int minimalLength(int []a, int n)
{
// Creating the required dp tables
int [,]dp = new int[n + 1, n + 1];
int []dp1 = new int[n];
int i, j, k;
// Initialising the dp table by -1
for (i = 0; i < n + 1; i++) {
for (j = 0; j < n + 1; j++) {
dp[i, j] = -1;
}
}
for (int size = 1; size <= n; size++) {
for (i = 0; i < n - size + 1; i++) {
j = i + size - 1;
// base case
if (i == j)
dp[i, j] = a[i];
else {
for (k = i; k < j; k++) {
// Check if the two subarray
// can be combined
if (dp[i, k] != -1
&& dp[i, k] == dp[k + 1, j])
dp[i, j] = dp[i, k] + 1;
}
}
}
}
// Intialising dp1 table with max value
for (i = 0; i < n; i++)
dp1[i] = (int) 1e7;
for (i = 0; i < n; i++) {
for (j = 0; j <= i; j++) {
// Check if the subarray can be
// reduced to a single element
if (dp[j, i] != -1) {
if (j == 0)
dp1[i] = 1;
// Minimal partition
// of [1: j-1] + 1
else
dp1[i] = Math.Min(
dp1[i],
dp1[j - 1] + 1);
}
}
}
return dp1[n - 1];
}
// Driver code
public static void Main(string[] args)
{
int n = 7;
int []a = { 3, 3, 4, 4, 4, 3, 3 };
Console.Write(minimalLength(a, n));
}
}
// This code is contributed by Yash_R
Javascript
2
时间复杂度: O(N 3 )