В моем предыдущем посте я подробно объяснил проблему увеличения длины подпоследовательности (LIS). Тем не менее, публикация покрывала только код, связанный с запросом размера LIS, но не конструкцию LIS. Я оставил это как упражнение. Если вы решили, ура. Если нет, вы не одиноки, вот код.
Если вы еще не читали мой предыдущий пост, читайте здесь . Обратите внимание, что приведенный ниже код печатает LIS в обратном порядке. Мы можем изменить порядок печати, используя стек (явный или системный стек). Я оставляю объяснение как упражнение (легко).
C ++
#include <bits/stdc++.h>
using namespace std;
int GetCeilIndex( int arr[], vector< int >& T, int l, int r,
int key)
{
while (r - l > 1) {
int m = l + (r - l) / 2;
if (arr[T[m]] >= key)
r = m;
else
l = m;
}
return r;
}
int LongestIncreasingSubsequence( int arr[], int n)
{
vector< int > tailIndices(n, 0);
vector< int > prevIndices(n, -1);
int len = 1;
for ( int i = 1; i < n; i++) {
if (arr[i] < arr[tailIndices[0]]) {
tailIndices[0] = i;
}
else if (arr[i] > arr[tailIndices[len - 1]]) {
prevIndices[i] = tailIndices[len - 1];
tailIndices[len++] = i;
}
else {
int pos = GetCeilIndex(arr, tailIndices, -1,
len - 1, arr[i]);
prevIndices[i] = tailIndices[pos - 1];
tailIndices[pos] = i;
}
}
cout << "LIS of given input" << endl;
for ( int i = tailIndices[len - 1]; i >= 0; i = prevIndices[i])
cout << arr[i] << " " ;
cout << endl;
return len;
}
int main()
{
int arr[] = { 2, 5, 3, 7, 11, 8, 10, 13, 6 };
int n = sizeof (arr) / sizeof (arr[0]);
printf ( "LIS size %d\n" , LongestIncreasingSubsequence(arr, n));
return 0;
}
|
Джава
import java.util.Arrays;
class GFG {
static int GetCeilIndex( int arr[],
int T[], int l,
int r, int key)
{
while (r - l > 1 ) {
int m = l + (r - l) / 2 ;
if (arr[T[m]] >= key)
r = m;
else
l = m;
}
return r;
}
static int LongestIncreasingSubsequence(
int arr[], int n)
{
int tailIndices[] = new int [n];
Arrays.fill(tailIndices, 0 );
int prevIndices[] = new int [n];
Arrays.fill(prevIndices, - 1 );
int len = 1 ;
for ( int i = 1 ; i < n; i++) {
if (arr[i] < arr[tailIndices[ 0 ]])
tailIndices[ 0 ] = i;
else if (arr[i] > arr[tailIndices[len - 1 ]]) {
prevIndices[i] = tailIndices[len - 1 ];
tailIndices[len++] = i;
}
else {
int pos = GetCeilIndex(arr,
tailIndices, - 1 , len - 1 , arr[i]);
prevIndices[i] = tailIndices[pos - 1 ];
tailIndices[pos] = i;
}
}
System.out.println( "LIS of given input" );
for ( int i = tailIndices[len - 1 ]; i >= 0 ;
i = prevIndices[i])
System.out.print(arr[i] + " " );
System.out.println();
return len;
}
public static void main(String[] args)
{
int arr[] = { 2 , 5 , 3 , 7 , 11 , 8 , 10 , 13 , 6 };
int n = arr.length;
System.out.print( "LIS size\n" + LongestIncreasingSubsequence(arr, n));
}
}
|
python3
def GetCeilIndex(arr, T, l, r, key):
while (r - l > 1 ):
m = l + (r - l) / / 2
if (arr[T[m]] > = key):
r = m
else :
l = m
return r
def LongestIncreasingSubsequence(arr, n):
tailIndices = [ 0 for i in range (n + 1 )]
prevIndices = [ - 1 for i in range (n + 1 )]
len = 1
for i in range ( 1 , n):
if (arr[i] < arr[tailIndices[ 0 ]]):
tailIndices[ 0 ] = i
elif (arr[i] > arr[tailIndices[ len - 1 ]]):
prevIndices[i] = tailIndices[ len - 1 ]
tailIndices[ len ] = i
len + = 1
else :
pos = GetCeilIndex(arr, tailIndices, - 1 ,
len - 1 , arr[i])
prevIndices[i] = tailIndices[pos - 1 ]
tailIndices[pos] = i
print ( "LIS of given input" )
i = tailIndices[ len - 1 ]
while (i > = 0 ):
print (arr[i], " " , end = "")
i = prevIndices[i]
print ()
return len
arr = [ 2 , 5 , 3 , 7 , 11 , 8 , 10 , 13 , 6 ]
n = len (arr)
print ( "LIS size\n" , LongestIncreasingSubsequence(arr, n))
|
C #
using System;
class GFG {
static int GetCeilIndex( int [] arr, int [] T, int l,
int r, int key)
{
while (r - l > 1) {
int m = l + (r - l) / 2;
if (arr[T[m]] >= key)
r = m;
else
l = m;
}
return r;
}
static int LongestIncreasingSubsequence(
int [] arr, int n)
{
int [] tailIndices = new int [n];
for ( int i = 0; i < n; i++)
tailIndices[i] = 0;
int [] prevIndices = new int [n];
for ( int i = 0; i < n; i++)
prevIndices[i] = -1;
int len = 1;
for ( int i = 1; i < n; i++) {
if (arr[i] < arr[tailIndices[0]])
tailIndices[0] = i;
else if (arr[i] > arr[tailIndices[len - 1]]) {
prevIndices[i] = tailIndices[len - 1];
tailIndices[len++] = i;
}
else {
int pos = GetCeilIndex(arr,
tailIndices, -1, len - 1, arr[i]);
prevIndices[i] = tailIndices[pos - 1];
tailIndices[pos] = i;
}
}
Console.Write( "LIS of given input" );
for ( int i = tailIndices[len - 1]; i >= 0;
i = prevIndices[i])
Console.Write(arr[i] + " " );
Console.WriteLine();
return len;
}
public static void Main()
{
int [] arr = { 2, 5, 3, 7, 11, 8, 10, 13, 6 };
int n = arr.Length;
Console.Write( "LIS size\n" + LongestIncreasingSubsequence(arr, n));
}
}
|
PHP
<?php
function GetCeilIndex( $arr , $T , $l , $r , $key )
{
while ( $r - $l > 1)
{
$m = (int)( $l + ( $r - $l )/2);
if ( $arr [ $T [ $m ]] >= $key )
$r = $m ;
else
$l = $m ;
}
return $r ;
}
function LongestIncreasingSubsequence( $arr , $n )
{
$tailIndices = array_fill (0, $n +1, 0);
$prevIndices = array_fill (0, $n +1, -1);
$len = 1;
for ( $i = 1; $i < $n ; $i ++)
{
if ( $arr [ $i ] < $arr [ $tailIndices [0]])
{
$tailIndices [0] = $i ;
}
else if ( $arr [ $i ] > $arr [ $tailIndices [ $len -1]])
{
$prevIndices [ $i ] = $tailIndices [ $len -1];
$tailIndices [ $len ++] = $i ;
}
else
{
$pos = GetCeilIndex( $arr , $tailIndices , -1,
$len -1, $arr [ $i ]);
$prevIndices [ $i ] = $tailIndices [ $pos -1];
$tailIndices [ $pos ] = $i ;
}
}
echo "LIS of given input\n" ;
for ( $i = $tailIndices [ $len -1]; $i >= 0; $i = $prevIndices [ $i ])
echo $arr [ $i ]. " " ;
echo "\n" ;
return $len ;
}
$arr = array ( 2, 5, 3, 7, 11, 8, 10, 13, 6 );
$n = count ( $arr );
print ( "LIS size " .LongestIncreasingSubsequence( $arr , $n ));
?>
|
Выход:
LIS of given input
13 10 8 7 3 2
LIS size 6
Упражнения:
1. Вы знаете алгоритм Кадане , чтобы найти подмассив с максимальной суммой . Измените алгоритм Кадане для отслеживания начального и конечного местоположения подмассива максимальной суммы.
2. Измените алгоритм Кадане , чтобы найти подмассив с максимальной суммой в круговом массиве. Обратитесь на форум GFG за множеством комментариев по этому вопросу.
3. Даны два целых числа A и B в качестве входных данных. Найдите число чисел Фибоначчи, существующих между этими двумя числами (включая A и B). Например, A = 3 и B = 18, между {3, 5, 8, 13} есть 4 числа Фибоначчи. Сделайте это за время O (log K), где K max (A, B). Каково ваше наблюдение?
— Венки . Пожалуйста, пишите комментарии, если вы обнаружите что-то неправильное или вы хотите поделиться дополнительной информацией по обсуждаемой выше теме.
Рекомендуемые посты:
Построение самой длинной возрастающей подпоследовательности (N log N)
0.00 (0%) 0 votes