给定长度为N的数组arr [] ,该数组由正整数组成,任务是找到可以由数组任一端的元素形成的最长的递增子序列。
例子 :
Input: N=4 arr[] ={ 1, 4, 2, 3 }
Output: 1 3 4
Explanation:
Append arr[0] to the sequence. Sequence = {1}. Array = {4, 2, 3}.
Append arr[2] to the sequence. Sequence = {1, 3}. Array = {4, 2}.
Append arr[0] to the sequence. Sequence = {1, 3, 4}. Array = {2}.
Therefore, {1, 3, 4} is the longest increasing sequence possible from the given array.
Input: N=3 arr[] ={ 4, 1, 3 }
Output: 3 4
方法:解决此问题的想法是使用两个指针方法。在严格增加的顺序中,为最右边的元素维护一个变量,例如rightmost_element 。在数组的末尾保留两个指针,分别说i和j,并执行以下步骤,直到i超过j或两端的元素都小于rightmost_element为止:
- 如果arr [i]> arr [j]:
- 如果arr [j]> rightmost_element:设置rightmost_element = arr [j]并递减j 。将arr [j]添加到序列中。
- 如果arr [i]> rightmost_element:设置rightmost_element = arr [i]并递增i 。将arr [i]添加到序列中。
- 如果arr [i]
- 如果arr [i]> rightmost_element :设置rightmost_element = arr [i]并递增i 。将arr [i]添加到序列中。
- 如果arr [j]> rightmost_element :设置rightmost_element = arr [j]并递减j 。将arr [j]添加到序列中。
- 如果arr [j] = arr [i]:
- 如果i = j:
- 如果arr [i]> rightmost_element :将arr [i]添加到序列中。
- 否则:分别检查可从两端添加的最大元素,将它们分别设为max_left和max_right 。
- 如果max_left> max_right :添加可以从左端添加的所有元素。
- 否则:添加可以从右侧添加的所有元素。
- 如果i = j:
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
#include
using namespace std;
// Function to find longest strictly
// increasing sequence using boundary elements
void findMaxLengthSequence(int N, int arr[4])
{
// Maintains rightmost element
// in the sequence
int rightmost_element = -1;
// Pointer to start of array
int i = 0;
// Pointer to end of array
int j = N - 1;
// Stores the required sequence
vector sequence;
// Traverse the array
while (i <= j) {
// If arr[i]>arr[j]
if (arr[i] > arr[j]) {
// If arr[j] is greater than
// rightmost element of the sequence
if (arr[j] > rightmost_element) {
// Push arr[j] into the sequence
sequence.push_back(arr[j]);
// Update rightmost element
rightmost_element = arr[j];
j--;
}
else if (arr[i] > rightmost_element) {
// Push arr[i] into the sequence
sequence.push_back(arr[i]);
// Update rightmost element
rightmost_element = arr[i];
i++;
}
else
break;
}
// If arr[i] < arr[j]
else if (arr[i] < arr[j]) {
// If arr[i] > rightmost element
if (arr[i] > rightmost_element) {
// Push arr[i] into the sequence
sequence.push_back(arr[i]);
// Update rightmost element
rightmost_element = arr[i];
i++;
}
// If arr[j] > rightmost element
else if (arr[j] > rightmost_element) {
// Push arr[j] into the sequence
sequence.push_back(arr[j]);
// Update rightmost element
rightmost_element = arr[j];
j--;
}
else
break;
}
// If arr[i] is equal to arr[j]
else if (arr[i] == arr[j]) {
// If i and j are at the same element
if (i == j) {
// If arr[i] > rightmostelement
if (arr[i] > rightmost_element) {
// Push arr[j] into the sequence
sequence.push_back(arr[i]);
// Update rightmost element
rightmost_element = arr[i];
i++;
}
break;
}
else {
sequence.push_back(arr[i]);
// Traverse array
// from left to right
int k = i + 1;
// Stores the increasing
// sequence from the left end
vector max_left;
// Traverse array from left to right
while (k < j && arr[k] > arr[k - 1]) {
// Push arr[k] to max_left vector
max_left.push_back(arr[k]);
k++;
}
// Traverse the array
// from right to left
int l = j - 1;
// Stores the increasing
// sequence from the right end
vector max_right;
// Traverse array from right to left
while (l > i && arr[l] > arr[l + 1]) {
// Push arr[k] to max_right vector
max_right.push_back(arr[l]);
l--;
}
// If size of max_left is greater
// than max_right
if (max_left.size() > max_right.size())
for (int element : max_left)
// Push max_left elements to
// the original sequence
sequence.push_back(element);
// Otherwise
else
for (int element : max_right)
// Push max_right elements to
// the original sequence
sequence.push_back(element);
break;
}
}
}
// Print the sequence
for (int element : sequence)
printf("%d ", element);
}
// Driver Code
int main()
{
int N = 4;
int arr[] = { 1, 3, 2, 1 };
// Print the longest increasing
// sequence using boundary elements
findMaxLengthSequence(N, arr);
}
Java
// Java program for the above approach
import java.util.*;
class GFG{
// Function to find longest strictly
// increasing sequence using boundary elements
static void findMaxLengthSequence(int N, int[] arr)
{
// Maintains rightmost element
// in the sequence
int rightmost_element = -1;
// Pointer to start of array
int i = 0;
// Pointer to end of array
int j = N - 1;
// Stores the required sequence
Vector sequence = new Vector();
// Traverse the array
while (i <= j)
{
// If arr[i]>arr[j]
if (arr[i] > arr[j])
{
// If arr[j] is greater than
// rightmost element of the sequence
if (arr[j] > rightmost_element)
{
// Push arr[j] into the sequence
sequence.add(arr[j]);
// Update rightmost element
rightmost_element = arr[j];
j--;
}
else if (arr[i] > rightmost_element)
{
// Push arr[i] into the sequence
sequence.add(arr[i]);
// Update rightmost element
rightmost_element = arr[i];
i++;
}
else
break;
}
// If arr[i] < arr[j]
else if (arr[i] < arr[j])
{
// If arr[i] > rightmost element
if (arr[i] > rightmost_element)
{
// Push arr[i] into the sequence
sequence.add(arr[i]);
// Update rightmost element
rightmost_element = arr[i];
i++;
}
// If arr[j] > rightmost element
else if (arr[j] > rightmost_element)
{
// Push arr[j] into the sequence
sequence.add(arr[j]);
// Update rightmost element
rightmost_element = arr[j];
j--;
}
else
break;
}
// If arr[i] is equal to arr[j]
else if (arr[i] == arr[j])
{
// If i and j are at the same element
if (i == j)
{
// If arr[i] > rightmostelement
if (arr[i] > rightmost_element)
{
// Push arr[j] into the sequence
sequence.add(arr[i]);
// Update rightmost element
rightmost_element = arr[i];
i++;
}
break;
}
else
{
sequence.add(arr[i]);
// Traverse array
// from left to right
int k = i + 1;
// Stores the increasing
// sequence from the left end
Vector max_left = new Vector();
// Traverse array from left to right
while (k < j && arr[k] > arr[k - 1])
{
// Push arr[k] to max_left vector
max_left.add(arr[k]);
k++;
}
// Traverse the array
// from right to left
int l = j - 1;
// Stores the increasing
// sequence from the right end
Vector max_right = new Vector();
// Traverse array from right to left
while (l > i && arr[l] > arr[l + 1])
{
// Push arr[k] to max_right vector
max_right.add(arr[l]);
l--;
}
// If size of max_left is greater
// than max_right
if (max_left.size() > max_right.size())
for(int element : max_left)
// Push max_left elements to
// the original sequence
sequence.add(element);
// Otherwise
else
for(int element : max_right)
// Push max_right elements to
// the original sequence
sequence.add(element);
break;
}
}
}
// Print the sequence
for(int element : sequence)
System.out.print(element + " ");
}
// Driver Code
public static void main(String[] args)
{
int N = 4;
int[] arr = { 1, 3, 2, 1 };
// Print the longest increasing
// sequence using boundary elements
findMaxLengthSequence(N, arr);
}
}
// This code is contributed by divyeshrabadiya07
Python3
# Python3 program for the above approach
# Function to find longest strictly
# increasing sequence using boundary elements
def findMaxLengthSequence(N, arr):
# Maintains rightmost element
# in the sequence
rightmost_element = -1
# Pointer to start of array
i = 0
# Pointer to end of array
j = N - 1
# Stores the required sequence
sequence = []
# Traverse the array
while (i <= j):
# If arr[i]>arr[j]
if (arr[i] > arr[j]):
# If arr[j] is greater than
# rightmost element of the sequence
if (arr[j] > rightmost_element):
# Push arr[j] into the sequence
sequence.append(arr[j])
# Update rightmost element
rightmost_element = arr[j]
j -= 1
elif (arr[i] > rightmost_element):
# Push arr[i] into the sequence
sequence.append(arr[i])
# Update rightmost element
rightmost_element = arr[i]
i += 1
else:
break
# If arr[i] < arr[j]
elif (arr[i] < arr[j]):
# If arr[i] > rightmost element
if (arr[i] > rightmost_element):
# Push arr[i] into the sequence
sequence.append(arr[i])
# Update rightmost element
rightmost_element = arr[i]
i += 1
# If arr[j] > rightmost element
elif (arr[j] > rightmost_element):
# Push arr[j] into the sequence
sequence.append(arr[j])
# Update rightmost element
rightmost_element = arr[j]
j -= 1
else:
break
# If arr[i] is equal to arr[j]
elif (arr[i] == arr[j]):
# If i and j are at the same element
if (i == j):
# If arr[i] > rightmostelement
if (arr[i] > rightmost_element):
# Push arr[j] into the sequence
sequence.append(arr[i])
# Update rightmost element
rightmost_element = arr[i]
i += 1
break
else:
sequence.append(arr[i])
# Traverse array
# from left to right
k = i + 1
# Stores the increasing
# sequence from the left end
max_left = []
# Traverse array from left to right
while (k < j and arr[k] > arr[k - 1]):
# Push arr[k] to max_left vector
max_left.append(arr[k])
k += 1
# Traverse the array
# from right to left
l = j - 1
# Stores the increasing
# sequence from the right end
max_right = []
# Traverse array from right to left
while (l > i and arr[l] > arr[l + 1]):
# Push arr[k] to max_right vector
max_right.append(arr[l])
l -= 1
# If size of max_left is greater
# than max_right
if (len(max_left) > len(max_right)):
for element in max_left:
# Push max_left elements to
# the original sequence
sequence.append(element)
# Otherwise
else:
for element in max_right:
# Push max_right elements to
# the original sequence
sequence.append(element)
break
# Print the sequence
for element in sequence:
print(element, end = " ")
# Driver Code
if __name__ == '__main__':
N = 4
arr = [ 1, 3, 2, 1 ]
# Print the longest increasing
# sequence using boundary elements
findMaxLengthSequence(N, arr)
# This code is contributed by mohit kumar 29
C#
// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG
{
// Function to find longest strictly
// increasing sequence using boundary elements
static void findMaxLengthSequence(int N, int[] arr)
{
// Maintains rightmost element
// in the sequence
int rightmost_element = -1;
// Pointer to start of array
int i = 0;
// Pointer to end of array
int j = N - 1;
// Stores the required sequence
List sequence = new List();
// Traverse the array
while (i <= j) {
// If arr[i]>arr[j]
if (arr[i] > arr[j]) {
// If arr[j] is greater than
// rightmost element of the sequence
if (arr[j] > rightmost_element) {
// Push arr[j] into the sequence
sequence.Add(arr[j]);
// Update rightmost element
rightmost_element = arr[j];
j--;
}
else if (arr[i] > rightmost_element) {
// Push arr[i] into the sequence
sequence.Add(arr[i]);
// Update rightmost element
rightmost_element = arr[i];
i++;
}
else
break;
}
// If arr[i] < arr[j]
else if (arr[i] < arr[j]) {
// If arr[i] > rightmost element
if (arr[i] > rightmost_element) {
// Push arr[i] into the sequence
sequence.Add(arr[i]);
// Update rightmost element
rightmost_element = arr[i];
i++;
}
// If arr[j] > rightmost element
else if (arr[j] > rightmost_element) {
// Push arr[j] into the sequence
sequence.Add(arr[j]);
// Update rightmost element
rightmost_element = arr[j];
j--;
}
else
break;
}
// If arr[i] is equal to arr[j]
else if (arr[i] == arr[j]) {
// If i and j are at the same element
if (i == j) {
// If arr[i] > rightmostelement
if (arr[i] > rightmost_element) {
// Push arr[j] into the sequence
sequence.Add(arr[i]);
// Update rightmost element
rightmost_element = arr[i];
i++;
}
break;
}
else {
sequence.Add(arr[i]);
// Traverse array
// from left to right
int k = i + 1;
// Stores the increasing
// sequence from the left end
List max_left = new List();
// Traverse array from left to right
while (k < j && arr[k] > arr[k - 1])
{
// Push arr[k] to max_left vector
max_left.Add(arr[k]);
k++;
}
// Traverse the array
// from right to left
int l = j - 1;
// Stores the increasing
// sequence from the right end
List max_right = new List();
// Traverse array from right to left
while (l > i && arr[l] > arr[l + 1])
{
// Push arr[k] to max_right vector
max_right.Add(arr[l]);
l--;
}
// If size of max_left is greater
// than max_right
if (max_left.Count > max_right.Count)
foreach(int element in max_left)
// Push max_left elements to
// the original sequence
sequence.Add(element);
// Otherwise
else
foreach(int element in max_right)
// Push max_right elements to
// the original sequence
sequence.Add(element);
break;
}
}
}
// Print the sequence
foreach(int element in sequence)
Console.Write(element + " ");
}
// Driver code
static void Main()
{
int N = 4;
int[] arr = { 1, 3, 2, 1 };
// Print the longest increasing
// sequence using boundary elements
findMaxLengthSequence(N, arr);
}
}
// This code is contribute by divyesh072019
输出:
1 2 3
时间复杂度: O(N)
辅助空间: O(1)