给定一个由N个元素组成的数组arr [] ,任务是找到最小子数组的长度,以便当从数组中删除该子数组时,所得数组的GCD最大。
注意:结果数组应为非空。
例子:
Input: N = 4, arr[] = {3, 6, 1, 2}
Output: 2
Explanation:
If we remove the subarray {1, 2} then the resulting subarray will be {3, 6} and the GCD of this is 3 which is the maximum possible value.
Input: N = 3, arr[] = {4, 8, 4}
Output: 0
Explanation:
Here we don’t need to remove any subarray and the maximum GCD possible is 4.
方法:已知GCD是一种非递增函数。也就是说,如果我们在数组中添加元素,则gcd将会减小或保持恒定。因此,该想法是使用此概念来解决此问题:
- 现在我们必须注意,在删除子数组之后,所得子数组应具有第一个或最后一个元素,或者具有两个元素。这是因为我们需要确保除去子数组后的结果数组应为非空。因此,我们无法删除所有元素。
- 因此,最大GCD可能为max(A [0],A [N – 1]) 。
- 现在,我们必须最小化为获得此答案而需要删除的子数组的长度。
- 为此,我们将使用两个指针技术,分别指向第一个和最后一个元素。
- 现在,如果该元素可被该gcd整除,我们将增加第一个指针,如果该元素可被gcd整除,我们将减少最后一个指针,因为这不会影响我们的答案。
- 因此,最后,两个指针之间的元素数将是我们需要删除的子数组的长度。
下面是上述方法的实现:
C++
// C++ program to find the length of
// the smallest subarray that must be
// removed in order to maximise the GCD
#include
using namespace std;
// Function to find the length of
// the smallest subarray that must be
// removed in order to maximise the GCD
int GetMinSubarrayLength(int a[], int n)
{
// Store the maximum possible
// GCD of the resulting subarray
int ans = max(a[0], a[n - 1]);
// Two pointers initially pointing
// to the first and last element
// respectively
int lo = 0, hi = n - 1;
// Moving the left pointer to the
// right if the elements are
// divisible by the maximum GCD
while (lo < n and a[lo] % ans == 0)
lo++;
// Moving the right pointer to the
// left if the elements are
// divisible by the maximum GCD
while (hi > lo and a[hi] % ans == 0)
hi--;
// Return the length of
// the subarray
return (hi - lo + 1);
}
// Driver code
int main()
{
int arr[] = { 4, 8, 2, 1, 4 };
int N = sizeof(arr) / sizeof(arr[0]);
int length = GetMinSubarrayLength(arr, N);
cout << length << "\n";
return 0;
}
Java
// Java program to find the length of
// the smallest subarray that must be
// removed in order to maximise the GCD
class GFG {
// Function to find the length of
// the smallest subarray that must be
// removed in order to maximise the GCD
static int GetMinSubarrayLength(int a[], int n)
{
// Store the maximum possible
// GCD of the resulting subarray
int ans = Math.max(a[0], a[n - 1]);
// Two pointers initially pointing
// to the first and last element
// respectively
int lo = 0, hi = n - 1;
// Moving the left pointer to the
// right if the elements are
// divisible by the maximum GCD
while (lo < n && a[lo] % ans == 0)
lo++;
// Moving the right pointer to the
// left if the elements are
// divisible by the maximum GCD
while (hi > lo && a[hi] % ans == 0)
hi--;
// Return the length of
// the subarray
return (hi - lo + 1);
}
// Driver code
public static void main (String[] args)
{
int arr[] = { 4, 8, 2, 1, 4 };
int N = arr.length;
int Length = GetMinSubarrayLength(arr, N);
System.out.println(Length);
}
}
// This code is contributed by Yash_R
Python3
# Python3 program to find the length of
# the smallest subarray that must be
# removed in order to maximise the GCD
# Function to find the length of
# the smallest subarray that must be
# removed in order to maximise the GCD
def GetMinSubarrayLength(a, n):
# Store the maximum possible
# GCD of the resulting subarray
ans = max(a[0], a[n - 1])
# Two pointers initially pointing
# to the first and last element
# respectively
lo = 0
hi = n - 1
# Moving the left pointer to the
# right if the elements are
# divisible by the maximum GCD
while (lo < n and a[lo] % ans == 0):
lo += 1
# Moving the right pointer to the
# left if the elements are
# divisible by the maximum GCD
while (hi > lo and a[hi] % ans == 0):
hi -= 1
# Return the length of
# the subarray
return (hi - lo + 1)
# Driver code
if __name__ == '__main__':
arr = [4, 8, 2, 1, 4]
N = len(arr)
length = GetMinSubarrayLength(arr, N)
print(length)
# This code is contributed by mohit kumar 29
C#
// C# program to find the length of
// the smallest subarray that must be
// removed in order to maximise the GCD
using System;
class GFG {
// Function to find the length of
// the smallest subarray that must be
// removed in order to maximise the GCD
static int GetMinSubarrayLength(int []a, int n)
{
// Store the maximum possible
// GCD of the resulting subarray
int ans = Math.Max(a[0], a[n - 1]);
// Two pointers initially pointing
// to the first and last element
// respectively
int lo = 0, hi = n - 1;
// Moving the left pointer to the
// right if the elements are
// divisible by the maximum GCD
while (lo < n && a[lo] % ans == 0)
lo++;
// Moving the right pointer to the
// left if the elements are
// divisible by the maximum GCD
while (hi > lo && a[hi] % ans == 0)
hi--;
// Return the length of
// the subarray
return (hi - lo + 1);
}
// Driver code
public static void Main (string[] args)
{
int []arr = { 4, 8, 2, 1, 4 };
int N = arr.Length;
int Length = GetMinSubarrayLength(arr, N);
Console.WriteLine(Length);
}
}
// This code is contributed by Yash_R
输出:
2
时间复杂度: O(N)