给定一个数组,任务是循环查找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.
- 给定数组追加相同的元素(即整个数组)。
- 对于大小为n(给定数组中的元素数)的每个窗口,执行LIS。
- 返回最大长度。
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