Open In App

Minimum length of the reduced Array formed using given operations

Last Updated : 10 Jan, 2023
Comments
Improve
Suggest changes
Like Article
Like
Report

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)
Auxiliary Space: O(N2), where N is the size of the given array.


Next Article

Similar Reads