📌  相关文章
📜  查找使阵列回文的最小合并操作数

📅  最后修改于: 2021-04-23 16:29:40             🧑  作者: Mango

给定正整数数组。我们需要将给定的数组设为“回文”。唯一允许的操作是“合并”(两个相邻元素的)。合并两个相邻元素意味着用它们的总和替换它们。任务是找到使给定数组成为“回文”所需的最小合并操作数。
要使任何数组成为回文,我们可以简单地应用n-1次合并操作,其中n是数组的大小(因为单元素数组始终是回文的,类似于单字符字符串)。在这种情况下,数组的大小将减小为1。但是在这个问题上,我们被要求以最少的操作数来进行操作。

例子 :

Input : arr[] = {15, 4, 15}
Output : 0
Array is already a palindrome. So we
do not need any merge operation.

Input : arr[] = {1, 4, 5, 1}
Output : 1
We can make given array palindrome with
minimum one merging (merging 4 and 5 to
make 9)

Input : arr[] = {11, 14, 15, 99}
Output : 3
We need to merge all elements to make
a palindrome.

预期的时间复杂度为O(n)。

令f(i,j)为最小合并操作,以使子数组arr [i..j]成为回文。如果i == j,答案为0。我们从0开始,而i从n-1开始。

  1. 如果arr [i] == arr [j],则无需对索引i或索引j进行任何合并操作。在这种情况下,我们的答案将是f(i + 1,j-1)。
  2. 否则,我们需要进行合并操作。出现以下情况。
    • 如果arr [i]> arr [j],那么我们应该在索引j处进行合并操作。我们合并索引j-1和j,并更新arr [j-1] = arr [j-1] + arr [j]。在这种情况下,我们的答案将是1 + f(i,j-1)。
    • 对于当arr [i]
  3. 我们的答案将是f(0,n-1),其中n是数组arr []的大小。

因此,可以使用两个指针(第一个指针指向数组的开始,第二个指针指向数组的最后一个元素)方法迭代地解决此问题,并保持到目前为止完成的合并操作总数。
以下是上述想法的实现。

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));
     
    }
}


Python
# 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


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.
?>


Javascript


输出 :

Count of minimum operations is 1

给定程序的时间复杂度为:O(n)