# Find minimum number of merge operations to make an array palindrome

Last Updated : 04 Dec, 2023

Given an array of positive integers. We need to make the given array a ‘Palindrome’. The only allowed operation is”merging” (of two adjacent elements). Merging two adjacent elements means replacing them with their sum. The task is to find the minimum number of merge operations required to make the given array a ‘Palindrome’.

To make any array a palindrome, we can simply apply merge operation n-1 times where n is the size of the array (because a single-element array is always palindromic, similar to single-character string). In that case, the size of array will be reduced to 1. But in this problem, we are asked to do it in the minimum number of operations.

Example :

`Input : arr[] = {15, 4, 15}Output : 0Array is already a palindrome. So wedo not need any merge operation.Input : arr[] = {1, 4, 5, 1}Output : 1We can make given array palindrome withminimum one merging (merging 4 and 5 tomake 9)Input : arr[] = {11, 14, 15, 99}Output : 3We need to merge all elements to makea palindrome.`

The expected time complexity is O(n).

Let f(i, j) be minimum merging operations to make subarray arr[i..j] a palindrome. If i == j answer is 0. We start i from 0 and j from n-1.

1. If arr[i] == arr[j], then there is no need to do any merging operations at index i or index j. Our answer in this case will be f(i+1, j-1).
2. Else, we need to do merging operations. Following cases arise.
• If arr[i] > arr[j], then we should do merging operation at index j. We merge index j-1 and j, and update arr[j-1] = arr[j-1] + arr[j]. Our answer in this case will be 1 + f(i, j-1).
• For the case when arr[i] < arr[j], update arr[i+1] = arr[i+1] + arr[i]. Our answer in this case will be 1 + f(i+1, j).
3. Our answer will be f(0, n-1), where n is the size of array arr[].

Therefore this problem can be solved iteratively using two pointers (first pointer pointing to start of the array and second pointer pointing to the last element of the array) method and keeping count of total merging operations done till now.

Below is an implementation of the above idea.

## C++

 `// C++ program to find number of operations` `// to make an array palindrome` `#include ` `using` `namespace` `std;`   `// Returns minimum number of count operations` `// required to make arr[] palindrome` `int` `findMinOps(``int` `arr[], ``int` `n)` `{` `    ``int` `ans = 0; ``// Initialize result`   `    ``// Start from two corners` `    ``for` `(``int` `i=0,j=n-1; i<=j;)` `    ``{` `        ``// If corner elements are same,` `        ``// problem reduces arr[i+1..j-1]` `        ``if` `(arr[i] == arr[j])` `        ``{` `            ``i++;` `            ``j--;` `        ``}`   `        ``// If left element is greater, then` `        ``// we merge right two elements` `        ``else` `if` `(arr[i] > arr[j])` `        ``{` `            ``// need to merge from tail.` `            ``j--;` `            ``arr[j] += arr[j+1] ;` `            ``ans++;` `        ``}`   `        ``// Else we merge left two elements` `        ``else` `        ``{` `            ``i++;` `            ``arr[i] += arr[i-1];` `            ``ans++;` `        ``}` `    ``}`   `    ``return` `ans;` `}`   `// Driver program to test above` `int` `main()` `{` `    ``int` `arr[] = {1, 4, 5, 9, 1};` `    ``int` `n = ``sizeof``(arr)/``sizeof``(arr[0]);` `    ``cout << ``"Count of minimum operations is "` `         ``<<  findMinOps(arr, n) << endl;` `    ``return` `0;` `}`

## Java

 `// Java program to find number of operations` `// to make an array palindrome`   `class` `GFG` `{` `    ``// Returns minimum number of count operations` `    ``// required to make arr[] palindrome` `    ``static` `int` `findMinOps(``int``[] arr, ``int` `n)` `    ``{` `        ``int` `ans = ``0``; ``// Initialize result`   `        ``// Start from two corners` `        ``for` `(``int` `i=``0``,j=n-``1``; i<=j;)` `        ``{` `            ``// If corner elements are same,` `            ``// problem reduces arr[i+1..j-1]` `            ``if` `(arr[i] == arr[j])` `            ``{` `                ``i++;` `                ``j--;` `            ``}`   `            ``// If left element is greater, then` `            ``// we merge right two elements` `            ``else` `if` `(arr[i] > arr[j])` `            ``{` `                ``// need to merge from tail.` `                ``j--;` `                ``arr[j] += arr[j+``1``] ;` `                ``ans++;` `            ``}`   `            ``// Else we merge left two elements` `            ``else` `            ``{` `                ``i++;` `                ``arr[i] += arr[i-``1``];` `                ``ans++;` `            ``}` `        ``}`   `        ``return` `ans;` `    ``}`   `    ``// Driver method to test the above function` `    ``public` `static` `void` `main(String[] args)` `    ``{` `        ``int` `arr[] = ``new` `int``[]{``1``, ``4``, ``5``, ``9``, ``1``} ;` `        ``System.out.println(``"Count of minimum operations is "``+` `                                ``findMinOps(arr, arr.length));` `    `  `    ``}` `}`

## Python3

 `# Python program to find number of operations` `# to make an array palindrome`   `# Returns minimum number of count operations` `# required to make arr[] palindrome` `def` `findMinOps(arr, n):` `    ``ans ``=` `0` `# Initialize result`   `    ``# Start from two corners` `    ``i,j ``=` `0``,n``-``1` `    ``while` `i<``=``j:` `        ``# If corner elements are same,` `        ``# problem reduces arr[i+1..j-1]` `        ``if` `arr[i] ``=``=` `arr[j]:` `            ``i ``+``=` `1` `            ``j ``-``=` `1`   `        ``# If left element is greater, then` `        ``# we merge right two elements` `        ``elif` `arr[i] > arr[j]:` `            ``# need to merge from tail.` `            ``j ``-``=` `1` `            ``arr[j] ``+``=` `arr[j``+``1``] ` `            ``ans ``+``=` `1`   `        ``# Else we merge left two elements` `        ``else``:` `            ``i ``+``=` `1` `            ``arr[i] ``+``=` `arr[i``-``1``]` `            ``ans ``+``=` `1`   `    ``return` `ans`     `# Driver program to test above` `arr ``=` `[``1``, ``4``, ``5``, ``9``, ``1``]` `n ``=` `len``(arr)` `print``(``"Count of minimum operations is "` `+` `str``(findMinOps(arr, n)))`   `# This code is contributed by Pratik Chhajer`

## C#

 `// C# program to find number of operations` `// to make an array palindrome` `using` `System;`   `class` `GFG` `{` `    ``// Returns minimum number of count operations` `    ``// required to make arr[] palindrome` `    ``static` `int` `findMinOps(``int` `[]arr, ``int` `n)` `    ``{` `        ``int` `ans = 0; ``// Initialize result`   `        ``// Start from two corners` `        ``for` `(``int` `i = 0, j = n - 1; i <= j;)` `        ``{` `            ``// If corner elements are same,` `            ``// problem reduces arr[i+1..j-1]` `            ``if` `(arr[i] == arr[j])` `            ``{` `                ``i++;` `                ``j--;` `            ``}`   `            ``// If left element is greater, then` `            ``// we merge right two elements` `            ``else` `if` `(arr[i] > arr[j])` `            ``{` `                ``// need to merge from tail.` `                ``j--;` `                ``arr[j] += arr[j + 1] ;` `                ``ans++;` `            ``}`   `            ``// Else we merge left two elements` `            ``else` `            ``{` `                ``i++;` `                ``arr[i] += arr[i-1];` `                ``ans++;` `            ``}` `        ``}`   `        ``return` `ans;` `    ``}`   `    ``// Driver Code` `    ``public` `static` `void` `Main()` `    ``{` `        ``int` `[]arr = ``new` `int``[]{1, 4, 5, 9, 1} ;` `        ``Console.Write(``"Count of minimum operations is "` `+` `                            ``findMinOps(arr, arr.Length));` `    `  `    ``}` `}`   `// This code is contributed by nitin mittal`

## Javascript

 ``

## PHP

 ` ``\$arr``[``\$j``])` `        ``{` `            ``// need to merge from tail.` `            ``\$j``--;` `            ``\$arr``[``\$j``] += ``\$arr``[``\$j` `+ 1] ;` `            ``\$ans``++;` `        ``}`   `        ``// Else we merge ` `        ``// left two elements` `        ``else` `        ``{` `            ``\$i``++;` `            ``\$arr``[``\$i``] += ``\$arr``[``\$i` `- 1];` `            ``\$ans``++;` `        ``}` `    ``}`   `    ``return` `\$ans``;` `}`   `// Driver Code` `\$arr``[] = ``array``(1, 4, 5, 9, 1);` `\$n` `= sizeof(``\$arr``);` `echo` `"Count of minimum operations is "``, ` `                 ``findMinOps(``\$arr``, ``\$n``) ;`   `// This code is contributed by nitin mittal.` `?>`

Output

```Count of minimum operations is 1

```

Time Complexity: O(n)
Auxiliary Space: O(1)

#### Approach#2: Using dynamic programming

Create a 2D array dp of size n x n where n is the length of the input array arr. Initialize all elements of dp to 0. For each gap value from 1 to n – 1, loop over all i values from 0 to n – gap – 1. Compute the corresponding j value as i + gap. If arr[i] is equal to arr[j], then set dp[i][j] to dp[i + 1][j – 1].Otherwise, set dp[i][j] to min(dp[i][j – 1], dp[i + 1][j]) + 1. The minimum number of merge operations required to make arr a palindrome is dp[0][n – 1].

#### Algorithm

1. Initialize count variable to 0.
2. Initialize two pointers i and j to the start and end of the array respectively.
3. While i is less than j,
a. If arr[i] is equal to arr[j], increment i and decrement j.
b. Else, if arr[i] is less than arr[j], increment i by 1 and add arr[i-1] to arr[i]. Increment count by 1.
c. Else, decrement j by 1 and add arr[j+1] to arr[j]. Increment count by 1.
4. Return count.

## C++

 `#include ` `#include ` `using` `namespace` `std;`   `int` `minMergeOperations(vector<``int``> arr)` `{` `    ``int` `n = arr.size();` `    ``vector > dp(n, vector<``int``>(n, 0));`   `    ``// Fill the dp table` `    ``for` `(``int` `gap = 1; gap < n; gap++) {` `        ``for` `(``int` `i = 0; i < n - gap; i++) {` `            ``int` `j = i + gap;` `            ``if` `(arr[i] == arr[j]) {` `                ``dp[i][j] = dp[i + 1][j - 1];` `            ``}` `            ``else` `{` `                ``dp[i][j]` `                    ``= min(dp[i][j - 1], dp[i + 1][j]) + 1;` `            ``}` `        ``}` `    ``}`   `    ``return` `dp[0][n - 1];` `}`   `int` `main()` `{` `    ``vector<``int``> arr = { 11, 14, 15, 99 };` `    ``cout << minMergeOperations(arr) << endl;` `    ``return` `0;` `}`

## Java

 `import` `java.util.Arrays;` `import` `java.util.Vector;`   `public` `class` `MinMergeOperations {`   `    ``// Function to calculate the minimum number of merge operations` `    ``// to make the array palindrome` `    ``static` `int` `minMergeOperations(Vector arr) {` `        ``int` `n = arr.size();` `        ``// Create a 2D array for dynamic programming` `        ``int``[][] dp = ``new` `int``[n][n];`   `        ``// Fill the dp table` `        ``for` `(``int` `gap = ``1``; gap < n; gap++) {` `            ``for` `(``int` `i = ``0``; i < n - gap; i++) {` `                ``int` `j = i + gap;` `                ``// If the elements at the ends are equal,` `                ``// no additional merge operation is needed` `                ``if` `(arr.get(i).equals(arr.get(j))) {` `                    ``dp[i][j] = dp[i + ``1``][j - ``1``];` `                ``}` `                ``// If the elements are different, choose the minimum` `                ``// of the two adjacent elements and add 1 for the merge` `                ``else` `{` `                    ``dp[i][j] = Math.min(dp[i][j - ``1``], dp[i + ``1``][j]) + ``1``;` `                ``}` `            ``}` `        ``}`   `        ``// The result is stored at the top-right corner of the dp table` `        ``return` `dp[``0``][n - ``1``];` `    ``}`   `    ``public` `static` `void` `main(String[] args) {` `        ``// Example array` `        ``Vector arr = ``new` `Vector<>(Arrays.asList(``11``, ``14``, ``15``, ``99``));`   `        ``// Print the minimum merge operations needed` `        ``System.out.println(minMergeOperations(arr));` `    ``}` `}`   `// This code is contributed by shivamgupta0987654321`

## Python3

 `def` `min_merge_operations(arr):` `    ``n ``=` `len``(arr)` `    ``dp ``=` `[[``0` `for` `j ``in` `range``(n)] ``for` `i ``in` `range``(n)]` `    `  `    ``for` `gap ``in` `range``(``1``, n):` `        ``for` `i ``in` `range``(n ``-` `gap):` `            ``j ``=` `i ``+` `gap` `            ``if` `arr[i] ``=``=` `arr[j]:` `                ``dp[i][j] ``=` `dp[i ``+` `1``][j ``-` `1``]` `            ``else``:` `                ``dp[i][j] ``=` `min``(dp[i][j ``-` `1``], dp[i ``+` `1``][j]) ``+` `1` `                `  `    ``return` `dp[``0``][n ``-` `1``]`   `arr ``=` `[``11``, ``14``, ``15``, ``99``]` `print``(min_merge_operations(arr))`

## C#

 `using` `System;` `using` `System.Collections.Generic;`   `class` `Program {` `    ``// Function to find the minimum merge operations` `    ``static` `int` `MinMergeOperations(List<``int``> arr)` `    ``{` `        ``int` `n = arr.Count;` `        ``int``[][] dp = ``new` `int``[n][];`   `        ``for` `(``int` `i = 0; i < n; i++) {` `            ``dp[i] = ``new` `int``[n];` `        ``}`   `        ``// Fill the dp table using dynamic programming` `        ``for` `(``int` `gap = 1; gap < n; gap++) {` `            ``for` `(``int` `i = 0; i < n - gap; i++) {` `                ``int` `j = i + gap;`   `                ``// If the elements at the ends are equal, no` `                ``// merge is needed.` `                ``if` `(arr[i] == arr[j]) {` `                    ``dp[i][j] = dp[i + 1][j - 1];` `                ``}` `                ``else` `{` `                    ``// If the elements at the ends are` `                    ``// different, we take the minimum of` `                    ``// merging from the left and merging` `                    ``// from the right, and add 1.` `                    ``dp[i][j] = Math.Min(dp[i][j - 1],` `                                        ``dp[i + 1][j])` `                               ``+ 1;` `                ``}` `            ``}` `        ``}`   `        ``// The result is stored at the top-right corner of` `        ``// the dp table.` `        ``return` `dp[0][n - 1];` `    ``}`   `    ``static` `void` `Main()` `    ``{` `        ``List<``int``> arr = ``new` `List<``int``>{ 11, 14, 15, 99 };` `        ``int` `minMergeOps = MinMergeOperations(arr);` `        ``Console.WriteLine(``"Minimum merge operations: "` `                          ``+ minMergeOps);` `    ``}` `}`

## Javascript

 `function` `min_merge_operations(arr) {` `    ``let n = arr.length;` `    ``let dp = Array.from(Array(n), () => Array(n).fill(0));` `    `  `    ``for` `(let gap = 1; gap < n; gap++) {` `        ``for` `(let i = 0; i < n - gap; i++) {` `            ``let j = i + gap;` `            ``if` `(arr[i] == arr[j]) {` `                ``dp[i][j] = dp[i + 1][j - 1];` `            ``} ``else` `{` `                ``dp[i][j] = Math.min(dp[i][j - 1], dp[i + 1][j]) + 1;` `            ``}` `        ``}` `    ``}` `                `  `    ``return` `dp[0][n - 1];` `}`   `let arr = [11, 14, 15, 99];` `console.log(min_merge_operations(arr));`

Output

```3

```

Time Complexity: O(n), where n is length of array
Auxiliary Space: O(1)

Previous
Next