📜  数组的边界元素可能导致的最长递增序列

📅  最后修改于: 2021-04-21 23:23:27             🧑  作者: Mango

给定长度为N的数组arr [] ,该数组由正整数组成任务是找到可以由数组任一端的元素形成的最长的递增子序列。

例子 :

方法:解决此问题的想法是使用两个指针方法。在严格增加的顺序中为最右边的元素维护一个变量,例如rightmost_element 。在数组的末尾保留两个指针,分别说ij,并执行以下步骤,直到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_leftmax_right
      • 如果max_left> max_right :添加可以从左端添加的所有元素。
      • 否则:添加可以从右侧添加的所有元素。

下面是上述方法的实现:

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)