Skip to content
Related Articles

Related Articles

Minimum length of the reduced Array formed using given operations

Improve Article
Save Article
  • Difficulty Level : Expert
  • Last Updated : 16 Jul, 2021
Improve Article
Save Article

Given an array arr of length N, the task is to minimize its length by performing following operations: 
 

  • Remove any adjacent equal pairs, ( i.e. if arr[i] = arr[i+1]) and replace it with single instance of arr[i] + 1.
  • Each operation decrements the length of the array by 1.
  • Repeat the operation till no more reductions can be made.

Examples: 
 

Input: arr = {3, 3, 4, 4, 4, 3, 3} 
Output:
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:
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 
 

 

Approach: The above mentioned problem can be solved using Dynamic Programming. It can be observed that each element in the final array will be the result of the replacement of a number of elements on the corresponding segment. So our goal is to find the minimal partition of the array on segments, where each segment can be converted to a single element by a series of operations.
Let us define the following dynamic programming table state: 
 

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. 
 

For computing dp[i][j]: 
 

  • If i = j, dp[i][j] = a[i]
  • Iterate from [i, j-1], let the traversing index be k (i <= k < j). For any k if dp[i][k] = dp[k+1][j], this means that subarray [i, j] can be divided into two parts and both the parts have same final value, so these two parts can be combined i.e. dp[i][j] = dp[i][k] + 1.

For computing minimum partitions, we will create another dp table in which the final result is stored. This table has the following state: 
 

dp1[i] = minimum partition of subarray [1: i]
which is the minimal size of array till i after above operations are performed. 
 

Below is the implementation of the above approach: 
 

CPP




// C++ implementation to find the
// minimum length of the array
 
#include <bits/stdc++.h>
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;
                }
            }
        }
    }
 
    // Initialising 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;
                }
            }
        }
    }
  
    // Initialising 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;
 
    # Initialising 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;
                    }
                }
            }
        }
     
        // Initialising 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




<script>
 
// Javascript implementation to find the
// minimum length of the array
 
// Function to find the
// length of minimized array
function minimalLength(a, n)
{
 
    // Creating the required dp t0ables
    // Initialising the dp table by -1
    var i, j, k;
    var dp = Array(n+1).fill(Array(n+1).fill(-1));
    var dp1 = Array(n).fill(0);
 
    for (var 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;
                }
            }
        }
    }
 
    // Initialising dp1 table with max value
    for (i = 0; i < n; i++)
        dp1[i] = 1000000000;
 
    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] = 2;
 
                // Minimal partition
                // of [1: j-1] + 1
                else
                    dp1[i] = Math.min(dp1[i], dp1[j - 1] + 1);
            }
        }
    }
    return dp1[n - 1];
}
 
// Driver code
var n = 7;
var a = [ 3, 3, 4, 4, 4, 3, 3 ];
document.write(minimalLength(a, n));
 
// This code is contributed by rrrtnx.
</script>

Output: 

2

 

Time complexity: O(N3)
 


My Personal Notes arrow_drop_up
Related Articles

Start Your Coding Journey Now!