给定N 个整数的排序数组。任务是找到最长的子序列,使得子序列中的每个元素都可以通过将任何素数乘以子序列中的前一个元素来达到。
注意:A[i] <= 10 5
例子:
Input: a[] = {3, 5, 6, 12, 15, 36}
Output 4
The longest subsequence is {3, 6, 12, 36}
6 = 3*2
12 = 6*2
36 = 12*3
2 and 3 are primes
Input: a[] = {1, 2, 5, 6, 12, 35, 60, 385}
Output: 5
方法:这个问题可以通过使用预先存储素数直到数组中的最大数和使用基本的动态规划来解决。可以按照以下步骤解决上述问题:
- 最初,它们将所有素数存储在任何数据结构中。
- 散列散列图中数字的索引。
- 创建一个大小为 N 的 dp[],并在每个地方用 1 初始化它,因为最长的子序列可能只有 1。 dp[i]表示以a[i]为起始元素可以形成的最长子序列的长度。
- 从 n-2 开始迭代,对每个数乘以所有素数,直到超过 a[n-1] 并执行以下操作。
- 将数字 a[i] 与素数相乘得到 x。如果 x 存在于散列映射中,那么循环将是dp[i] = max(dp[i], 1 + dp[hash[x]]) 。
- 最后,在 dp[] 数组中迭代并找到最大值作为我们的答案。
下面是上述方法的实现:
C++
// C++ program to implement the
// above approach
#include
using namespace std;
// Function to pre-store primes
void SieveOfEratosthenes(int MAX, vector& primes)
{
bool prime[MAX + 1];
memset(prime, true, sizeof(prime));
// Sieve method to check if prime or not
for (long long p = 2; p * p <= MAX; p++) {
if (prime[p] == true) {
// Multiples
for (long long i = p * p; i <= MAX; i += p)
prime[i] = false;
}
}
// Pre-store all the primes
for (long long i = 2; i <= MAX; i++) {
if (prime[i])
primes.push_back(i);
}
}
// Function to find the longest subsequence
int findLongest(int A[], int n)
{
// Hash map
unordered_map mpp;
vector primes;
// Call the function to pre-store the primes
SieveOfEratosthenes(A[n - 1], primes);
int dp[n];
memset(dp, 0, sizeof dp);
// Initialize last element with 1
// as that is the longest possible
dp[n - 1] = 1;
mpp[A[n - 1]] = n - 1;
// Iterate from the back and find the longest
for (int i = n - 2; i >= 0; i--) {
// Get the number
int num = A[i];
// Initialize dp[i] as 1
// as the element will only me in
// the subsequence .
dp[i] = 1;
int maxi = 0;
// Iterate in all the primes and
// multiply to get the next element
for (auto it : primes) {
// Next element if multiplied with it
int xx = num * it;
// If exceeds the last element
// then break
if (xx > A[n - 1])
break;
// If the number is there in the array
else if (mpp[xx] != 0) {
// Get the maximum most element
dp[i] = max(dp[i], 1 + dp[mpp[xx]]);
}
}
// Hash the element
mpp[A[i]] = i;
}
int ans = 1;
// Find the longest
for (int i = 0; i < n; i++) {
ans = max(ans, dp[i]);
}
return ans;
}
// Driver Code
int main()
{
int a[] = { 1, 2, 5, 6, 12, 35, 60, 385 };
int n = sizeof(a) / sizeof(a[0]);
cout << findLongest(a, n);
}
Java
// Java program to implement the
// above approach
import java.util.HashMap;
import java.util.Vector;
class GFG
{
// Function to pre-store primes
public static void SieveOfEratosthenes(int MAX,
Vector primes)
{
boolean[] prime = new boolean[MAX + 1];
for (int i = 0; i < MAX + 1; i++)
prime[i] = true;
// Sieve method to check if prime or not
for (int p = 2; p * p <= MAX; p++)
{
if (prime[p] == true)
{
// Multiples
for (int i = p * p; i <= MAX; i += p)
prime[i] = false;
}
}
// Pre-store all the primes
for (int i = 2; i <= MAX; i++)
{
if (prime[i])
primes.add(i);
}
}
// Function to find the intest subsequence
public static int findLongest(int[] A, int n)
{
// Hash map
HashMap mpp = new HashMap<>();
Vector primes = new Vector<>();
// Call the function to pre-store the primes
SieveOfEratosthenes(A[n - 1], primes);
int[] dp = new int[n];
// Initialize last element with 1
// as that is the intest possible
dp[n - 1] = 1;
mpp.put(A[n - 1], n - 1);
// Iterate from the back and find the intest
for (int i = n - 2; i >= 0; i--)
{
// Get the number
int num = A[i];
// Initialize dp[i] as 1
// as the element will only me in
// the subsequence .
dp[i] = 1;
int maxi = 0;
// Iterate in all the primes and
// multiply to get the next element
for (int it : primes)
{
// Next element if multiplied with it
int xx = num * it;
// If exceeds the last element
// then break
if (xx > A[n - 1])
break;
// If the number is there in the array
else if (mpp.get(xx) != null && mpp.get(xx) != 0)
{
// Get the maximum most element
dp[i] = Math.max(dp[i], 1 + dp[mpp.get(xx)]);
}
}
// Hash the element
mpp.put(A[i], i);
}
int ans = 1;
// Find the intest
for (int i = 0; i < n; i++)
ans = Math.max(ans, dp[i]);
return ans;
}
// Driver code
public static void main(String[] args)
{
int[] a = { 1, 2, 5, 6, 12, 35, 60, 385 };
int n = a.length;
System.out.println(findLongest(a, n));
}
}
// This code is contributed by
// sanjeev2552
Python3
# Python3 program to implement the
# above approach
from math import sqrt
# Function to pre-store primes
def SieveOfEratosthenes(MAX, primes) :
prime = [True]*(MAX + 1);
# Sieve method to check if prime or not
for p in range(2,int(sqrt(MAX)) + 1) :
if (prime[p] == True) :
# Multiples
for i in range(p**2, MAX + 1, p) :
prime[i] = False;
# Pre-store all the primes
for i in range(2, MAX + 1) :
if (prime[i]) :
primes.append(i);
# Function to find the longest subsequence
def findLongest(A, n) :
# Hash map
mpp = {};
primes = [];
# Call the function to pre-store the primes
SieveOfEratosthenes(A[n - 1], primes);
dp = [0] * n ;
# Initialize last element with 1
# as that is the longest possible
dp[n - 1] = 1;
mpp[A[n - 1]] = n - 1;
# Iterate from the back and find the longest
for i in range(n-2,-1,-1) :
# Get the number
num = A[i];
# Initialize dp[i] as 1
# as the element will only me in
# the subsequence
dp[i] = 1;
maxi = 0;
# Iterate in all the primes and
# multiply to get the next element
for it in primes :
# Next element if multiplied with it
xx = num * it;
# If exceeds the last element
# then break
if (xx > A[n - 1]) :
break;
# If the number is there in the array
elif xx in mpp :
# Get the maximum most element
dp[i] = max(dp[i], 1 + dp[mpp[xx]]);
# Hash the element
mpp[A[i]] = i;
ans = 1;
# Find the longest
for i in range(n) :
ans = max(ans, dp[i]);
return ans;
# Driver Code
if __name__ == "__main__" :
a = [ 1, 2, 5, 6, 12, 35, 60, 385 ];
n = len(a);
print(findLongest(a, n));
# This code is contributed by AnkitRai01
C#
// C# program to implement the
// above approach
using System;
using System.Collections.Generic;
class GFG
{
// Function to pre-store primes
public static void SieveOfEratosthenes(int MAX,
List primes)
{
Boolean[] prime = new Boolean[MAX + 1];
for (int i = 0; i < MAX + 1; i++)
prime[i] = true;
// Sieve method to check if prime or not
for (int p = 2; p * p <= MAX; p++)
{
if (prime[p] == true)
{
// Multiples
for (int i = p * p; i <= MAX; i += p)
prime[i] = false;
}
}
// Pre-store all the primes
for (int i = 2; i <= MAX; i++)
{
if (prime[i])
primes.Add(i);
}
}
// Function to find the intest subsequence
public static int findLongest(int[] A, int n)
{
// Hash map
Dictionary mpp = new Dictionary();
List primes = new List();
// Call the function to pre-store the primes
SieveOfEratosthenes(A[n - 1], primes);
int[] dp = new int[n];
// Initialize last element with 1
// as that is the intest possible
dp[n - 1] = 1;
mpp.Add(A[n - 1], n - 1);
// Iterate from the back and find the intest
for (int i = n - 2; i >= 0; i--)
{
// Get the number
int num = A[i];
// Initialize dp[i] as 1
// as the element will only me in
// the subsequence .
dp[i] = 1;
// Iterate in all the primes and
// multiply to get the next element
foreach (int it in primes)
{
// Next element if multiplied with it
int xx = num * it;
// If exceeds the last element
// then break
if (xx > A[n - 1])
break;
// If the number is there in the array
else if (mpp.ContainsKey(xx) && mpp[xx] != 0)
{
// Get the maximum most element
dp[i] = Math.Max(dp[i], 1 + dp[mpp[xx]]);
}
}
// Hash the element
if(mpp.ContainsKey(A[i]))
mpp[A[i]] = i;
else
mpp.Add(A[i], i);
}
int ans = 1;
// Find the intest
for (int i = 0; i < n; i++)
ans = Math.Max(ans, dp[i]);
return ans;
}
// Driver code
public static void Main(String[] args)
{
int[] a = { 1, 2, 5, 6, 12, 35, 60, 385 };
int n = a.Length;
Console.WriteLine(findLongest(a, n));
}
}
// This code is contributed by Rajput-Ji
Javascript
输出:
5
时间复杂度:O(N log N)
辅助空间:O(N)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。