Maximize length of increasing subsequence possible by replacing array element by nearest primes
Last Updated :
17 May, 2021
Given an array arr[], the task is to maximize the length of increasing subsequence by replacing elements to greater or smaller prime number to the element.
Examples:
Input: arr[] = {4, 20, 6, 12}
Output: 3
Explanation:
Modify the array arr[] as {3, 19, 5, 11} to maximize answer,
where {3, 5, 11} is longest increasing subsequence with length as 3.
Input: arr[] = {30, 43, 42, 19}
Output: 2
Explanation:
Modify the array arr[] as {31, 43, 42, 19} to maximize answer,
where {31, 43} is longest increasing subsequence with length as 2.
Approach: The idea is to replace each element with a smaller prime number and next prime number and form another sequence over which we can apply the standard Longest increasing subsequence algorithm. Keeping a greater prime number before the smaller prime number guarantees that both of them cannot exist in any increasing sequence simultaneously.
Below is the implementation of the above approach:
C++14
#include<bits/stdc++.h>
using namespace std;
bool isprime( int n)
{
if (n < 2)
return false ;
for ( int i = 2; i * i <= n; i++)
if (n % i == 0)
return false ;
return true ;
}
int nextprime( int n)
{
while (!isprime(n))
n++;
return n;
}
int prevprime( int n)
{
if (n < 2)
return 2;
while (!isprime(n))
n--;
return n;
}
int longestSequence(vector< int > A)
{
int n = A.size();
int M = 1;
vector< int > l;
l.push_back(prevprime(A[0]));
for ( int i = 1; i < n; i++)
{
int x = A[i];
for ( int p :{ nextprime(x),
prevprime(x) })
{
int low = 0;
int high = M - 1;
if (p <= l[0])
{
l[0] = p;
continue ;
}
while (low < high)
{
int mid = (low + high + 1) / 2;
if (p > l[mid])
low = mid;
else
high = mid - 1;
}
if (low + 1 < M)
l[low + 1] = p;
else
{
l.push_back(p);
M++;
}
}
}
return M;
}
int main()
{
vector< int > A = { 4, 20, 6, 12 };
cout << (longestSequence(A));
}
|
Java
import java.util.*;
import java.lang.*;
class GFG {
static boolean isprime( int n)
{
if (n < 2 )
return false ;
for ( int i = 2 ; i * i <= n; i++)
if (n % i == 0 )
return false ;
return true ;
}
static int nextprime( int n)
{
while (!isprime(n))
n++;
return n;
}
static int prevprime( int n)
{
if (n < 2 )
return 2 ;
while (!isprime(n))
n--;
return n;
}
static int longestSequence( int [] A)
{
int n = A.length;
int M = 1 ;
List<Integer> l
= new ArrayList<>();
l.add(prevprime(A[ 0 ]));
for ( int i = 1 ; i < n; i++) {
int x = A[i];
for ( int p :
new int [] { nextprime(x),
prevprime(x) }) {
int low = 0 ;
int high = M - 1 ;
if (p <= l.get( 0 )) {
l.set( 0 , p);
continue ;
}
while (low < high) {
int mid = (low + high + 1 ) / 2 ;
if (p > l.get(mid))
low = mid;
else
high = mid - 1 ;
}
if (low + 1 < M)
l.set(low + 1 , p);
else {
l.add(p);
M++;
}
}
}
return M;
}
public static void main(String[] args)
{
int [] A = { 4 , 20 , 6 , 12 };
System.out.println(
longestSequence(A));
}
}
|
Python3
def isprime(n):
if (n < 2 ):
return False
i = 2
while i * i < = n:
if (n % i = = 0 ):
return False
i + = 2
return True
def nextprime(n):
while ( not isprime(n)):
n + = 1
return n
def prevprime(n):
if (n < 2 ):
return 2
while ( not isprime(n)):
n - = 1
return n
def longestSequence(A):
n = len (A)
M = 1
l = []
l.append(prevprime(A[ 0 ]))
for i in range ( 1 , n):
x = A[i]
for p in [nextprime(x),
prevprime(x)]:
low = 0
high = M - 1
if (p < = l[ 0 ]):
l[ 0 ] = p
continue
while (low < high) :
mid = (low + high + 1 ) / / 2
if (p > l[mid]):
low = mid
else :
high = mid - 1
if (low + 1 < M):
l[low + 1 ] = p
else :
l.append(p)
M + = 1
return M
if __name__ = = "__main__" :
A = [ 4 , 20 , 6 , 12 ]
print (longestSequence(A))
|
C#
using System;
using System.Collections.Generic;
class GFG{
static bool isprime( int n)
{
if (n < 2)
return false ;
for ( int i = 2; i * i <= n; i++)
if (n % i == 0)
return false ;
return true ;
}
static int nextprime( int n)
{
while (!isprime(n))
n++;
return n;
}
static int prevprime( int n)
{
if (n < 2)
return 2;
while (!isprime(n))
n--;
return n;
}
static int longestSequence( int [] A)
{
int n = A.Length;
int M = 1;
List< int > l = new List< int >();
l.Add(prevprime(A[0]));
for ( int i = 1; i < n; i++)
{
int x = A[i];
foreach ( int p in new int [] {nextprime(x),
prevprime(x)})
{
int low = 0;
int high = M - 1;
if (p <= l[0])
{
l[0] = p;
continue ;
}
while (low < high)
{
int mid = (low + high + 1) / 2;
if (p > l[mid])
low = mid;
else
high = mid - 1;
}
if (low + 1 < M)
l[low + 1] = p;
else
{
l.Add(p);
M++;
}
}
}
return M;
}
public static void Main(String[] args)
{
int [] A = {4, 20, 6, 12};
Console.WriteLine(longestSequence(A));
}
}
|
Javascript
<script>
function isprime(n)
{
if (n < 2)
return false ;
for (let i = 2; i * i <= n; i++)
if (n % i == 0)
return false ;
return true ;
}
function nextprime(n)
{
while (!isprime(n))
n++;
return n;
}
function prevprime(n)
{
if (n < 2)
return 2;
while (!isprime(n))
n--;
return n;
}
function longestSequence(A)
{
let n = A.length;
let M = 1;
let l = new Array();
l.push(prevprime(A[0]));
for (let i = 1; i < n; i++)
{
let x = A[i];
for (let p of [nextprime(x), prevprime(x)])
{
let low = 0;
let high = M - 1;
if (p <= l[0])
{
l[0] = p;
continue ;
}
while (low < high)
{
let mid = low + high + 1 / 2;
if (p > l[mid])
low = mid;
else
high = mid - 1;
}
if (low + 1 < M)
l[low + 1] = p;
else
{
l.push(p);
M++;
}
}
}
return M;
}
let A = [ 4, 20, 6, 12 ];
document.write(longestSequence(A));
</script>
|
Time Complexity: O(N×logN)
Auxiliary Space: O(N)
Share your thoughts in the comments
Please Login to comment...