给定正整数数组。我们需要将给定的数组设为“回文”。唯一允许的操作是“合并”(两个相邻元素的)。合并两个相邻元素意味着用它们的总和替换它们。任务是找到使给定数组成为“回文”所需的最小合并操作数。
要使任何数组成为回文,我们可以简单地应用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开始。
- 如果arr [i] == arr [j],则无需对索引i或索引j进行任何合并操作。在这种情况下,我们的答案将是f(i + 1,j-1)。
- 否则,我们需要进行合并操作。出现以下情况。
- 如果arr [i]> arr [j],那么我们应该在索引j处进行合并操作。我们合并索引j-1和j,并更新arr [j-1] = arr [j-1] + arr [j]。在这种情况下,我们的答案将是1 + f(i,j-1)。
- 对于当arr [i]
- 我们的答案将是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)