给定一个由N 个整数组成的数组arr[] ,任务是找到最长的子数组,其中该子数组中的所有数字都是素数。
例子:
Input: arr[] = {3, 5, 2, 66, 7, 11, 8}
Output: 3
Explanation:
Maximum contiguous prime number sequence is {2, 3, 5}
Input: arr[] = {1, 2, 11, 32, 8, 9}
Output: 2
Explanation:
Maximum contiguous prime number sequence is {2, 11}
方法:
对于按10 6顺序排列的数组元素,我们在本文中讨论了一种方法。
对于按10 9顺序排列的数组元素,其想法是使用 Segmented Sieve 来查找最大为10 9 的质数。
步骤:
- 使用本文中讨论的方法找到数组的最小元素和最大元素范围之间的质数。
- 计算范围之间的素数后。可以使用 Kadane 算法计算具有质数的最长子阵列。以下是步骤:
- 使用两个名为current_max和max_so_far 的变量遍历给定数组arr[] 。
- 如果找到质数,则增加current_max并将其与max_so_far进行比较。
- 如果current_max大于max_so_far ,则将 max_so_far 更新为current_max 。
- 如果任何元素是非素数元素,则将current_max重置为 0。
下面是上述方法的实现:
C++
// C++ program to find longest subarray
// of prime numbers
#include
using namespace std;
// To store the prime numbers
unordered_set allPrimes;
// Function that find prime numbers
// till limit
void simpleSieve(int limit,
vector& prime)
{
bool mark[limit + 1];
memset(mark, false, sizeof(mark));
// Find primes using
// Sieve of Eratosthenes
for (int i = 2; i <= limit; ++i) {
if (mark[i] == false) {
prime.push_back(i);
for (int j = i; j <= limit;
j += i) {
mark[j] = true;
}
}
}
}
// Function that finds all prime
// numbers in given range using
// Segmented Sieve
void primesInRange(int low, int high)
{
// Find the limit
int limit = floor(sqrt(high)) + 1;
// To store the prime numbers
vector prime;
// Comput all primes less than
// or equals to sqrt(high)
// using Simple Sieve
simpleSieve(limit, prime);
// Count the elements in the
// range [low, high]
int n = high - low + 1;
// Declaring boolean for the
// range [low, high]
bool mark[n + 1];
// Initialise bool[] to false
memset(mark, false, sizeof(mark));
// Traverse the prime numbers till
// limit
for (int i = 0; i < prime.size(); i++) {
int loLim = floor(low / prime[i]);
loLim
*= prime[i];
// Find the minimum number in
// [low..high] that is a
// multiple of prime[i]
if (loLim < low) {
loLim += prime[i];
}
if (loLim == prime[i]) {
loLim += prime[i];
}
// Mark the multiples of prime[i]
// in [low, high] as true
for (int j = loLim; j <= high;
j += prime[i])
mark[j - low] = true;
}
// Element which are not marked in
// range are Prime
for (int i = low; i <= high; i++) {
if (!mark[i - low]) {
allPrimes.insert(i);
}
}
}
// Function that finds longest subarray
// of prime numbers
int maxPrimeSubarray(int arr[], int n)
{
int current_max = 0;
int max_so_far = 0;
for (int i = 0; i < n; i++) {
// If element is Non-prime then
// updated current_max to 0
if (!allPrimes.count(arr[i]))
current_max = 0;
// If element is prime, then
// update current_max and
// max_so_far
else {
current_max++;
max_so_far = max(current_max,
max_so_far);
}
}
// Return the count of longest
// subarray
return max_so_far;
}
// Driver Code
int main()
{
int arr[] = { 1, 2, 4, 3, 29,
11, 7, 8, 9 };
int n = sizeof(arr) / sizeof(arr[0]);
// Find minimum and maximum element
int max_el = *max_element(arr, arr + n);
int min_el = *min_element(arr, arr + n);
// Find prime in the range
// [min_el, max_el]
primesInRange(min_el, max_el);
// Function call
cout << maxPrimeSubarray(arr, n);
return 0;
}
Java
// Java program to find longest subarray
// of prime numbers
import java.util.*;
import java.lang.*;
import java.io.*;
class GFG{
// To store the prime numbers
static Set allPrimes = new HashSet<>();
// Function that find prime numbers
// till limit
static void simpleSieve(int limit,
ArrayList prime)
{
boolean []mark = new boolean[limit + 1];
// Find primes using
// Sieve of Eratosthenes
for(int i = 2; i <= limit; ++i)
{
if (mark[i] == false)
{
prime.add(i);
for(int j = i; j <= limit; j += i)
{
mark[j] = true;
}
}
}
}
// Function that finds all prime
// numbers in given range using
// Segmented Sieve
static void primesInRange(int low, int high)
{
// Find the limit
int limit = (int)Math.floor(Math.sqrt(high)) + 1;
// To store the prime numbers
ArrayList prime = new ArrayList<>();
// Comput all primes less than
// or equals to sqrt(high)
// using Simple Sieve
simpleSieve(limit, prime);
// Count the elements in the
// range [low, high]
int n = high - low + 1;
// Declaring boolean for the
// range [low, high]
boolean []mark = new boolean[n + 1];
// Traverse the prime numbers till
// limit
for(int i = 0; i < prime.size(); i++)
{
int loLim = (int)Math.floor((double)low /
(int)prime.get(i));
loLim *= (int)prime.get(i);
// Find the minimum number in
// [low..high] that is a
// multiple of prime[i]
if (loLim < low)
{
loLim += (int)prime.get(i);
}
if (loLim == (int)prime.get(i))
{
loLim += (int)prime.get(i);
}
// Mark the multiples of prime[i]
// in [low, high] as true
for(int j = loLim; j <= high;
j += (int)prime.get(i))
mark[j - low] = true;
}
// Element which are not marked in
// range are Prime
for(int i = low; i <= high; i++)
{
if (!mark[i - low])
{
allPrimes.add(i);
}
}
}
// Function that finds longest subarray
// of prime numbers
static int maxPrimeSubarray(int []arr, int n)
{
int current_max = 0;
int max_so_far = 0;
for(int i = 0; i < n; i++)
{
// If element is Non-prime then
// updated current_max to 0
if (!allPrimes.contains(arr[i]))
current_max = 0;
// If element is prime, then
// update current_max and
// max_so_far
else
{
current_max++;
max_so_far = Math.max(current_max,
max_so_far);
}
}
// Return the count of longest
// subarray
return max_so_far;
}
// Driver code
public static void main(String[] args)
{
int []arr = { 1, 2, 4, 3, 29,
11, 7, 8, 9 };
int n = arr.length;
// Find minimum and maximum element
int max_el = Integer.MIN_VALUE;
int min_el = Integer.MAX_VALUE;
for(int i = 0; i < n; i++)
{
if (arr[i] < min_el)
{
min_el = arr[i];
}
if (arr[i] > max_el)
{
max_el = arr[i];
}
}
// Find prime in the range
// [min_el, max_el]
primesInRange(min_el, max_el);
// Function call
System.out.print(maxPrimeSubarray(arr, n));
}
}
// This code is contributed by offbeat
Python3
# Python3 program to find longest subarray
# of prime numbers
import math
# To store the prime numbers
allPrimes = set()
# Function that find prime numbers
# till limit
def simpleSieve(limit, prime):
mark = [False] * (limit + 1)
# Find primes using
# Sieve of Eratosthenes
for i in range(2, limit + 1):
if mark[i] == False:
prime.append(i)
for j in range(i, limit + 1, i):
mark[j] = True
# Function that finds all prime
# numbers in given range using
# Segmented Sieve
def primesInRange(low, high):
# Find the limit
limit = math.floor(math.sqrt(high)) + 1
# To store the prime numbers
prime = []
# Compute all primes less than
# or equals to sqrt(high)
# using Simple Sieve
simpleSieve(limit, prime)
# Count the elements in the
# range [low, high]
n = high - low + 1
# Declaring and initializing boolean
# for the range[low,high] to False
mark = [False] * (n + 1)
# Traverse the prime numbers till
# limit
for i in range(len(prime)):
loLim = low // prime[i]
loLim *= prime[i]
# Find the minimum number in
# [low..high] that is a
# multiple of prime[i]
if loLim < low:
loLim += prime[i]
if loLim == prime[i]:
loLim += prime[i]
# Mark the multiples of prime[i]
# in [low, high] as true
for j in range(loLim, high + 1, prime[i]):
mark[j - low] = True
# Element which are not marked in
# range are Prime
for i in range(low, high + 1):
if not mark[i - low]:
allPrimes.add(i)
# Function that finds longest subarray
# of prime numbers
def maxPrimeSubarray(arr, n):
current_max = 0
max_so_far = 0
for i in range(n):
# If element is Non-prime then
# updated current_max to 0
if arr[i] not in allPrimes:
current_max = 0
# If element is prime, then
# update current_max and
# max_so_far
else:
current_max += 1
max_so_far = max(current_max,
max_so_far)
# Return the count of longest
# subarray
return max_so_far
# Driver Code
arr = [ 1, 2, 4, 3, 29, 11, 7, 8, 9 ]
n = len(arr)
# Find minimum and maximum element
max_el = max(arr)
min_el = min(arr)
# Find prime in the range
# [min_el, max_el]
primesInRange(min_el, max_el)
# Function call
print(maxPrimeSubarray(arr, n))
# This code is contributed by Shivam Singh
C#
// C# program to find longest subarray
// of prime numbers
using System;
using System.Collections;
using System.Collections.Generic;
class GFG{
// To store the prime numbers
static HashSet allPrimes = new HashSet();
// Function that find prime numbers
// till limit
static void simpleSieve(int limit,
ref ArrayList prime)
{
bool []mark = new bool[limit + 1];
Array.Fill(mark, false);
// Find primes using
// Sieve of Eratosthenes
for(int i = 2; i <= limit; ++i)
{
if (mark[i] == false)
{
prime.Add(i);
for(int j = i; j <= limit; j += i)
{
mark[j] = true;
}
}
}
}
// Function that finds all prime
// numbers in given range using
// Segmented Sieve
static void primesInRange(int low, int high)
{
// Find the limit
int limit = (int)Math.Floor(Math.Sqrt(high)) + 1;
// To store the prime numbers
ArrayList prime = new ArrayList();
// Comput all primes less than
// or equals to sqrt(high)
// using Simple Sieve
simpleSieve(limit, ref prime);
// Count the elements in the
// range [low, high]
int n = high - low + 1;
// Declaring boolean for the
// range [low, high]
bool []mark = new bool[n + 1];
// Initialise bool[] to false
Array.Fill(mark, false);
// Traverse the prime numbers till
// limit
for(int i = 0; i < prime.Count; i++)
{
int loLim = (int)Math.Floor((double)low /
(int)prime[i]);
loLim *= (int)prime[i];
// Find the minimum number in
// [low..high] that is a
// multiple of prime[i]
if (loLim < low)
{
loLim += (int)prime[i];
}
if (loLim == (int)prime[i])
{
loLim += (int)prime[i];
}
// Mark the multiples of prime[i]
// in [low, high] as true
for(int j = loLim; j <= high;
j += (int)prime[i])
mark[j - low] = true;
}
// Element which are not marked in
// range are Prime
for(int i = low; i <= high; i++)
{
if (!mark[i - low])
{
allPrimes.Add(i);
}
}
}
// Function that finds longest subarray
// of prime numbers
static int maxPrimeSubarray(int []arr, int n)
{
int current_max = 0;
int max_so_far = 0;
for(int i = 0; i < n; i++)
{
// If element is Non-prime then
// updated current_max to 0
if (!allPrimes.Contains(arr[i]))
current_max = 0;
// If element is prime, then
// update current_max and
// max_so_far
else
{
current_max++;
max_so_far = Math.Max(current_max,
max_so_far);
}
}
// Return the count of longest
// subarray
return max_so_far;
}
// Driver code
public static void Main(string[] args)
{
int []arr = { 1, 2, 4, 3, 29,
11, 7, 8, 9 };
int n = arr.Length;
// Find minimum and maximum element
int max_el = Int32.MinValue;
int min_el = Int32.MaxValue;
for(int i = 0; i < n; i++)
{
if (arr[i] < min_el)
{
min_el = arr[i];
}
if (arr[i] > max_el)
{
max_el = arr[i];
}
}
// Find prime in the range
// [min_el, max_el]
primesInRange(min_el, max_el);
// Function call
Console.Write(maxPrimeSubarray(arr, n));
}
}
// This code is contributed by rutvik_56
Javascript
输出:
4
时间复杂度: O(N),其中 N 是数组的长度。
辅助空间: O(N),其中 N 是数组的长度。
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。