给定一个大小为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( )
辅助空间: O(1)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。