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

📅  最后修改于: 2021-05-08 16:29:07             🧑  作者: 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)