给定一个整数数组,找出最长子序列的长度,使得子序列中的元素为连续整数,连续数可以是任意顺序。
例子:
Input: arr[] = {1, 9, 3, 10, 4, 20, 2}
Output: 4
Explanation:
The subsequence 1, 3, 4, 2 is the longest
subsequence of consecutive elements
Input: arr[] = {36, 41, 56, 35, 44, 33, 34, 92, 43, 32, 42}
Output: 5
Explanation:
The subsequence 36, 35, 33, 34, 32 is the longest
subsequence of consecutive elements.
朴素的方法:想法是首先对数组进行排序,然后找到具有连续元素的最长子数组。
在对数组进行排序并删除多次出现的元素后,运行一个循环并保留一个计数和最大值(最初都为零)。从头到尾运行一个循环,如果当前元素不等于前一个(元素+1),则将计数设置为 1,否则增加计数。使用最大计数和最大值更新 max。
C++
// C++ program to find longest
// contiguous subsequence
#include
using namespace std;
// Returns length of the longest
// contiguous subsequence
int findLongestConseqSubseq(int arr[], int n)
{
int ans = 0, count = 0;
// sort the array
sort(arr, arr + n);
vector v;
v.push_back(arr[0]);
//insert repeated elements only once in the vector
for (int i = 1; i < n; i++)
{
if (arr[i] != arr[i - 1])
v.push_back(arr[i]);
}
// find the maximum length
// by traversing the array
for (int i = 0; i < v.size(); i++)
{
// Check if the current element is equal
// to previous element +1
if (i > 0 && v[i] == v[i - 1] + 1)
count++;
// reset the count
else
count = 1;
// update the maximum
ans = max(ans, count);
}
return ans;
}
// Driver code
int main()
{
int arr[] = { 1, 2, 2, 3 };
int n = sizeof arr / sizeof arr[0];
cout << "Length of the Longest contiguous subsequence "
"is "
<< findLongestConseqSubseq(arr, n);
return 0;
}
Java
// Java program to find longest
// contiguous subsequence
import java.io.*;
import java.util.*;
class GFG
{
static int findLongestConseqSubseq(int arr[],
int n)
{
// Sort the array
Arrays.sort(arr);
int ans = 0, count = 0;
ArrayList v = new ArrayList();
v.add(10);
// Insert repeated elements
// only once in the vector
for (int i = 1; i < n; i++)
{
if (arr[i] != arr[i - 1])
v.add(arr[i]);
}
// Find the maximum length
// by traversing the array
for (int i = 0; i < v.size(); i++)
{
// Check if the current element is
// equal to previous element +1
if (i > 0 &&v.get(i) == v.get(i - 1) + 1)
count++;
else
count = 1;
// Update the maximum
ans = Math.max(ans, count);
}
return ans;
}
// Driver code
public static void main(String[] args)
{
int arr[] = { 1, 9, 3, 10, 4, 20, 2 };
int n = arr.length;
System.out.println(
"Length of the Longest "
+ "contiguous subsequence is "
+ findLongestConseqSubseq(arr, n));
}
}
// This code is contributed by parascoding
Python3
# Python3 program to find longest
# contiguous subsequence
# Returns length of the longest
# contiguous subsequence
def findLongestConseqSubseq(arr, n):
ans = 0
count = 0
# Sort the array
arr.sort()
v = []
v.append(arr[0])
# Insert repeated elements only
# once in the vector
for i in range(1, n):
if (arr[i] != arr[i - 1]):
v.append(arr[i])
# Find the maximum length
# by traversing the array
for i in range(len(v)):
# Check if the current element is
# equal to previous element +1
if (i > 0 and v[i] == v[i - 1] + 1):
count += 1
# Reset the count
else:
count = 1
# Update the maximum
ans = max(ans, count)
return ans
# Driver code
arr = [ 1, 2, 2, 3 ]
n = len(arr)
print("Length of the Longest contiguous subsequence is",
findLongestConseqSubseq(arr, n))
# This code is contributed by avanitrachhadiya2155
C#
// C# program to find longest
// contiguous subsequence
using System;
using System.Collections.Generic;
class GFG{
static int findLongestConseqSubseq(int[] arr,
int n)
{
// Sort the array
Array.Sort(arr);
int ans = 0, count = 0;
List v = new List();
v.Add(10);
// Insert repeated elements
// only once in the vector
for(int i = 1; i < n; i++)
{
if (arr[i] != arr[i - 1])
v.Add(arr[i]);
}
// Find the maximum length
// by traversing the array
for(int i = 0; i < v.Count; i++)
{
// Check if the current element is
// equal to previous element +1
if (i > 0 && v[i] == v[i - 1] + 1)
count++;
else
count = 1;
// Update the maximum
ans = Math.Max(ans, count);
}
return ans;
}
// Driver code
static void Main()
{
int[] arr = { 1, 9, 3, 10, 4, 20, 2 };
int n = arr.Length;
Console.WriteLine("Length of the Longest " +
"contiguous subsequence is " +
findLongestConseqSubseq(arr, n));
}
}
// This code is contributed by divyeshrabadiya07
Javascript
C++
// C++ program to find longest
// contiguous subsequence
#include
using namespace std;
// Returns length of the longest
// contiguous subsequence
int findLongestConseqSubseq(int arr[], int n)
{
unordered_set S;
int ans = 0;
// Hash all the array elements
for (int i = 0; i < n; i++)
S.insert(arr[i]);
// check each possible sequence from
// the start then update optimal length
for (int i = 0; i < n; i++)
{
// if current element is the starting
// element of a sequence
if (S.find(arr[i] - 1) == S.end())
{
// Then check for next elements
// in the sequence
int j = arr[i];
while (S.find(j) != S.end())
j++;
// update optimal length if
// this length is more
ans = max(ans, j - arr[i]);
}
}
return ans;
}
// Driver code
int main()
{
int arr[] = { 1, 9, 3, 10, 4, 20, 2 };
int n = sizeof arr / sizeof arr[0];
cout << "Length of the Longest contiguous subsequence "
"is "
<< findLongestConseqSubseq(arr, n);
return 0;
}
Java
// Java program to find longest
// consecutive subsequence
import java.io.*;
import java.util.*;
class ArrayElements {
// Returns length of the longest
// consecutive subsequence
static int findLongestConseqSubseq(int arr[], int n)
{
HashSet S = new HashSet();
int ans = 0;
// Hash all the array elements
for (int i = 0; i < n; ++i)
S.add(arr[i]);
// check each possible sequence from the start
// then update optimal length
for (int i = 0; i < n; ++i)
{
// if current element is the starting
// element of a sequence
if (!S.contains(arr[i] - 1))
{
// Then check for next elements
// in the sequence
int j = arr[i];
while (S.contains(j))
j++;
// update optimal length if this
// length is more
if (ans < j - arr[i])
ans = j - arr[i];
}
}
return ans;
}
// Driver Code
public static void main(String args[])
{
int arr[] = { 1, 9, 3, 10, 4, 20, 2 };
int n = arr.length;
System.out.println(
"Length of the Longest consecutive subsequence is "
+ findLongestConseqSubseq(arr, n));
}
}
// This code is contributed by Aakash Hasija
Python
# Python program to find longest contiguous subsequence
from sets import Set
def findLongestConseqSubseq(arr, n):
s = Set()
ans = 0
# Hash all the array elements
for ele in arr:
s.add(ele)
# check each possible sequence from the start
# then update optimal length
for i in range(n):
# if current element is the starting
# element of a sequence
if (arr[i]-1) not in s:
# Then check for next elements in the
# sequence
j = arr[i]
while(j in s):
j += 1
# update optimal length if this length
# is more
ans = max(ans, j-arr[i])
return ans
# Driver code
if __name__ == '__main__':
n = 7
arr = [1, 9, 3, 10, 4, 20, 2]
print "Length of the Longest contiguous subsequence is ",
print findLongestConseqSubseq(arr, n)
# Contributed by: Harshit Sidhwa
C#
using System;
using System.Collections.Generic;
// C# program to find longest consecutive subsequence
public class ArrayElements {
// Returns length of the
// longest consecutive subsequence
public static int findLongestConseqSubseq(int[] arr,
int n)
{
HashSet S = new HashSet();
int ans = 0;
// Hash all the array elements
for (int i = 0; i < n; ++i) {
S.Add(arr[i]);
}
// check each possible sequence from the start
// then update optimal length
for (int i = 0; i < n; ++i)
{
// if current element is the starting
// element of a sequence
if (!S.Contains(arr[i] - 1))
{
// Then check for next elements in the
// sequence
int j = arr[i];
while (S.Contains(j))
{
j++;
}
// update optimal length if this length
// is more
if (ans < j - arr[i])
{
ans = j - arr[i];
}
}
}
return ans;
}
// Driver code
public static void Main(string[] args)
{
int[] arr = new int[] { 1, 9, 3, 10, 4, 20, 2 };
int n = arr.Length;
Console.WriteLine(
"Length of the Longest consecutive subsequence is "
+ findLongestConseqSubseq(arr, n));
}
}
// This code is contributed by Shrikant13
Javascript
C++
// CPP program for the above approach
#include
using namespace std;
int findLongestConseqSubseq(int arr[], int N)
{
priority_queue, greater > pq;
for (int i = 0; i < N; i++) {
// adding element from
// array to PriorityQueue
pq.push(arr[i]);
}
// Storing the first element
// of the Priority Queue
// This first element is also
// the smallest element
int prev = pq.top();
pq.pop();
// Taking a counter variable with value 1
int c = 1;
// Storing value of max as 1
// as there will always be
// one element
int max = 1;
while (!pq.empty()) {
// check if current peek
// element minus previous
// element is greater then
// 1 This is done because
// if it's greater than 1
// then the sequence
// doesn't start or is broken here
if (pq.top() - prev > 1) {
// Store the value of counter to 1
// As new sequence may begin
c = 1;
// Update the previous position with the
// current peek And remove it
prev = pq.top();
pq.pop();
}
// Check if the previous
// element and peek are same
else if (pq.top() - prev == 0) {
// Update the previous position with the
// current peek And remove it
prev = pq.top();
pq.pop();
}
// If the difference
// between previous element and peek is 1
else {
// Update the counter
// These are consecutive elements
c++;
// Update the previous position
// with the current peek And remove it
prev = pq.top();
pq.pop();
}
// Check if current longest
// subsequence is the greatest
if (max < c) {
// Store the current subsequence count as
// max
max = c;
}
}
return max;
}
// Driver Code
int main()
{
int arr[] = { 1, 9, 3, 10, 4, 20, 2 };
int n = 7;
cout << "Length of the Longest consecutive subsequence "
"is "
<< findLongestConseqSubseq(arr, n);
return 0;
}
// this code is contributed by Manu Pathria
Java
// Java Program to find longest consecutive
// subsequence This Program uses Priority Queue
import java.io.*;
import java.util.PriorityQueue;
public class Longset_Sub
{
// return the length of the longest
// subsequence of consecutive integers
static int findLongestConseqSubseq(int arr[], int N)
{
PriorityQueue pq
= new PriorityQueue();
for (int i = 0; i < N; i++)
{
// adding element from
// array to PriorityQueue
pq.add(arr[i]);
}
// Storing the first element
// of the Priority Queue
// This first element is also
// the smallest element
int prev = pq.poll();
// Taking a counter variable with value 1
int c = 1;
// Storing value of max as 1
// as there will always be
// one element
int max = 1;
for (int i = 1; i < N; i++)
{
// check if current peek
// element minus previous
// element is greater then
// 1 This is done because
// if it's greater than 1
// then the sequence
// doesn't start or is broken here
if (pq.peek() - prev > 1)
{
// Store the value of counter to 1
// As new sequence may begin
c = 1;
// Update the previous position with the
// current peek And remove it
prev = pq.poll();
}
// Check if the previous
// element and peek are same
else if (pq.peek() - prev == 0)
{
// Update the previous position with the
// current peek And remove it
prev = pq.poll();
}
// if the difference
// between previous element and peek is 1
else
{
// Update the counter
// These are consecutive elements
c++;
// Update the previous position
// with the current peek And remove it
prev = pq.poll();
}
// Check if current longest
// subsequence is the greatest
if (max < c)
{
// Store the current subsequence count as
// max
max = c;
}
}
return max;
}
// Driver Code
public static void main(String args[])
throws IOException
{
int arr[] = { 1, 9, 3, 10, 4, 20, 2 };
int n = arr.length;
System.out.println(
"Length of the Longest consecutive subsequence is "
+ findLongestConseqSubseq(arr, n));
}
}
// This code is contributed by Sudipa Sarkar
输出
Length of the Longest contiguous subsequence is 3
复杂度分析:
- 时间复杂度: O(nLogn)。
对数组进行排序的时间是 O(nlogn)。 - 辅助空间: O(1)。
因为不需要额外的空间。
感谢 Hao.W 提出上述解决方案。
有效的解决方案:
这个问题可以使用Efficient Solution在 O(n) 时间内解决。这个想法是使用哈希。我们首先将所有元素插入到一个集合中。然后检查所有可能的连续子序列的开始。
算法:
- 创建一个空哈希。
- 将所有数组元素插入到哈希中。
- 对每个元素 arr[i] 执行以下操作
- 检查此元素是否是子序列的起点。要检查这一点,只需在散列中查找 arr[i] – 1,如果未找到,则这是子序列的第一个元素。
- 如果这个元素是第一个元素,那么计算从这个元素开始的连续元素的个数。从 arr[i] + 1 迭代直到可以找到的最后一个元素。
- 如果计数大于之前找到的最长子序列,则更新它。
下图是上述方法的试运行:
下面是上述方法的实现:
C++
// C++ program to find longest
// contiguous subsequence
#include
using namespace std;
// Returns length of the longest
// contiguous subsequence
int findLongestConseqSubseq(int arr[], int n)
{
unordered_set S;
int ans = 0;
// Hash all the array elements
for (int i = 0; i < n; i++)
S.insert(arr[i]);
// check each possible sequence from
// the start then update optimal length
for (int i = 0; i < n; i++)
{
// if current element is the starting
// element of a sequence
if (S.find(arr[i] - 1) == S.end())
{
// Then check for next elements
// in the sequence
int j = arr[i];
while (S.find(j) != S.end())
j++;
// update optimal length if
// this length is more
ans = max(ans, j - arr[i]);
}
}
return ans;
}
// Driver code
int main()
{
int arr[] = { 1, 9, 3, 10, 4, 20, 2 };
int n = sizeof arr / sizeof arr[0];
cout << "Length of the Longest contiguous subsequence "
"is "
<< findLongestConseqSubseq(arr, n);
return 0;
}
Java
// Java program to find longest
// consecutive subsequence
import java.io.*;
import java.util.*;
class ArrayElements {
// Returns length of the longest
// consecutive subsequence
static int findLongestConseqSubseq(int arr[], int n)
{
HashSet S = new HashSet();
int ans = 0;
// Hash all the array elements
for (int i = 0; i < n; ++i)
S.add(arr[i]);
// check each possible sequence from the start
// then update optimal length
for (int i = 0; i < n; ++i)
{
// if current element is the starting
// element of a sequence
if (!S.contains(arr[i] - 1))
{
// Then check for next elements
// in the sequence
int j = arr[i];
while (S.contains(j))
j++;
// update optimal length if this
// length is more
if (ans < j - arr[i])
ans = j - arr[i];
}
}
return ans;
}
// Driver Code
public static void main(String args[])
{
int arr[] = { 1, 9, 3, 10, 4, 20, 2 };
int n = arr.length;
System.out.println(
"Length of the Longest consecutive subsequence is "
+ findLongestConseqSubseq(arr, n));
}
}
// This code is contributed by Aakash Hasija
Python
# Python program to find longest contiguous subsequence
from sets import Set
def findLongestConseqSubseq(arr, n):
s = Set()
ans = 0
# Hash all the array elements
for ele in arr:
s.add(ele)
# check each possible sequence from the start
# then update optimal length
for i in range(n):
# if current element is the starting
# element of a sequence
if (arr[i]-1) not in s:
# Then check for next elements in the
# sequence
j = arr[i]
while(j in s):
j += 1
# update optimal length if this length
# is more
ans = max(ans, j-arr[i])
return ans
# Driver code
if __name__ == '__main__':
n = 7
arr = [1, 9, 3, 10, 4, 20, 2]
print "Length of the Longest contiguous subsequence is ",
print findLongestConseqSubseq(arr, n)
# Contributed by: Harshit Sidhwa
C#
using System;
using System.Collections.Generic;
// C# program to find longest consecutive subsequence
public class ArrayElements {
// Returns length of the
// longest consecutive subsequence
public static int findLongestConseqSubseq(int[] arr,
int n)
{
HashSet S = new HashSet();
int ans = 0;
// Hash all the array elements
for (int i = 0; i < n; ++i) {
S.Add(arr[i]);
}
// check each possible sequence from the start
// then update optimal length
for (int i = 0; i < n; ++i)
{
// if current element is the starting
// element of a sequence
if (!S.Contains(arr[i] - 1))
{
// Then check for next elements in the
// sequence
int j = arr[i];
while (S.Contains(j))
{
j++;
}
// update optimal length if this length
// is more
if (ans < j - arr[i])
{
ans = j - arr[i];
}
}
}
return ans;
}
// Driver code
public static void Main(string[] args)
{
int[] arr = new int[] { 1, 9, 3, 10, 4, 20, 2 };
int n = arr.Length;
Console.WriteLine(
"Length of the Longest consecutive subsequence is "
+ findLongestConseqSubseq(arr, n));
}
}
// This code is contributed by Shrikant13
Javascript
输出
Length of the Longest contiguous subsequence is 4
复杂度分析:
- 时间复杂度: O(n)。
假设哈希插入和搜索花费 O(1) 时间,只需要一次遍历,时间复杂度为 O(n)。 - 辅助空间: O(n)。
需要将每个元素存储在 hashmap O(n) 空间中
感谢Gaurav Ahirwar提供上述解决方案。
另一个解决方案:
这个问题可以用另一种方法在O(N log N)时间内解决,这次的想法是使用 Priority Queue。
算法:
- 创建一个优先队列来存储元素
- 将第一个元素存储在变量中
- 将其从优先队列中移除
- 检查这个删除的第一个元素和新的 peek 元素之间的区别
- 如果差值等于 1,则将计数加 1 并重复步骤 2 和步骤 3
- 如果差值大于 1,则将计数器设置为 1 并重复步骤 2 和步骤 3
- 如果差值等于 0 重复步骤 2 和 3
- 如果计数器大于先前的最大值,则将计数器存储到最大值
- 继续第 4 步到第 7 步,直到我们到达优先队列的末尾
- 返回最大值
C++
// CPP program for the above approach
#include
using namespace std;
int findLongestConseqSubseq(int arr[], int N)
{
priority_queue, greater > pq;
for (int i = 0; i < N; i++) {
// adding element from
// array to PriorityQueue
pq.push(arr[i]);
}
// Storing the first element
// of the Priority Queue
// This first element is also
// the smallest element
int prev = pq.top();
pq.pop();
// Taking a counter variable with value 1
int c = 1;
// Storing value of max as 1
// as there will always be
// one element
int max = 1;
while (!pq.empty()) {
// check if current peek
// element minus previous
// element is greater then
// 1 This is done because
// if it's greater than 1
// then the sequence
// doesn't start or is broken here
if (pq.top() - prev > 1) {
// Store the value of counter to 1
// As new sequence may begin
c = 1;
// Update the previous position with the
// current peek And remove it
prev = pq.top();
pq.pop();
}
// Check if the previous
// element and peek are same
else if (pq.top() - prev == 0) {
// Update the previous position with the
// current peek And remove it
prev = pq.top();
pq.pop();
}
// If the difference
// between previous element and peek is 1
else {
// Update the counter
// These are consecutive elements
c++;
// Update the previous position
// with the current peek And remove it
prev = pq.top();
pq.pop();
}
// Check if current longest
// subsequence is the greatest
if (max < c) {
// Store the current subsequence count as
// max
max = c;
}
}
return max;
}
// Driver Code
int main()
{
int arr[] = { 1, 9, 3, 10, 4, 20, 2 };
int n = 7;
cout << "Length of the Longest consecutive subsequence "
"is "
<< findLongestConseqSubseq(arr, n);
return 0;
}
// this code is contributed by Manu Pathria
Java
// Java Program to find longest consecutive
// subsequence This Program uses Priority Queue
import java.io.*;
import java.util.PriorityQueue;
public class Longset_Sub
{
// return the length of the longest
// subsequence of consecutive integers
static int findLongestConseqSubseq(int arr[], int N)
{
PriorityQueue pq
= new PriorityQueue();
for (int i = 0; i < N; i++)
{
// adding element from
// array to PriorityQueue
pq.add(arr[i]);
}
// Storing the first element
// of the Priority Queue
// This first element is also
// the smallest element
int prev = pq.poll();
// Taking a counter variable with value 1
int c = 1;
// Storing value of max as 1
// as there will always be
// one element
int max = 1;
for (int i = 1; i < N; i++)
{
// check if current peek
// element minus previous
// element is greater then
// 1 This is done because
// if it's greater than 1
// then the sequence
// doesn't start or is broken here
if (pq.peek() - prev > 1)
{
// Store the value of counter to 1
// As new sequence may begin
c = 1;
// Update the previous position with the
// current peek And remove it
prev = pq.poll();
}
// Check if the previous
// element and peek are same
else if (pq.peek() - prev == 0)
{
// Update the previous position with the
// current peek And remove it
prev = pq.poll();
}
// if the difference
// between previous element and peek is 1
else
{
// Update the counter
// These are consecutive elements
c++;
// Update the previous position
// with the current peek And remove it
prev = pq.poll();
}
// Check if current longest
// subsequence is the greatest
if (max < c)
{
// Store the current subsequence count as
// max
max = c;
}
}
return max;
}
// Driver Code
public static void main(String args[])
throws IOException
{
int arr[] = { 1, 9, 3, 10, 4, 20, 2 };
int n = arr.length;
System.out.println(
"Length of the Longest consecutive subsequence is "
+ findLongestConseqSubseq(arr, n));
}
}
// This code is contributed by Sudipa Sarkar
输出
Length of the Longest consecutive subsequence is 4
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。