📜  循环找到最长的递增子序列

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

给定一个数组,任务是循环查找LIS(最长递增子序列)。

例子 :

Input : arr[] = {5, 4, 3, 2, 1}
Output : 2
Although there is no LIS in a given array 
but in a circular form there can be
{1, 5}, {2, 5}, ...... 

Input : arr[]= {5, 6, 7, 1, 2, 3}
Output : 6
{1, 2, 3, 5, 6, 7} will be the LIS in the
circular manner.
  1. 给定数组追加相同的元素(即整个数组)。
  2. 对于大小为n(给定数组中的元素数)的每个窗口,执行LIS。
  3. 返回最大长度。
For example : Given array is {1, 4, 6, 2, 3}

After appending elements resultant array
will be {1, 4, 6, 2, 3, 1, 4, 6, 2, 3}.

Now for every consecutive n elements perform LIS.
1- {1, 4, 6, 2, 3} --3 is length of LIS.
2- {4, 6, 2, 3, 1} --2 is length of LIS.
3- {6, 2, 3, 1, 4} --3
4- {2, 3, 1, 4, 6}-- 4 {2, 3, 4, 6}
5- {3, 1, 4, 6, 2} --3.
6- {1, 4, 6, 2, 3} Original list.

So, maximum length of LIS in circular manner is 4. 

与在最后一个窗口中一样,我们将具有与给定数组中相同的元素,而无需再次计算,因此我们可以仅追加n-1个元素以减少操作数量。

C++
// C++ implementation to find LIS in circular way
#include
using namespace std;
  
// Utility function to find LIS using Dynamic programming
int computeLIS(int circBuff[], int start, int end, int n)
{
    int LIS[end-start];
  
    /* Initialize LIS values for all indexes */
    for (int i = start; i < end; i++)
        LIS[i] = 1;
  
    /* Compute optimized LIS values in bottom up manner */
    for (int i = start + 1; i < end; i++)
  
        // Set j on the basis of current window
        // i.e. first element of the current window
        for (int j = start; j < i; j++ )
            if (circBuff[i] > circBuff[j] && LIS[i] < LIS[j] + 1)
                LIS[i] = LIS[j] + 1;
  
    /* Pick maximum of all LIS values */
    int res = INT_MIN;
    for (int i = start; i < end; i++)
        res = max(res, LIS[i]);
  
    return res;
}
  
// Function to find Longest Increasing subsequence in
// Circular manner
int LICS(int arr[], int n)
{
    // Make a copy of given array by appending same
    // array elements  to itself
    int circBuff[2 * n];
    for (int i = 0; i


Java
// Java implementation to find LIS in circular way
  
class Test
{
    // Utility method to find LIS using Dynamic programming
    static int computeLIS(int circBuff[], int start, int end, int n)
    {
        int LIS[] = new int[n+end-start];
       
        /* Initialize LIS values for all indexes */
        for (int i = start; i < end; i++)
            LIS[i] = 1;
       
        /* Compute optimized LIS values in bottom up manner */
        for (int i = start + 1; i < end; i++)
       
            // Set j on the basis of current window
            // i.e. first element of the current window
            for (int j = start; j < i; j++ )
                if (circBuff[i] > circBuff[j] && LIS[i] < LIS[j] + 1)
                    LIS[i] = LIS[j] + 1;
       
        /* Pick maximum of all LIS values */
        int res = Integer.MIN_VALUE;
        for (int i = start; i < end; i++)
            res = Math.max(res, LIS[i]);
       
        return res;
    }
       
    // Function to find Longest Increasing subsequence in
    // Circular manner
    static int LICS(int arr[], int n)
    {
        // Make a copy of given array by appending same
        // array elements  to itself
        int circBuff[] = new int[2 * n];
        for (int i = 0; i


Python3
# Python3 implementation to find 
# LIS in circular way Utility 
# function to find LIS using 
# Dynamic programmi
def computeLIS(circBuff, start, end, n):
    LIS = [0 for i in range(end)]
      
    # Initialize LIS values 
    # for all indexes 
    for i in range(start, end):
        LIS[i] = 1
          
    # Compute optimized LIS values
    # in bottom up manner
    for i in range(start + 1, end):
          
        # Set j on the basis of current 
        # window i.e. first element of
        # the current window 
        for j in range(start,i):
            if (circBuff[i] > circBuff[j] and 
                LIS[i] < LIS[j] + 1):
                LIS[i] = LIS[j] + 1
                  
    # Pick maximum of all LIS values
    res = -100000
    for i in range(start, end):
        res = max(res, LIS[i])
    return res
  
# Function to find Longest Increasing 
# subsequence in Circular manner
def LICS(arr, n):
      
    # Make a copy of given 
    # array by appending same 
    # array elements to itself 
    circBuff = [0 for i in range(2 * n)]
    for i in range(n):
        circBuff[i] = arr[i]
    for i in range(n, 2 * n):
        circBuff[i] = arr[i - n]
          
    # Perform LIS for each
    # window of size n 
    res = -100000
    for i in range(n):
        res = max(computeLIS(circBuff, i, 
                             i + n, n), res)
    return res
  
# Driver code
arr = [ 1, 4, 6, 2, 3 ]
n = len(arr)
print("Length of LICS is", LICS(arr, n))
  
# This code is contributed 
# by sahilshelangia


C#
// C# implementation to find 
// LIS in circular way
using System;
  
class Test
{
    // Utility method to find LIS
    // using Dynamic programming
    static int computeLIS(int []circBuff, int start, 
                                     int end, int n)
    {
        int []LIS = new int[n+end-start];
      
        /* Initialize LIS values for all indexes */
        for (int i = start; i < end; i++)
            LIS[i] = 1;
      
        /* Compute optimized LIS values 
           in bottom up manner */
        for (int i = start + 1; i < end; i++)
      
            // Set j on the basis of current window
            // i.e. first element of the current window
            for (int j = start; j < i; j++ )
                if (circBuff[i] > circBuff[j] && 
                            LIS[i] < LIS[j] + 1)
                    LIS[i] = LIS[j] + 1;
      
        /* Pick maximum of all LIS values */
        int res = int.MinValue;
        for (int i = start; i < end; i++)
            res = Math.Max(res, LIS[i]);
      
        return res;
    }
      
    // Function to find Longest Increasing 
    // subsequence in Circular manner
    static int LICS(int []arr, int n)
    {
        // Make a copy of given array by 
        // appending same array elements to itself
        int []circBuff = new int[2 * n];
          
        for (int i = 0; i


PHP
 $circBuff[$j] && 
                     $LIS[$i] < $LIS[$j] + 1)
                $LIS[$i] = $LIS[$j] + 1;
  
    /* Pick maximum of
    all LIS values */
    $res = PHP_INT_MIN;
    for ($i = $start; $i < $end; $i++)
        $res = max($res, $LIS[$i]);
  
    return $res;
}
  
// Function to find LIS 
// in Circular manner
function LICS($arr, $n)
{
    // Make a copy of given array
    // by appending same array
    // elements to itself
    for ($i = 0; $i < $n; $i++)
        $circBuff[$i] = $arr[$i];
    for ($i = $n; $i < 2 * $n; $i++)
        $circBuff[$i] = $arr[$i - $n];
  
    // Perform LIS for each 
    // window of size n
    $res = PHP_INT_MIN;
    for ($i = 0; $i < $n; $i++)
        $res = max(computeLIS($circBuff, $i, 
                              $i + $n, $n), 
                              $res);
  
    return $res;
}
  
// Driver Code
$arr = array(1, 4, 6, 2, 3);
$n = sizeof($arr);
  
echo "Length of LICS is " , 
            LICS($arr, $n);
      
// This code is contributed by aj_36
?>


输出 :

Length of LICS is 4

上述解决方案的时间复杂度为O(n 3 )。可以使用O(n Log n)算法将其减少O(n 2 Log n)以找到LIS。

参考 :
https://www.careercup.com/question?id=5942735794077696