📌  相关文章
📜  计算将数组分成相等GCD的两个子数组的方法

📅  最后修改于: 2021-05-17 23:46:38             🧑  作者: Mango

给定一个大小为N的数组arr [] ,任务是计算将给定数组元素拆分为两个子数组的方式的数量,以使两个子数组的GCD相等。

例子:

天真的方法:解决此问题的最简单方法是遍历数组,并在每个数组索引处将数组划分为两个子数组,然后检查两个子数组的GCD是否相等。如果发现为真,则增加此类子数组的计数。最后,打印计数。

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

高效方法:为了优化上述方法,其思想是使用Prefix Sum Array技术。请按照以下步骤解决问题:

  • 初始化一个变量,例如说cntWays,以存储将数组拆分为两个子数组的方式的数量,以使两个子数组的GCD相等。
  • 初始化一个数组,例如prefixGCD []以存储数组元素的前缀GCD。
  • 初始化一个数组,例如使用suffixGCD []存储数组元素的后缀GCD。
  • 使用变量i遍历prefixGCD []和suffixGCD []数组,并检查prefixGCD [i]suffixGCD [i + 1]是否相等。如果发现为真,则增加cntWays的值。
  • 最后,打印cntWays的值。

下面是上述方法的实现:

C++
// C++ program to implement
// the above approach
 
#include 
using namespace std;
 
// Function to count number of ways to split
// array into two groups with equal GCD value.
int cntWaysToSplitArrayTwo(int arr[], int N)
{
    // Stores prefix GCD
    // of the array
    int prefixGCD[N];
 
    // Update prefixGCD[0]
    prefixGCD[0] = arr[0];
 
    // Stores suffix GCD
    // of the array
    int suffixGCD[N];
 
    // Update suffixGCD[N - 1]
    suffixGCD[N - 1] = arr[N - 1];
 
    // Traverse the array
    for (int i = 1; i < N; i++) {
 
        // Update prefixGCD[i]
        prefixGCD[i]
            = __gcd(prefixGCD[i - 1],
                    arr[i]);
    }
 
    // Traverse the array
    for (int i = N - 2; i >= 0; i--) {
 
        // Update prefixGCD[i]
        suffixGCD[i]
            = __gcd(suffixGCD[i + 1],
                    arr[i]);
    }
 
    // Stores count of ways to split array
    // into two groups with equal GCD
    int cntWays = 0;
 
    // Traverse prefixGCD[] and suffixGCD[]
    for (int i = 0; i < N - 1; i++) {
 
        // If GCD of both groups equal
        if (prefixGCD[i]
            == suffixGCD[i + 1]) {
 
            // Update cntWays
            cntWays += 1;
        }
    }
 
    return cntWays;
}
 
// Driver Code
int main()
{
    int arr[] = { 8, 4, 4, 8, 12 };
    int N = sizeof(arr) / sizeof(arr[0]);
    cout << cntWaysToSplitArrayTwo(arr, N);
 
    return 0;
}


Java
// Java program to implement
// the above approach
import java.io.*;
import java.util.*;
 
class GFG{
  
static int gcd(int a, int b)
{
     
    // Everything divides 0
    if (a == 0)
      return b;
    if (b == 0)
      return a;
   
    // Base case
    if (a == b)
        return a;
   
    // a is greater
    if (a > b)
        return gcd(a - b, b);
         
    return gcd(a, b - a);
}
     
// Function to count number of ways to split
// array into two groups with equal GCD value.
static int cntWaysToSplitArrayTwo(int arr[],
                                  int N)
{
     
    // Stores prefix GCD
    // of the array
    int prefixGCD[] = new int[N];
     
    // Update prefixGCD[0]
    prefixGCD[0] = arr[0];
  
    // Stores suffix GCD
    // of the array
    int suffixGCD[] = new int[N];
  
    // Update suffixGCD[N - 1]
    suffixGCD[N - 1] = arr[N - 1];
  
    // Traverse the array
    for(int i = 1; i < N; i++)
    {
         
        // Update prefixGCD[i]
        prefixGCD[i] = gcd(prefixGCD[i - 1],
                                 arr[i]);
    }
  
    // Traverse the array
    for(int i = N - 2; i >= 0; i--)
    {
         
        // Update prefixGCD[i]
        suffixGCD[i] = gcd(suffixGCD[i + 1],
                                 arr[i]);
    }
  
    // Stores count of ways to split array
    // into two groups with equal GCD
    int cntWays = 0;
  
    // Traverse prefixGCD[] and suffixGCD[]
    for(int i = 0; i < N - 1; i++)
    {
         
        // If GCD of both groups equal
        if (prefixGCD[i] == suffixGCD[i + 1])
        {
             
            // Update cntWays
            cntWays += 1;
        }
    }
    return cntWays;
}
   
// Driver Code
public static void main(String[] args)
{
    int arr[] = { 8, 4, 4, 8, 12 };
    int N = arr.length;
     
    System.out.print(cntWaysToSplitArrayTwo(arr, N));
}
}
 
// This code is contributed by sanjoy_62


Python3
# Python3 program to implement
# the above approach
import math
 
# Function to count number of ways to split
# array into two groups with equal GCD value.
def cntWaysToSplitArrayTwo(arr, N):
     
    # Stores prefix GCD
    # of the array
    prefixGCD = [0] * N
  
    # Update prefixGCD[0]
    prefixGCD[0] = arr[0]
  
    # Stores suffix GCD
    # of the array
    suffixGCD = [0] * N
  
    # Update suffixGCD[N - 1]
    suffixGCD[N - 1] = arr[N - 1]
  
    # Traverse the array
    for i in range(N):
  
        # Update prefixGCD[i]
        prefixGCD[i] = math.gcd(prefixGCD[i - 1], arr[i])
     
    # Traverse the array
    for i in range(N - 2, -1, -1):
  
        # Update prefixGCD[i]
        suffixGCD[i] = math.gcd(suffixGCD[i + 1], arr[i])
     
    # Stores count of ways to split array
    # into two groups with equal GCD
    cntWays = 0
  
    # Traverse prefixGCD[] and suffixGCD[]
    for i in range(N - 1):
         
        # If GCD of both groups equal
        if (prefixGCD[i] == suffixGCD[i + 1]):
             
            # Update cntWays
            cntWays += 1
  
    return cntWays
 
# Driver Code
arr = [ 8, 4, 4, 8, 12 ]
N = len(arr)
 
print(cntWaysToSplitArrayTwo(arr, N))
 
# This code is contributed by susmitakundugoaldanga


C#
// C# program to implement
// the above approach
using System;
 
class GFG{
  
static int gcd(int a, int b)
{
     
    // Everything divides 0
    if (a == 0)
      return b;
    if (b == 0)
      return a;
   
    // Base case
    if (a == b)
        return a;
   
    // a is greater
    if (a > b)
        return gcd(a - b, b);
         
    return gcd(a, b - a);
}
     
// Function to count number of ways to split
// array into two groups with equal GCD value.
static int cntWaysToSplitArrayTwo(int []arr,
                                  int N)
{
     
    // Stores prefix GCD
    // of the array
    int []prefixGCD = new int[N];
     
    // Update prefixGCD[0]
    prefixGCD[0] = arr[0];
  
    // Stores suffix GCD
    // of the array
    int []suffixGCD = new int[N];
  
    // Update suffixGCD[N - 1]
    suffixGCD[N - 1] = arr[N - 1];
  
    // Traverse the array
    for(int i = 1; i < N; i++)
    {
         
        // Update prefixGCD[i]
        prefixGCD[i] = gcd(prefixGCD[i - 1],
                                 arr[i]);
    }
  
    // Traverse the array
    for(int i = N - 2; i >= 0; i--)
    {
         
        // Update prefixGCD[i]
        suffixGCD[i] = gcd(suffixGCD[i + 1],
                                 arr[i]);
    }
  
    // Stores count of ways to split array
    // into two groups with equal GCD
    int cntWays = 0;
  
    // Traverse prefixGCD[] and suffixGCD[]
    for(int i = 0; i < N - 1; i++)
    {
         
        // If GCD of both groups equal
        if (prefixGCD[i] == suffixGCD[i + 1])
        {
             
            // Update cntWays
            cntWays += 1;
        }
    }
    return cntWays;
}
   
// Driver Code
public static void Main(String[] args)
{
    int []arr = { 8, 4, 4, 8, 12 };
    int N = arr.Length;
     
    Console.Write(cntWaysToSplitArrayTwo(arr, N));
}
}
 
// This code is contributed by Princi Singh


Javascript


输出:
2

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