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

📅  最后修改于: 2021-09-17 16:07:06             🧑  作者: 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
?>


Javascript


输出 :

Length of LICS is 4

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程