给定一个由N 个整数组成的数组arr[] ,任务是找到数组元素递增/递减1的最小次数,以使数组的前缀和的符号交替。
例子:
Input: arr[] = {1, -3, 1, 0}
Output: 4
Explanation:
Following are the operations performed on the given array elements:
- Incrementing the array element arr[1](= -3) by 1 modifies the array to {1, -2, 1, 0}.
- Incrementing the array element arr[2](= 1) by 1 modifies the array to {1, -2, 2, 0}.
- Decrementing the array element arr[3](= 0) by 1 modifies the array to {1, -2, 2, -1}.
- Decrementing the array element arr[3](= -1) by 1 modifies the array to {1, -2, 2, -2}.
After the above operations, the prefix sum of the modified array is {1, -1, 1, -1}, which is in alternate order of sign. Therefore, the minimum number of operations required is 4.
Input: arr[] = {3, -6, 4, -5, 7}
Output: 0
方法:可以通过使用给定的操作以正、负、正、…或负、正、负、…的顺序修改数组元素来解决给定的问题,并打印所需的两个操作中的最小值。请按照以下步骤解决给定的问题:
- 对于案例1:按照负、正、负的顺序修改数组元素:
- 将变量current_prefix_1初始化为0 ,用于存储数组的前缀和。
- 将变量minOperationCase1初始化为0 ,以存储所需的最小操作数。
- 遍历给定数组并执行以下步骤:
- 通过arr[i]增加current_prefix_1 。
- 如果current_prefix_1的值或奇偶校验为 -ve,则通过abs(parity – current_prefix_1)增加最小操作次数。
- 将奇偶校验乘以(-1) 。
- 类似地,如案例 1 中所讨论的,找到前缀和的顺序为正、负、正……所需的最小运算次数,并将其存储在变量minOperationCase2 中。
- 完成上述步骤后,打印minOperationCase1和minOperationCase2的最小值作为所需的结果操作。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find the minimum number
// of increments/decrements of array
// elements by 1 to make signs of
// prefix sum array elements alternating
int minimumOperations(int A[], int N)
{
// Case 1. neg - pos - neg
int cur_prefix_1 = 0;
// Stores the current sign of
// the prefix sum of array
int parity = -1;
// Stores minimum number of operations
// for Case 1
int minOperationsCase1 = 0;
// Traverse the array
for (int i = 0; i < N; i++) {
cur_prefix_1 += A[i];
// Checking both conditions
if (cur_prefix_1 == 0
|| parity * cur_prefix_1 < 0) {
minOperationsCase1
+= abs(parity - cur_prefix_1);
// Update the current prefix1 to
// currentPrefixSum
cur_prefix_1 = parity;
}
parity *= -1;
}
// Case 2. pos - neg - pos
int cur_prefix_2 = 0;
// Stores the prefix sum of array
parity = 1;
// Stores minimum number of operations
// for Case 1
int minOperationsCase2 = 0;
for (int i = 0; i < N; i++) {
cur_prefix_2 += A[i];
// Checking both conditions
if (cur_prefix_2 == 0
|| parity * cur_prefix_2 < 0) {
minOperationsCase2
+= abs(parity - cur_prefix_2);
// Update the current prefix2 to
// currentPrefixSum
cur_prefix_2 = parity;
}
parity *= -1;
}
return min(minOperationsCase1,
minOperationsCase2);
}
// Driver Code
int main()
{
int A[] = { 1, -3, 1, 0 };
int N = sizeof(A) / sizeof(A[0]);
cout << minimumOperations(A, N);
return 0;
}
Java
// Java code for above approach
import java.util.*;
class GFG{
// Function to find the minimum number
// of increments/decrements of array
// elements by 1 to make signs of
// prefix sum array elements alternating
static int minimumOperations(int A[], int N)
{
// Case 1. neg - pos - neg
int cur_prefix_1 = 0;
// Stores the current sign of
// the prefix sum of array
int parity = -1;
// Stores minimum number of operations
// for Case 1
int minOperationsCase1 = 0;
// Traverse the array
for (int i = 0; i < N; i++) {
cur_prefix_1 += A[i];
// Checking both conditions
if (cur_prefix_1 == 0
|| parity * cur_prefix_1 < 0) {
minOperationsCase1
+= Math.abs(parity - cur_prefix_1);
// Update the current prefix1 to
// currentPrefixSum
cur_prefix_1 = parity;
}
parity *= -1;
}
// Case 2. pos - neg - pos
int cur_prefix_2 = 0;
// Stores the prefix sum of array
parity = 1;
// Stores minimum number of operations
// for Case 1
int minOperationsCase2 = 0;
for (int i = 0; i < N; i++) {
cur_prefix_2 += A[i];
// Checking both conditions
if (cur_prefix_2 == 0
|| parity * cur_prefix_2 < 0) {
minOperationsCase2
+= Math.abs(parity - cur_prefix_2);
// Update the current prefix2 to
// currentPrefixSum
cur_prefix_2 = parity;
}
parity *= -1;
}
return Math.min(minOperationsCase1,
minOperationsCase2);
}
// Driver Code
public static void main(String[] args)
{
int A[] = { 1, -3, 1, 0 };
int N = A.length;
System.out.print(minimumOperations(A, N));
}
}
// This code is contributed by avijitmondal1998.
C#
// C# code for above approach
using System;
public class GFG
{
// Function to find the minimum number
// of increments/decrements of array
// elements by 1 to make signs of
// prefix sum array elements alternating
static int minimumOperations(int []A, int N)
{
// Case 1. neg - pos - neg
int cur_prefix_1 = 0;
// Stores the current sign of
// the prefix sum of array
int parity = -1;
// Stores minimum number of operations
// for Case 1
int minOperationsCase1 = 0;
// Traverse the array
for (int i = 0; i < N; i++) {
cur_prefix_1 += A[i];
// Checking both conditions
if (cur_prefix_1 == 0
|| parity * cur_prefix_1 < 0) {
minOperationsCase1
+= Math.Abs(parity - cur_prefix_1);
// Update the current prefix1 to
// currentPrefixSum
cur_prefix_1 = parity;
}
parity *= -1;
}
// Case 2. pos - neg - pos
int cur_prefix_2 = 0;
// Stores the prefix sum of array
parity = 1;
// Stores minimum number of operations
// for Case 1
int minOperationsCase2 = 0;
for (int i = 0; i < N; i++) {
cur_prefix_2 += A[i];
// Checking both conditions
if (cur_prefix_2 == 0
|| parity * cur_prefix_2 < 0) {
minOperationsCase2
+= Math.Abs(parity - cur_prefix_2);
// Update the current prefix2 to
// currentPrefixSum
cur_prefix_2 = parity;
}
parity *= -1;
}
return Math.Min(minOperationsCase1,
minOperationsCase2);
}
// Driver Code
public static void Main(String[] args)
{
int []A = { 1, -3, 1, 0 };
int N = A.Length;
Console.Write(minimumOperations(A, N));
}
}
// This code is contributed by Amit Katiyar
Javascript
输出:
4
时间复杂度: O(N)
辅助空间: O(1)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。