给定一个由N 个整数组成的数组arr[] ,任务是找到最长子序列的长度,使得该子序列的相邻元素至少有一个公共数字。
例子:
Input: arr[] = {1, 12, 44, 29, 33, 96, 89}
Output: 5
The longest sub-sequence is {1 12 29 96 89}
Input: arr[] = {12, 23, 45, 43, 36, 97}
Output: 4
The longest sub-sequence is {12 23 43 36}
方法:这个想法是为数组元素中存在的每个数字存储最长子序列的长度。
- 如果数字 d 是公共数字,dp[i][d] 表示到第 i 个元素的最长子序列的长度。
- 声明一个 cnt 数组并为当前元素中存在的每个数字设置 cnt[d] = 1。
- 将每个数字 d 视为公共数字,并找到以 arr[i] 结尾的最大长度子序列为 dp[i][d] = max(dp[j][d]+1) (0<=j
- 还要找到当前元素的局部最大值 max(dp[i][d])。
- 在找到局部最大值后,将当前元素中存在的所有数字的 dp[i][d] 更新为局部最大值。
- 这是必需的,因为局部最大值表示具有数字 d 的元素的最大长度子序列。
E.g. Consider arr[] = {24, 49, 96}.
The local maximum for 49 is 2 obtain from digit 4.
This local maximum will be used in finding the local maximum for 96 with common digit 9.
For that it is required for all digits in 49, dp[i][d] should be set to local maximum.
下面是上述方法的实现:
C++
// C++ program to find maximum length subsequence
// such that adjacent elements have at least
// one common digit
#include
using namespace std;
// Returns length of maximum length subsequence
int findSubsequence(int arr[], int n)
{
// To store the length of the
// maximum length subsequence
int len = 1;
// To store current element arr[i]
int tmp;
int i, j, d;
// To store the length of the sub-sequence
// ending at index i and having common digit d
int dp[n][10];
memset(dp, 0, sizeof(dp));
// To store digits present in current element
int cnt[10];
// To store length of maximum length subsequence
// ending at index i
int locMax;
// For first element maximum length is 1 for
// each digit
tmp = arr[0];
while (tmp > 0) {
dp[0][tmp % 10] = 1;
tmp /= 10;
}
// Find digits of each element, then find length
// of subsequence for each digit and then find
// local maximum
for (i = 1; i < n; i++) {
tmp = arr[i];
locMax = 1;
memset(cnt, 0, sizeof(cnt));
// Find digits in current element
while (tmp > 0) {
cnt[tmp % 10] = 1;
tmp /= 10;
}
// For each digit present find length of
// subsequence and find local maximum
for (d = 0; d <= 9; d++) {
if (cnt[d]) {
dp[i][d] = 1;
for (j = 0; j < i; j++) {
dp[i][d] = max(dp[i][d], dp[j][d] + 1);
locMax = max(dp[i][d], locMax);
}
}
}
// Update value of dp[i][d] for each digit
// present in current element to local maximum
// found.
for (d = 0; d <= 9; d++) {
if (cnt[d]) {
dp[i][d] = locMax;
}
}
// Update maximum length with local maximum
len = max(len, locMax);
}
return len;
}
// Driver code
int main()
{
int arr[] = { 1, 12, 44, 29, 33, 96, 89 };
int n = sizeof(arr) / sizeof(arr[0]);
cout << findSubsequence(arr, n);
return 0;
}
Java
// Java program to find maximum length subsequence
// such that adjacent elements have at least
// one common digit
class GFG
{
// Returns length of maximum length subsequence
static int findSubsequence(int arr[], int n)
{
// To store the length of the
// maximum length subsequence
int len = 1;
// To store current element arr[i]
int tmp;
int i, j, d;
// To store the length of the sub-sequence
// ending at index i and having common digit d
int[][] dp = new int[n][10];
// To store digits present in current element
int[] cnt = new int[10];
// To store length of maximum length subsequence
// ending at index i
int locMax;
// For first element maximum length is 1 for
// each digit
tmp = arr[0];
while (tmp > 0)
{
dp[0][tmp % 10] = 1;
tmp /= 10;
}
// Find digits of each element, then find length
// of subsequence for each digit and then find
// local maximum
for (i = 1; i < n; i++)
{
tmp = arr[i];
locMax = 1;
for (int x = 0; x < 10; x++)
cnt[x]=0;
// Find digits in current element
while (tmp > 0)
{
cnt[tmp % 10] = 1;
tmp /= 10;
}
// For each digit present find length of
// subsequence and find local maximum
for (d = 0; d <= 9; d++)
{
if (cnt[d] > 0)
{
dp[i][d] = 1;
for (j = 0; j < i; j++)
{
dp[i][d] = Math.max(dp[i][d], dp[j][d] + 1);
locMax = Math.max(dp[i][d], locMax);
}
}
}
// Update value of dp[i][d] for each digit
// present in current element to local maximum
// found.
for (d = 0; d <= 9; d++)
{
if (cnt[d] > 0)
{
dp[i][d] = locMax;
}
}
// Update maximum length with local maximum
len = Math.max(len, locMax);
}
return len;
}
// Driver code
public static void main (String[] args)
{
int arr[] = { 1, 12, 44, 29, 33, 96, 89 };
int n = arr.length;
System.out.println(findSubsequence(arr, n));
}
}
// This code is contributed by mits
Python3
# Python3 program to find maximum
# Length subsequence such that
# adjacent elements have at least
# one common digit
# Returns Length of maximum
# Length subsequence
def findSubsequence(arr, n):
# To store the Length of the
# maximum Length subsequence
Len = 1
# To store current element arr[i]
tmp = 0
i, j, d = 0, 0, 0
# To store the Length of the sub-sequence
# ending at index i and having common digit d
dp = [[0 for i in range(10)]
for i in range(n)]
# To store digits present in current element
cnt = [0 for i in range(10)]
# To store Length of maximum
# Length subsequence ending at index i
locMax = 0
# For first element maximum
# Length is 1 for each digit
tmp = arr[0]
while (tmp > 0):
dp[0][tmp % 10] = 1
tmp //= 10
# Find digits of each element,
# then find Length of subsequence
# for each digit and then find
# local maximum
for i in range(1, n):
tmp = arr[i]
locMax = 1
cnt = [0 for i in range(10)]
# Find digits in current element
while (tmp > 0):
cnt[tmp % 10] = 1
tmp //= 10
# For each digit present find Length of
# subsequence and find local maximum
for d in range(10):
if (cnt[d]):
dp[i][d] = 1
for j in range(i):
dp[i][d] = max(dp[i][d],
dp[j][d] + 1)
locMax = max(dp[i][d], locMax)
# Update value of dp[i][d] for each digit
# present in current element to local
# maximum found.
for d in range(10):
if (cnt[d]):
dp[i][d] = locMax
# Update maximum Length
# with local maximum
Len = max(Len, locMax)
return Len
# Driver code
arr = [1, 12, 44, 29, 33, 96, 89]
n = len(arr)
print(findSubsequence(arr, n))
# This code is contributed
# by mohit kumar
C#
// C# program to find maximum length subsequence
// such that adjacent elements have at least
// one common digit
using System;
class GFG
{
// Returns length of maximum length subsequence
static int findSubsequence(int []arr, int n)
{
// To store the length of the
// maximum length subsequence
int len = 1;
// To store current element arr[i]
int tmp;
int i, j, d;
// To store the length of the sub-sequence
// ending at index i and having common digit d
int[,] dp = new int[n, 10];
// To store digits present in current element
int[] cnt = new int[10];
// To store length of maximum length subsequence
// ending at index i
int locMax;
// For first element maximum length is 1 for
// each digit
tmp = arr[0];
while (tmp > 0)
{
dp[0, tmp % 10] = 1;
tmp /= 10;
}
// Find digits of each element, then find length
// of subsequence for each digit and then find
// local maximum
for (i = 1; i < n; i++)
{
tmp = arr[i];
locMax = 1;
for (int x = 0; x < 10; x++)
cnt[x] = 0;
// Find digits in current element
while (tmp > 0)
{
cnt[tmp % 10] = 1;
tmp /= 10;
}
// For each digit present find length of
// subsequence and find local maximum
for (d = 0; d <= 9; d++)
{
if (cnt[d] > 0)
{
dp[i, d] = 1;
for (j = 0; j < i; j++)
{
dp[i, d] = Math.Max(dp[i, d], dp[j, d] + 1);
locMax = Math.Max(dp[i, d], locMax);
}
}
}
// Update value of dp[i,d] for each digit
// present in current element to local maximum
// found.
for (d = 0; d <= 9; d++)
{
if (cnt[d] > 0)
{
dp[i, d] = locMax;
}
}
// Update maximum length with local maximum
len = Math.Max(len, locMax);
}
return len;
}
// Driver code
public static void Main()
{
int []arr = { 1, 12, 44, 29, 33, 96, 89 };
int n = arr.Length;
Console.WriteLine(findSubsequence(arr, n));
}
}
// This code is contributed by mits
Javascript
C++
// C++ program to find maximum length subsequence
// such that adjacent elements have at least
// one common digit
#include
using namespace std;
// Returns length of maximum length subsequence
int findSubsequence(int arr[], int n)
{
// To store length of maximum length subsequence
int len = 1;
// To store current element arr[i]
int tmp;
int i, j, d;
// To store length of subsequence
// having common digit d
int dp[10];
memset(dp, 0, sizeof(dp));
// To store digits present in current element
int cnt[10];
// To store local maximum for current element
int locMax;
// For first element maximum length is 1 for
// each digit
tmp = arr[0];
while (tmp > 0) {
dp[tmp % 10] = 1;
tmp /= 10;
}
// Find digits of each element, then find length
// of subsequence for each digit and then find
// local maximum
for (i = 1; i < n; i++) {
tmp = arr[i];
locMax = 1;
memset(cnt, 0, sizeof(cnt));
// Find digits in current element
while (tmp > 0) {
cnt[tmp % 10] = 1;
tmp /= 10;
}
// For each digit present find length of
// subsequence and find local maximum
for (d = 0; d <= 9; d++) {
if (cnt[d]) {
dp[d]++;
locMax = max(locMax, dp[d]);
}
}
// Update value of dp[d] for each digit
// present in current element to local maximum
// found
for (d = 0; d <= 9; d++) {
if (cnt[d]) {
dp[d] = locMax;
}
}
// Update maximum length with local maximum
len = max(len, locMax);
}
return len;
}
// Driver code
int main()
{
int arr[] = { 1, 12, 44, 29, 33, 96, 89 };
int n = sizeof(arr) / sizeof(arr[0]);
cout << findSubsequence(arr, n);
return 0;
}
Java
// Java program to find maximum length subsequence
// such that adjacent elements have at least
// one common digit
import java.util.*;
class GFG
{
// Returns length of maximum length subsequence
static int findSubsequence(int arr[], int n)
{
// To store length of maximum length subsequence
int len = 1;
// To store current element arr[i]
int tmp;
int i, j, d;
// To store length of subsequence
// having common digit d
int dp[] = new int[10];
// To store digits present in current element
int cnt[] = new int[10];
// To store local maximum for current element
int locMax;
// For first element maximum length is 1 for
// each digit
tmp = arr[0];
while (tmp > 0)
{
dp[tmp % 10] = 1;
tmp /= 10;
}
// Find digits of each element, then find length
// of subsequence for each digit and then find
// local maximum
for (i = 1; i < n; i++)
{
tmp = arr[i];
locMax = 1;
Arrays.fill(cnt, 0);
// Find digits in current element
while (tmp > 0)
{
cnt[tmp % 10] = 1;
tmp /= 10;
}
// For each digit present find length of
// subsequence and find local maximum
for (d = 0; d <= 9; d++)
{
if (cnt[d] == 1)
{
dp[d]++;
locMax = Math.max(locMax, dp[d]);
}
}
// Update value of dp[d] for each digit
// present in current element to local maximum
// found
for (d = 0; d <= 9; d++)
{
if (cnt[d] == 1)
{
dp[d] = locMax;
}
}
// Update maximum length with local maximum
len = Math.max(len, locMax);
}
return len;
}
// Driver code
public static void main(String[] args)
{
int arr[] = { 1, 12, 44, 29, 33, 96, 89 };
int n = arr.length;
System.out.print(findSubsequence(arr, n));
}
}
/* This code contributed by PrinciRaj1992 */
Python3
# Python3 program to find maximum length
# subsequence such that adjacent elements
# have at least one common digit
# Returns length of maximum
# length subsequence
def findSubsequence(arr, n) :
# To store length of maximum
# length subsequence
length = 1;
# To store length of subsequence
# having common digit d
dp = [0] * 10;
# For first element maximum length
# is 1 for each digit
tmp = arr[0];
while (tmp > 0) :
dp[tmp % 10] = 1;
tmp //= 10;
# Find digits of each element, then
# find length of subsequence for each
# digit and then find local maximum
for i in range(1, n) :
tmp = arr[i];
locMax = 1;
cnt = [0] * 10
# Find digits in current element
while (tmp > 0) :
cnt[tmp % 10] = 1;
tmp //= 10;
# For each digit present find length of
# subsequence and find local maximum
for d in range(10) :
if (cnt[d]) :
dp[d] += 1;
locMax = max(locMax, dp[d]);
# Update value of dp[d] for each digit
# present in current element to local
# maximum found
for d in range(10) :
if (cnt[d]) :
dp[d] = locMax;
# Update maximum length with local
# maximum
length = max(length, locMax);
return length;
# Driver code
if __name__ == "__main__" :
arr = [ 1, 12, 44, 29, 33, 96, 89 ];
n = len(arr)
print(findSubsequence(arr, n));
# This code is contributed by Ryuga
C#
// C# program to find maximum length subsequence
// such that adjacent elements have at least
// one common digit
using System;
class GFG
{
// Returns length of maximum length subsequence
static int findSubsequence(int []arr, int n)
{
// To store length of maximum length subsequence
int len = 1;
// To store current element arr[i]
int tmp;
int i, j, d;
// To store length of subsequence
// having common digit d
int []dp = new int[10];
// To store digits present in current element
int []cnt = new int[10];
// To store local maximum for current element
int locMax;
// For first element maximum length is 1 for
// each digit
tmp = arr[0];
while (tmp > 0)
{
dp[tmp % 10] = 1;
tmp /= 10;
}
// Find digits of each element, then find length
// of subsequence for each digit and then find
// local maximum
for (i = 1; i < n; i++)
{
tmp = arr[i];
locMax = 1;
for(int k = 0; k < 10; k++)
{
cnt[k] = 0;
}
// Find digits in current element
while (tmp > 0)
{
cnt[tmp % 10] = 1;
tmp /= 10;
}
// For each digit present find length of
// subsequence and find local maximum
for (d = 0; d <= 9; d++)
{
if (cnt[d] == 1)
{
dp[d]++;
locMax = Math.Max(locMax, dp[d]);
}
}
// Update value of dp[d] for each digit
// present in current element to local maximum
// found
for (d = 0; d <= 9; d++)
{
if (cnt[d] == 1)
{
dp[d] = locMax;
}
}
// Update maximum length with local maximum
len = Math.Max(len, locMax);
}
return len;
}
// Driver code
public static void Main(String[] args)
{
int []arr = { 1, 12, 44, 29, 33, 96, 89 };
int n = arr.Length;
Console.WriteLine(findSubsequence(arr, n));
}
}
// This code contributed by Rajput-Ji
PHP
0)
{
$dp[$tmp % 10] = 1;
$tmp = intval($tmp / 10);
}
// Find digits of each element, then
// find length of subsequence for each
// digit and then find local maximum
for ($i = 1; $i < $n; $i++)
{
$tmp = $arr[$i];
$locMax = 1;
$cnt = array_fill(0, 10, NULL);
// Find digits in current element
while ($tmp > 0)
{
$cnt[$tmp % 10] = 1;
$tmp = intval($tmp / 10);
}
// For each digit present find length of
// subsequence and find local maximum
for ($d = 0; $d <= 9; $d++)
{
if ($cnt[$d])
{
$dp[$d]++;
$locMax = max($locMax, $dp[$d]);
}
}
// Update value of dp[d] for each digit
// present in current element to local
// maximum found
for ($d = 0; $d <= 9; $d++)
{
if ($cnt[$d])
{
$dp[$d] = $locMax;
}
}
// Update maximum length with
// local maximum
$len = max($len, $locMax);
}
return $len;
}
// Driver code
$arr = array( 1, 12, 44, 29, 33, 96, 89 );
$n = sizeof($arr);
echo findSubsequence($arr, $n);
// This code is contributed by ita_c
?>
Javascript
5
时间复杂度: O(n 2 )
辅助空间: O(n)
可以进一步减少上述方案所需的辅助空间。观察到,对于出现在 arr[i] 中的每个数字 d,无论子序列在哪个元素结束,都需要找到直到该数字的最大长度子序列。这减少了 O(1) 所需的辅助空间。对于每个 arr[i],找到局部最大值并将 arr[i] 中每个数字 d 的 dig[d] 更新为局部最大值。
下面是上述方法的实现:
C++
// C++ program to find maximum length subsequence
// such that adjacent elements have at least
// one common digit
#include
using namespace std;
// Returns length of maximum length subsequence
int findSubsequence(int arr[], int n)
{
// To store length of maximum length subsequence
int len = 1;
// To store current element arr[i]
int tmp;
int i, j, d;
// To store length of subsequence
// having common digit d
int dp[10];
memset(dp, 0, sizeof(dp));
// To store digits present in current element
int cnt[10];
// To store local maximum for current element
int locMax;
// For first element maximum length is 1 for
// each digit
tmp = arr[0];
while (tmp > 0) {
dp[tmp % 10] = 1;
tmp /= 10;
}
// Find digits of each element, then find length
// of subsequence for each digit and then find
// local maximum
for (i = 1; i < n; i++) {
tmp = arr[i];
locMax = 1;
memset(cnt, 0, sizeof(cnt));
// Find digits in current element
while (tmp > 0) {
cnt[tmp % 10] = 1;
tmp /= 10;
}
// For each digit present find length of
// subsequence and find local maximum
for (d = 0; d <= 9; d++) {
if (cnt[d]) {
dp[d]++;
locMax = max(locMax, dp[d]);
}
}
// Update value of dp[d] for each digit
// present in current element to local maximum
// found
for (d = 0; d <= 9; d++) {
if (cnt[d]) {
dp[d] = locMax;
}
}
// Update maximum length with local maximum
len = max(len, locMax);
}
return len;
}
// Driver code
int main()
{
int arr[] = { 1, 12, 44, 29, 33, 96, 89 };
int n = sizeof(arr) / sizeof(arr[0]);
cout << findSubsequence(arr, n);
return 0;
}
Java
// Java program to find maximum length subsequence
// such that adjacent elements have at least
// one common digit
import java.util.*;
class GFG
{
// Returns length of maximum length subsequence
static int findSubsequence(int arr[], int n)
{
// To store length of maximum length subsequence
int len = 1;
// To store current element arr[i]
int tmp;
int i, j, d;
// To store length of subsequence
// having common digit d
int dp[] = new int[10];
// To store digits present in current element
int cnt[] = new int[10];
// To store local maximum for current element
int locMax;
// For first element maximum length is 1 for
// each digit
tmp = arr[0];
while (tmp > 0)
{
dp[tmp % 10] = 1;
tmp /= 10;
}
// Find digits of each element, then find length
// of subsequence for each digit and then find
// local maximum
for (i = 1; i < n; i++)
{
tmp = arr[i];
locMax = 1;
Arrays.fill(cnt, 0);
// Find digits in current element
while (tmp > 0)
{
cnt[tmp % 10] = 1;
tmp /= 10;
}
// For each digit present find length of
// subsequence and find local maximum
for (d = 0; d <= 9; d++)
{
if (cnt[d] == 1)
{
dp[d]++;
locMax = Math.max(locMax, dp[d]);
}
}
// Update value of dp[d] for each digit
// present in current element to local maximum
// found
for (d = 0; d <= 9; d++)
{
if (cnt[d] == 1)
{
dp[d] = locMax;
}
}
// Update maximum length with local maximum
len = Math.max(len, locMax);
}
return len;
}
// Driver code
public static void main(String[] args)
{
int arr[] = { 1, 12, 44, 29, 33, 96, 89 };
int n = arr.length;
System.out.print(findSubsequence(arr, n));
}
}
/* This code contributed by PrinciRaj1992 */
蟒蛇3
# Python3 program to find maximum length
# subsequence such that adjacent elements
# have at least one common digit
# Returns length of maximum
# length subsequence
def findSubsequence(arr, n) :
# To store length of maximum
# length subsequence
length = 1;
# To store length of subsequence
# having common digit d
dp = [0] * 10;
# For first element maximum length
# is 1 for each digit
tmp = arr[0];
while (tmp > 0) :
dp[tmp % 10] = 1;
tmp //= 10;
# Find digits of each element, then
# find length of subsequence for each
# digit and then find local maximum
for i in range(1, n) :
tmp = arr[i];
locMax = 1;
cnt = [0] * 10
# Find digits in current element
while (tmp > 0) :
cnt[tmp % 10] = 1;
tmp //= 10;
# For each digit present find length of
# subsequence and find local maximum
for d in range(10) :
if (cnt[d]) :
dp[d] += 1;
locMax = max(locMax, dp[d]);
# Update value of dp[d] for each digit
# present in current element to local
# maximum found
for d in range(10) :
if (cnt[d]) :
dp[d] = locMax;
# Update maximum length with local
# maximum
length = max(length, locMax);
return length;
# Driver code
if __name__ == "__main__" :
arr = [ 1, 12, 44, 29, 33, 96, 89 ];
n = len(arr)
print(findSubsequence(arr, n));
# This code is contributed by Ryuga
C#
// C# program to find maximum length subsequence
// such that adjacent elements have at least
// one common digit
using System;
class GFG
{
// Returns length of maximum length subsequence
static int findSubsequence(int []arr, int n)
{
// To store length of maximum length subsequence
int len = 1;
// To store current element arr[i]
int tmp;
int i, j, d;
// To store length of subsequence
// having common digit d
int []dp = new int[10];
// To store digits present in current element
int []cnt = new int[10];
// To store local maximum for current element
int locMax;
// For first element maximum length is 1 for
// each digit
tmp = arr[0];
while (tmp > 0)
{
dp[tmp % 10] = 1;
tmp /= 10;
}
// Find digits of each element, then find length
// of subsequence for each digit and then find
// local maximum
for (i = 1; i < n; i++)
{
tmp = arr[i];
locMax = 1;
for(int k = 0; k < 10; k++)
{
cnt[k] = 0;
}
// Find digits in current element
while (tmp > 0)
{
cnt[tmp % 10] = 1;
tmp /= 10;
}
// For each digit present find length of
// subsequence and find local maximum
for (d = 0; d <= 9; d++)
{
if (cnt[d] == 1)
{
dp[d]++;
locMax = Math.Max(locMax, dp[d]);
}
}
// Update value of dp[d] for each digit
// present in current element to local maximum
// found
for (d = 0; d <= 9; d++)
{
if (cnt[d] == 1)
{
dp[d] = locMax;
}
}
// Update maximum length with local maximum
len = Math.Max(len, locMax);
}
return len;
}
// Driver code
public static void Main(String[] args)
{
int []arr = { 1, 12, 44, 29, 33, 96, 89 };
int n = arr.Length;
Console.WriteLine(findSubsequence(arr, n));
}
}
// This code contributed by Rajput-Ji
PHP
0)
{
$dp[$tmp % 10] = 1;
$tmp = intval($tmp / 10);
}
// Find digits of each element, then
// find length of subsequence for each
// digit and then find local maximum
for ($i = 1; $i < $n; $i++)
{
$tmp = $arr[$i];
$locMax = 1;
$cnt = array_fill(0, 10, NULL);
// Find digits in current element
while ($tmp > 0)
{
$cnt[$tmp % 10] = 1;
$tmp = intval($tmp / 10);
}
// For each digit present find length of
// subsequence and find local maximum
for ($d = 0; $d <= 9; $d++)
{
if ($cnt[$d])
{
$dp[$d]++;
$locMax = max($locMax, $dp[$d]);
}
}
// Update value of dp[d] for each digit
// present in current element to local
// maximum found
for ($d = 0; $d <= 9; $d++)
{
if ($cnt[$d])
{
$dp[$d] = $locMax;
}
}
// Update maximum length with
// local maximum
$len = max($len, $locMax);
}
return $len;
}
// Driver code
$arr = array( 1, 12, 44, 29, 33, 96, 89 );
$n = sizeof($arr);
echo findSubsequence($arr, $n);
// This code is contributed by ita_c
?>
Javascript
5
时间复杂度: O(n)
辅助空间: O(1)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。