给定两个数组,我们需要找到最长的双调序列,使得增加的部分必须来自第一个数组,并且应该是第一个数组的子序列。同样, 的减少部分必须来自第二个数组,并且应该是它的子序列。
例子:
Input : arr1[] = {1, 5, 2, 4, 3, 5},
arr2[] = {8, 6, 4, 7, 3, 2}
Output : 1, 2, 4, 5, 8, 6, 4, 3, 2
Input : arr1[] = {2, 0, 1, 3, 4},
arr2[] = {5, 3, 2, 1}
Output : 0, 1, 2, 3, 4, 5, 3, 2, 1
这个想法是使用来自 array1 的最大递增序列和来自 array2 的最大递减序列,然后将两者结合起来得到我们的结果。
C++
// CPP to find largest bitonic sequence such that
#include
using namespace std;
vector res;
// utility Binary search
int GetCeilIndex(int arr[], vector& 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;
}
// function to find LIS in reverse form
void LIS(int arr[], int n)
{
// Add boundary case, when array n is zero
// Depend on smart pointers
vector tailIndices(n, 0); // Initialized with 0
vector prevIndices(n, -1); // initialized with -1
int len = 1; // it will always point to empty location
for (int i = 1; i < n; i++) {
// new smallest value
if (arr[i] < arr[tailIndices[0]])
tailIndices[0] = i;
// arr[i] wants to extend largest subsequence
else if (arr[i] > arr[tailIndices[len - 1]]) {
prevIndices[i] = tailIndices[len - 1];
tailIndices[len++] = i;
}
// arr[i] wants to be a potential candidate of
// future subsequence
// It will replace ceil value in tailIndices
else {
int pos = GetCeilIndex(arr, tailIndices, -1,
len - 1, arr[i]);
prevIndices[i] = tailIndices[pos - 1];
tailIndices[pos] = i;
}
}
// put LIS into vector
for (int i = tailIndices[len - 1]; i >= 0; i = prevIndices[i])
res.push_back(arr[i]);
}
// function for finding longest bitonic seq
void longestBitonic(int arr1[], int n1, int arr2[], int n2)
{
// find LIS of array 1 in reverse form
LIS(arr1, n1);
// reverse res to get LIS of first array
reverse(res.begin(), res.end());
// reverse array2 and find its LIS
reverse(arr2, arr2 + n2);
LIS(arr2, n2);
// print result
for (int i = 0; i < res.size(); i++)
cout << res[i] << " ";
}
// driver preogram
int main()
{
int arr1[] = { 1, 2, 4, 3, 2 };
int arr2[] = { 8, 6, 4, 7, 8, 9 };
int n1 = sizeof(arr1) / sizeof(arr1[0]);
int n2 = sizeof(arr2) / sizeof(arr2[0]);
longestBitonic(arr1, n1, arr2, n2);
return 0;
}
Java
// Java to find largest bitonic sequence such that
import java.util.*;
class GFG
{
static Vector res = new Vector<>();
// utility Binary search
static Integer GetCeilIndex(Integer[] arr, Integer[] T,
Integer l, Integer r, Integer key)
{
while (r - l > 1)
{
Integer m = l + (r - l) / 2;
if (arr[T[m]] >= key)
r = m;
else
l = m;
}
return r;
}
// function to find LIS in reverse form
static void LIS(Integer[] arr, Integer n)
{
// Add boundary case, when array n is zero
// Depend on smart pointers
Integer[] tailIndices = new Integer[n];
Integer[] prevIndices = new Integer[n];
Arrays.fill(tailIndices, 0); // Initialized with 0
Arrays.fill(prevIndices, -1); // initialized with -1
Integer len = 1; // it will always point to empty location
for (Integer i = 1; i < n; i++)
{
// new smallest value
if (arr[i] < arr[tailIndices[0]])
tailIndices[0] = i;
// arr[i] wants to extend largest subsequence
else if (arr[i] > arr[tailIndices[len - 1]])
{
prevIndices[i] = tailIndices[len - 1];
tailIndices[len++] = i;
}
// arr[i] wants to be a potential candidate of
// future subsequence
// It will replace ceil value in tailIndices
else
{
Integer pos = GetCeilIndex(arr,
tailIndices, -1, len - 1, arr[i]);
prevIndices[i] = tailIndices[pos - 1];
tailIndices[pos] = i;
}
}
// put LIS into vector
for (Integer i = tailIndices[len - 1]; i >= 0; i = prevIndices[i])
res.add(arr[i]);
}
// function for finding longest bitonic seq
static void longestBitonic(Integer[] arr1, Integer n1,
Integer[] arr2, Integer n2)
{
// find LIS of array 1 in reverse form
LIS(arr1, n1);
// reverse res to get LIS of first array
Collections.reverse(res);
// reverse array2 and find its LIS
Collections.reverse(Arrays.asList(arr2));
LIS(arr2, n2);
// print result
for (Integer i = 0; i < res.size(); i++)
System.out.print(res.elementAt(i) + " ");
}
// Driver Code
public static void main(String[] args)
{
Integer[] arr1 = { 1, 2, 4, 3, 2 };
Integer[] arr2 = { 8, 6, 4, 7, 8, 9 };
Integer n1 = arr1.length;
Integer n2 = arr2.length;
longestBitonic(arr1, n1, arr2, n2);
}
}
// This code is contributed by
// sanjeev2552
Python3
# Python3 to find largest bitonic sequence such that
res = []
# utility Binary search
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
# function to find LIS in reverse form
def LIS(arr, n):
# Add boundary case, when array n is zero
# Depend on smart pointers
tailIndices = [0]*(n) #Initialized with 0
prevIndices = [-1]*(n) #initialized with -1
leN = 1 # it will always poto empty location
for i in range(1, n):
# new smallest value
if (arr[i] < arr[tailIndices[0]]):
tailIndices[0] = i
# arr[i] wants to extend largest subsequence
elif (arr[i] > arr[tailIndices[leN - 1]]):
prevIndices[i] = tailIndices[leN - 1]
tailIndices[leN] = i
leN += 1
# arr[i] wants to be a potential candidate of
# future subsequence
# It will replace ceil value in tailIndices
else:
pos = GetCeilIndex(arr, tailIndices, -1,
leN - 1, arr[i])
prevIndices[i] = tailIndices[pos - 1]
tailIndices[pos] = i
# put LIS into vector
i = tailIndices[leN - 1]
while(i >= 0):
# print(i)
res.append(arr[i])
i = prevIndices[i]
# function for finding longest bitonic seq
def longestBitonic(arr1, n1, arr2, n2):
global res
# find LIS of array 1 in reverse form
LIS(arr1, n1)
# reverse res to get LIS of first array
res = res[::-1]
# reverse array2 and find its LIS
arr2 = arr2[::-1]
LIS(arr2, n2)
# print result
for i in res:
print(i,end=" ")
# Driver program
arr1 = [1, 2, 4, 3, 2]
arr2 = [8, 6, 4, 7, 8, 9]
n1 = len(arr1)
n2 = len(arr2)
longestBitonic(arr1, n1, arr2, n2);
# This code is contributed by mohit kumar 29
C#
// C# to find largest bitonic
// sequence
using System;
using System.Collections.Generic;
class GFG{
static List res = new List();
// Reverse array
static int[] reverse(int []a)
{
int i, n = a.Length, t;
for (i = 0; i < n / 2; i++)
{
t = a[i];
a[i] = a[n - i - 1];
a[n - i - 1] = t;
}
return a;
}
// Utility Binary search
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;
}
// Function to find LIS in reverse form
static void LIS(int[] arr, int n)
{
// Add boundary case,
// when array n is zero
// Depend on smart pointers
int[] tailIndices = new int[n];
int[] prevIndices = new int[n];
for(int i = 0; i < n; i++)
{
tailIndices[i] = 0;
prevIndices[i] = -1;
}
int len = 1;
// It will always point
// to empty location
for (int i = 1; i < n; i++)
{
// New smallest value
if (arr[i] < arr[tailIndices[0]])
tailIndices[0] = i;
// arr[i] wants to extend
// largest subsequence
else if (arr[i] > arr[tailIndices[len - 1]])
{
prevIndices[i] = tailIndices[len - 1];
tailIndices[len++] = i;
}
// arr[i] wants to be
// a potential candidate of
// future subsequence
// It will replace ceil
// value in tailIndices
else
{
int pos = GetCeilIndex(arr, tailIndices,
-1, len - 1, arr[i]);
prevIndices[i] = tailIndices[pos - 1];
tailIndices[pos] = i;
}
}
// Put LIS into vector
for (int i = tailIndices[len - 1];
i >= 0; i = prevIndices[i])
res.Add(arr[i]);
}
// Function for finding longest bitonic seq
static void longestBitonic(int[] arr1, int n1,
int[] arr2, int n2)
{
// Find LIS of array 1
// in reverse form
LIS(arr1, n1);
// Reverse res to get
// LIS of first array
res.Reverse();
// Reverse array2 and
// find its LIS
arr2 = reverse(arr2);
LIS(arr2, n2);
// Print result
for (int i = 0; i < res.Count; i++)
Console.Write(res[i] + " ");
}
// Driver Code
public static void Main(String[] args)
{
int[] arr1 = {1, 2, 4, 3, 2};
int[] arr2 = {8, 6, 4, 7, 8, 9};
int n1 = arr1.Length;
int n2 = arr2.Length;
longestBitonic(arr1, n1, arr2, n2);
}
}
// This code is contributed by gauravrajput1
Javascript
输出:
1 2 3 8 6 4
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。