给定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
输出:
5
时间复杂度:O(N log N)
辅助空间:O(N)