给定大小为N的数组arr [] ,任务是将整个数组拆分为最小数量的子数组,以使得对于每个子数组,子数组的第一个元素和最后一个元素的GCD都大于1。
例子:
Input: arr[] = {2, 3, 4, 4, 4, 3}
Output: 2
Explanation:
Split the given array into [2, 3, 4, 4, 4] and [3].
The first subarray has gcd(2, 4) = 2 which is more than 1 and
The second subarray has gcd(3, 3) = 3 which is also more than 1.
Input: arr[] = {1, 2, 3}
Output: 0
Explanation:
There is no possible splitting of the given array into subarrays in which the GCD of first and last element of the subarray is more than 1.
天真的方法:解决问题的最简单方法是在给定数组中执行所有可能的拆分,对于每个拆分,检查所有子数组的第一个和最后一个元素的GCD是否大于1。对于被发现为真的所有子阵列,存储子阵列的计数。最后,打印在这些拆分中获得的最小计数。
时间复杂度: O(2 N )
辅助空间: O(1)
高效方法:该方法基于始终使用原始数组的第一个和最后一个元素的想法。第一个元素将在第一个子数组拆分中使用,最后一个元素将在最后一个子数组拆分中使用。为了最大程度地减少有效子数组的数量,请按照以下步骤操作:
- 固定一个指向原始数组arr []的最后一个元素的右指针,并在原始数组中找到最左边的元素,使GCD(left,right)> 1 。如果找不到这样的元素,则没有有效的答案。
- 如果找到了这样的元素,则意味着我们已经找到了有效的子数组。然后将右指针更改为(left – 1) ,然后再次开始搜索有效的子数组。
- 重复上述步骤,直到right大于0,并继续增加到目前为止找到的子数组的数量。
- 完成上述所有步骤后,打印计数值。
下面是上述方法的实现:
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)