📌  相关文章
📜  将数组拆分为最小数量的子数组,其第一个和最后一个元素的 GCD 超过 1

📅  最后修改于: 2021-09-02 07:27:28             🧑  作者: Mango

给定一个大小为N的数组arr[] ,任务是将整个数组拆分为最少数量的子数组,使得对于每个子数组,子数组的第一个和最后一个元素的 GCD 大于 1。

例子:

朴素方法:解决问题的最简单方法是在给定数组中执行所有可能的拆分,对于每个拆分,检查所有子数组的第一个和最后一个元素的 GCD 是否大于 1。对于所有发现为真的子数组,存储子数组的计数。最后,打印这些拆分中获得的最小计数。
时间复杂度: O(2 N )
辅助空间: O(1)

高效方法:该方法基于始终使用原始数组的第一个和最后一个元素的想法。第一个元素将用于第一个子阵列拆分,最后一个元素将用于最后一个子阵列拆分。要最小化有效子数组的数量,请按照以下步骤操作:

  1. 指针固定到原始数组arr[]的最后一个元素,并找到原始数组中最左边的元素,使得GCD(left, right) > 1 。如果找不到这样的元素,则没有有效答案。
  2. 如果找到这样的元素,就意味着我们找到了一个有效的子数组。然后将指针更改为(left – 1) ,并再次开始搜索有效的子数组。
  3. 重复上述步骤直到right大于0并继续增加直到现在找到的子数组的数量。
  4. 在所有上述步骤之后打印计数的值。

下面是上述方法的实现:

C++
// C++ program for the above approach
#include 
using namespace std;
 
// Function to find the
// minimum number of subarrays
int minSubarrays(int arr[], int n)
{
    // Right pointer
    int right = n - 1;
 
    // Left pointer
    int left = 0;
 
    // Count of subarrays
    int subarrays = 0;
 
    while (right >= 0) {
 
        for (left = 0; left <= right;
             left += 1) {
 
            // Find GCD(left, right)
            if (__gcd(arr[left],
                      arr[right])
                > 1) {
 
                // Found a valid large
                // subarray between
                // arr[left, right]
                subarrays += 1;
                right = left - 1;
                break;
            }
 
            // Searched the arr[0..right]
            // and found no subarray
            // having size >1 and having
            // gcd(left, right) > 1
            if (left == right
                && __gcd(arr[left],
                         arr[right])
                       == 1) {
                return 0;
            }
        }
    }
    return subarrays;
}
 
// Driver Code
int main()
{
    int N = 6;
    int arr[] = { 2, 3, 4, 4, 4, 3 };
 
    // Function call
    cout << minSubarrays(arr, N);
    return 0;
}


Java
// Java program for the above approach
import java.util.*;
class GFG{
 
// Function to find the
// minimum number of subarrays
static int minSubarrays(int arr[], int n)
{
    // Right pointer
    int right = n - 1;
 
    // Left pointer
    int left = 0;
 
    // Count of subarrays
    int subarrays = 0;
 
    while (right >= 0)
    {
        for (left = 0; left <= right; left += 1)
        {
            // Find GCD(left, right)
            if (__gcd(arr[left],
                      arr[right]) > 1)
            {
                // Found a valid large
                // subarray between
                // arr[left, right]
                subarrays += 1;
                right = left - 1;
                break;
            }
 
            // Searched the arr[0..right]
            // and found no subarray
            // having size >1 and having
            // gcd(left, right) > 1
            if (left == right &&
                __gcd(arr[left],
                arr[right]) == 1)
            {
                return 0;
            }
        }
    }
    return subarrays;
}
static int __gcd(int a, int b) 
{ 
    return b == 0 ? a : __gcd(b, a % b);    
}
// Driver Code
public static void main(String[] args)
{
    int N = 6;
    int arr[] = {2, 3, 4, 4, 4, 3};
 
    // Function call
    System.out.print(minSubarrays(arr, N));
}
}
 
// This code is contributed by Rajput-Ji


Python3
# Python3 program for the above approach
from math import gcd
 
# Function to find the
# minimum number of subarrays
def minSubarrays(arr, n):
     
    # Right pointer
    right = n - 1
 
    # Left pointer
    left = 0
 
    # Count of subarrays
    subarrays = 0
 
    while (right >= 0):
        for left in range(right + 1):
 
            # Find GCD(left, right)
            if (gcd(arr[left], arr[right]) > 1):
 
                # Found a valid large
                # subarray between
                # arr[left, right]
                subarrays += 1
                right = left - 1
                break
 
            # Searched the arr[0..right]
            # and found no subarray
            # having size >1 and having
            # gcd(left, right) > 1
            if (left == right and
                __gcd(arr[left],
                      arr[right]) == 1):
                return 0
 
    return subarrays
 
# Driver Code
if __name__ == '__main__':
     
    N = 6
    arr = [ 2, 3, 4, 4, 4, 3 ]
 
    # Function call
    print(minSubarrays(arr, N))
     
# This code is contributed by mohit kumar 29


C#
// C# program for the above approach
using System;
class GFG{
 
// Function to find the
// minimum number of subarrays
static int minSubarrays(int[] arr, int n)
{
    // Right pointer
    int right = n - 1;
 
    // Left pointer
    int left = 0;
 
    // Count of subarrays
    int subarrays = 0;
 
    while (right >= 0)
    {
        for (left = 0; left <= right; left += 1)
        {
            // Find GCD(left, right)
            if (__gcd(arr[left],
                      arr[right]) > 1)
            {
                // Found a valid large
                // subarray between
                // arr[left, right]
                subarrays += 1;
                right = left - 1;
                break;
            }
 
            // Searched the arr[0..right]
            // and found no subarray
            // having size >1 and having
            // gcd(left, right) > 1
            if (left == right &&
                __gcd(arr[left],
                      arr[right]) == 1)
            {
                return 0;
            }
        }
    }
    return subarrays;
}
   
static int __gcd(int a, int b) 
{ 
    return b == 0 ? a : __gcd(b, a % b);    
}
   
// Driver Code
public static void Main()
{
    int N = 6;
    int[] arr = {2, 3, 4, 4, 4, 3};
 
    // Function call
    Console.Write(minSubarrays(arr, N));
}
}
 
// This code is contributed by Chitranayal


Javascript


输出:
2

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

如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live