📜  使前缀和的相邻元素对的乘积为负的最小运算

📅  最后修改于: 2021-10-26 06:51:49             🧑  作者: Mango

给定一个大小为N的数组arr[ ] ,考虑一个数组prefix[ ] ,其中prefix[i]arr的前i 个元素的总和。任务是找到修改给定数组所需的最少操作次数,使得前缀数组中任意两个相邻元素的乘积为负。在一个操作中,您可以将任何元素的值增加或减少 1。

方法:这个想法是尝试两种独立的可能性,即偶数长度前缀和为正,奇数长度前缀和为负,反之亦然。请按照以下步骤解决问题:

  • 初始化一个变量res = INT_MAX来存储最小操作次数。
  • 使用变量r遍历范围 [0, 1]
    • 初始化变量ans = 0sum = 0分别存储总操作数和当前前缀和。
    • 使用变量i遍历范围 [0, N-1]
      • arr[i]添加到sum的值。
      • 如果(i+r) 的值为奇数且sum不是正数,则将sum+1添加到ans并将sum的值更新为 1。
      • 否则,如果第(i + r)为偶数,如果总和不为负然后添加总和+ 1ANS更新的值的总和为-1。
    • 将 res 的值更新为 min(res, ans)。
  • 完成上述步骤后,打印res的值。
C++
// C++ code for the above approach
#include 
using namespace std;
 
// Function to find minimum operations
// needed to make the product of any
// two adjacent elements in prefix
// sum array negative
void minOperations(vector a)
{
    // Stores the minimum operations
    int res = INT_MAX;
    int N = a.size();
 
    for (int r = 0; r < 2; r++) {
        // Stores the prefix sum
        // and number of operations
        int sum = 0, ans = 0;
 
        // Traverse the array
        for (int i = 0; i < N; i++) {
            // Update the value of sum
            sum += a[i];
            // Check if i+r is odd
            if ((i + r) % 2) {
 
                // Check if prefix sum
                // is not positive
                if (sum <= 0) {
 
                    // Update the value of
                    // ans and sum
                    ans += -sum + 1;
                    sum = 1;
                }
            }
            else {
 
                // Check if prefix sum is
                // not negative
                if (sum >= 0) {
                    // Update the value of
                    // ans and sum
                    ans += sum + 1;
                    sum = -1;
                }
            }
        }
 
        // Update the value of res
        res = min(res, ans);
    }
 
    // Print the value of res
    cout << res;
}
 
// Driver Code
int main()
{
    vector a{ 1, -3, 1, 0 };
 
    minOperations(a);
 
    return 0;
}


Java
// Java code for the above approach
import java.util.*;
 
class GFG{
  
// Function to find minimum operations
// needed to make the product of any
// two adjacent elements in prefix
// sum array negative
static void minOperations(ArrayList a)
{
     
    // Stores the minimum operations
    int res = Integer.MAX_VALUE;
    int N = a.size();
 
    for(int r = 0; r < 2; r++)
    {
         
        // Stores the prefix sum
        // and number of operations
        int sum = 0, ans = 0;
 
        // Traverse the array
        for(int i = 0; i < N; i++)
        {
             
            // Update the value of sum
            sum += a.get(i);
             
            // Check if i+r is odd
            if ((i + r) % 2 == 1)
            {
                 
                // Check if prefix sum
                // is not positive
                if (sum <= 0)
                {
                     
                    // Update the value of
                    // ans and sum
                    ans += -sum + 1;
                    sum = 1;
                }
            }
            else
            {
                 
                // Check if prefix sum is
                // not negative
                if (sum >= 0)
                {
                     
                    // Update the value of
                    // ans and sum
                    ans += sum + 1;
                    sum = -1;
                }
            }
        }
 
        // Update the value of res
        res = Math.min(res, ans);
    }
 
    // Print the value of res
    System.out.print(res);
}
 
// Driver Code
public static void main(String args[])
{
    ArrayList a = new ArrayList();
    a.add(1);
    a.add(-3);
    a.add(1);
    a.add(0);
 
    minOperations(a);
}
}
     
// This code is contributed by SURENDRA_GANGWAR


Python3
# python code for the above approach
# // Function to find minimum operations
# // needed to make the product of any
# // two adjacent elements in prefix
# // sum array negative
def minOperations(a):
   
    #Stores the minimum operations
    res = 100000000000
    N = len(a)
    for r in range(0,2):
       
        # Stores the prefix sum
        # and number of operations
        sum = 0
        ans = 0
         
        # Traverse the array
        for i in range (0,N):
           
            # Update the value of sum
            sum += a[i]
             
            # Check if i+r is odd
            if ((i + r) % 2):
 
                # Check if prefix sum
                # is not positive
                if (sum <= 0):
                   
                    # Update the value of
                    # ans and sum
                    ans += -sum + 1
                    sum = 1
            else:
 
                 # Check if prefix sum is
                # not negative
                if (sum >= 0):
                   
                    # Update the value of
                    # ans and sum
                    ans += sum + 1;
                    sum = -1;
 
        # Update the value of res
        res = min(res, ans)
         
    # // Print the value of res
    print(res)
 
    # Driver code
a = [1, -3, 1, 0]
minOperations(a);
 
# This code is contributed by Stream_Cipher


C#
// C# code for the above approach
using System;
using System.Collections.Generic;
 
class GFG
{
   
// Function to find minimum operations
// needed to make the product of any
// two adjacent elements in prefix
// sum array negative
static void minOperations(List a)
{
   
    // Stores the minimum operations
    int res = Int32.MaxValue;
    int N = a.Count;
 
    for (int r = 0; r < 2; r++)
    {
       
        // Stores the prefix sum
        // and number of operations
        int sum = 0, ans = 0;
 
        // Traverse the array
        for (int i = 0; i < N; i++)
        {
           
            // Update the value of sum
            sum += a[i];
           
            // Check if i+r is odd
            if ((i + r) % 2 == 1) {
 
                // Check if prefix sum
                // is not positive
                if (sum <= 0) {
 
                    // Update the value of
                    // ans and sum
                    ans += -sum + 1;
                    sum = 1;
                }
            }
            else {
 
                // Check if prefix sum is
                // not negative
                if (sum >= 0) {
                    // Update the value of
                    // ans and sum
                    ans += sum + 1;
                    sum = -1;
                }
            }
        }
 
        // Update the value of res
        res = Math.Min(res, ans);
    }
 
    // Print the value of res
    Console.Write(res);
}
 
// Driver Code
public static void Main()
{
    List a = new List(){ 1, -3, 1, 0 };
 
    minOperations(a);
}
}
 
// This code is contributed by bgangwar59.


Javascript


输出

4

时间复杂度: O(N)
辅助空间: O(1)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程