Given an integer array arr[] that is sorted in increasing order and an integer K. Check whether it is possible to split arr[] into one or more subsequences such that both of the following conditions are true:
- Each subsequence is a consecutive increasing sequence (i.e. each integer is exactly one more than the previous integer).
- All subsequences have a length of K or more.
Examples:
Input: arr = [1, 2, 3, 3, 4, 5], k = 3 Output: true Explanation: arr can be split into the following subsequences: [1, 2, 3, 3, 4, 5] –> 1, 2, 3 [1, 2, 3, 3, 4, 5] –> 3, 4, 5
Input: arr = [1, 1, 1, 1, 1], k = 4 Output: false Explanation: It is impossible to split arr into consecutive increasing subsequences of length 4 or more.
Input: arr = [1, 2, 3, 4, 4, 5], k=5 Output: false Explanation: It is impossible to split arr into consecutive increasing subsequences of length k or more.
Approach: To solve the problem follow the below idea:
The idea to solve the problem is we can use a Min-Heap to store the current number and the count of the assumed subarray.
- We use a Min Heap to keep track of the current number and its assumed subarray count.
- Start with an empty Heap, indicating we haven’t begun processing elements yet.
- For the first element, set it as the starting point of the assumed subarray with a size of 1, then insert it into the Heap.
- For each subsequent element:
- Compare it with the top element in the Heap (which has the smallest number with the fewest subarray elements).
- If they are equal, increment the subarray count.
- If they are consecutive, create a new pair with the current element and its count, then insert it into the Heap while removing the top element.
- If neither condition holds, check if the count of the top pair in the Heap is greater than or equal to k. If so, remove it; otherwise, return false.
- Continue this process until all elements are processed.
- After traversal, inspect any remaining elements in the Heap. If there are identical elements pushed sequentially, consider them as potential starting points of subarrays (with a count not exceeding 1). If such elements exist, return false.
- If all conditions are met without encountering a false condition, return true.
Below is the implementation of the above approach:
C++14
#include <bits/stdc++.h>
using namespace std;
class comparison {
public :
bool operator()(pair< int , int > a, pair< int , int > b)
{
if (a.first == b.first) {
return a.second > b.second;
}
else {
return a.first > b.first;
}
}
};
bool isPossible(vector< int >& nums, int k)
{
priority_queue<pair< int , int >, vector<pair< int , int > >,
comparison>
pq;
int i = 0;
while (i < nums.size()) {
if (pq.empty()) {
pq.push({ nums[i], 1 });
i++;
}
else {
if (nums[i] == pq.top().first) {
pq.push({ nums[i], 1 });
i++;
}
else if (nums[i] == pq.top().first + 1) {
auto temp = pq.top();
pq.pop();
pq.push({ nums[i], temp.second + 1 });
i++;
}
else {
if (pq.top().second < k) {
return false ;
}
pq.pop();
}
}
}
while (!pq.empty()) {
if (pq.top().second < k) {
return false ;
}
pq.pop();
}
return true ;
}
int main()
{
vector< int > vec = { 1, 2, 3, 3, 4, 5 };
int k = 3;
if (isPossible(vec, k)) {
cout << "True" << endl;
}
else {
cout << "False" << endl;
}
return 0;
}
|
Java
import java.util.*;
class Solution {
public static boolean isPossible(List<Integer> nums, int k) {
PriorityQueue<Pair<Integer, Integer>> pq = new PriorityQueue<>( new Comparator<Pair<Integer, Integer>>() {
@Override
public int compare(Pair<Integer, Integer> a, Pair<Integer, Integer> b) {
if (a.getKey().equals(b.getKey())) {
return a.getValue() - b.getValue();
} else {
return a.getKey() - b.getKey();
}
}
});
int i = 0 ;
while (i < nums.size()) {
if (pq.isEmpty()) {
pq.add( new Pair<>(nums.get(i), 1 ));
i++;
} else {
if (nums.get(i).equals(pq.peek().getKey())) {
pq.add( new Pair<>(nums.get(i), 1 ));
i++;
} else if (nums.get(i) == pq.peek().getKey() + 1 ) {
Pair<Integer, Integer> temp = pq.poll();
pq.add( new Pair<>(nums.get(i), temp.getValue() + 1 ));
i++;
} else {
if (pq.peek().getValue() < k) {
return false ;
}
pq.poll();
}
}
}
while (!pq.isEmpty()) {
if (pq.peek().getValue() < k) {
return false ;
}
pq.poll();
}
return true ;
}
public static void main(String[] args) {
List<Integer> vec = Arrays.asList( 1 , 2 , 3 , 3 , 4 , 5 );
int k = 3 ;
if (isPossible(vec, k)) {
System.out.println( "True" );
} else {
System.out.println( "False" );
}
}
}
class Pair<K, V> {
private final K key;
private final V value;
public Pair(K key, V value) {
this .key = key;
this .value = value;
}
public K getKey() {
return key;
}
public V getValue() {
return value;
}
}
|
Python3
import heapq
class Comparison:
def __call__( self , a, b):
if a[ 0 ] = = b[ 0 ]:
return a[ 1 ] > b[ 1 ]
else :
return a[ 0 ] > b[ 0 ]
def is_possible(nums, k):
pq = []
i = 0
while i < len (nums):
if not pq:
heapq.heappush(pq, (nums[i], 1 ))
i + = 1
else :
if nums[i] = = pq[ 0 ][ 0 ]:
heapq.heappush(pq, (nums[i], 1 ))
i + = 1
elif nums[i] = = pq[ 0 ][ 0 ] + 1 :
temp = heapq.heappop(pq)
heapq.heappush(pq, (nums[i], temp[ 1 ] + 1 ))
i + = 1
else :
if pq[ 0 ][ 1 ] < k:
return False
heapq.heappop(pq)
while pq:
if pq[ 0 ][ 1 ] < k:
return False
heapq.heappop(pq)
return True
vec = [ 1 , 2 , 3 , 3 , 4 , 5 ]
k = 3
if is_possible(vec, k):
print ( "True" )
else :
print ( "False" )
|
C#
using System;
using System.Collections.Generic;
public class GFG
{
public static bool IsPossible(List< int > nums, int k)
{
PriorityQueue<Pair< int , int >> pq = new PriorityQueue<Pair< int , int >>( new PairComparer());
int i = 0;
while (i < nums.Count)
{
if (pq.Count == 0)
{
pq.Enqueue( new Pair< int , int >(nums[i], 1));
i++;
}
else
{
if (nums[i] == pq.Peek().Key)
{
pq.Enqueue( new Pair< int , int >(nums[i], 1));
i++;
}
else if (nums[i] == pq.Peek().Key + 1)
{
Pair< int , int > temp = pq.Dequeue();
pq.Enqueue( new Pair< int , int >(nums[i], temp.Value + 1));
i++;
}
else
{
if (pq.Peek().Value < k)
{
return false ;
}
pq.Dequeue();
}
}
}
while (pq.Count > 0)
{
if (pq.Peek().Value < k)
{
return false ;
}
pq.Dequeue();
}
return true ;
}
public static void Main( string [] args)
{
List< int > vec = new List< int > { 1, 2, 3, 3, 4, 5 };
int k = 3;
if (IsPossible(vec, k))
{
Console.WriteLine( "True" );
}
else
{
Console.WriteLine( "False" );
}
}
}
public class Pair<K, V>
{
public K Key { get ; }
public V Value { get ; }
public Pair(K key, V value)
{
Key = key;
Value = value;
}
}
public class PairComparer : IComparer<Pair< int , int >>
{
public int Compare(Pair< int , int > a, Pair< int , int > b)
{
if (a.Key == b.Key)
{
return a.Value - b.Value;
}
else
{
return a.Key - b.Key;
}
}
}
public class PriorityQueue<T>
{
private List<T> data;
private IComparer<T> comparer;
public PriorityQueue(IComparer<T> comparer)
{
this .data = new List<T>();
this .comparer = comparer;
}
public int Count
{
get { return data.Count; }
}
public T Peek()
{
return data[0];
}
public void Enqueue(T item)
{
data.Add(item);
int childIndex = data.Count - 1;
while (childIndex > 0)
{
int parentIndex = (childIndex - 1) / 2;
if (comparer.Compare(data[childIndex], data[parentIndex]) >= 0)
break ;
T tmp = data[childIndex];
data[childIndex] = data[parentIndex];
data[parentIndex] = tmp;
childIndex = parentIndex;
}
}
public T Dequeue()
{
int lastIndex = data.Count - 1;
T frontItem = data[0];
data[0] = data[lastIndex];
data.RemoveAt(lastIndex);
lastIndex--;
int parentIndex = 0;
while ( true )
{
int leftChild = parentIndex * 2 + 1;
if (leftChild > lastIndex)
break ;
int rightChild = leftChild + 1;
if (rightChild <= lastIndex && comparer.Compare(data[rightChild], data[leftChild]) < 0)
leftChild = rightChild;
if (comparer.Compare(data[parentIndex], data[leftChild]) <= 0)
break ;
T tmp = data[parentIndex];
data[parentIndex] = data[leftChild];
data[leftChild] = tmp;
parentIndex = leftChild;
}
return frontItem;
}
}
|
Javascript
class PriorityQueue {
constructor() {
this .queue = [];
}
push(item) {
this .queue.push(item);
this .queue.sort((a, b) => {
if (a[0] === b[0]) {
return a[1] - b[1];
} else {
return a[0] - b[0];
}
});
}
pop() {
return this .queue.shift();
}
top() {
return this .queue[0];
}
empty() {
return this .queue.length === 0;
}
}
function isPossible(nums, k) {
const pq = new PriorityQueue();
let i = 0;
while (i < nums.length) {
if (pq.empty()) {
pq.push([nums[i], 1]);
i++;
} else {
if (nums[i] === pq.top()[0]) {
pq.push([nums[i], 1]);
i++;
} else if (nums[i] === pq.top()[0] + 1) {
const temp = pq.pop();
pq.push([nums[i], temp[1] + 1]);
i++;
} else {
if (pq.top()[1] < k) {
return false ;
}
pq.pop();
}
}
}
while (!pq.empty()) {
if (pq.top()[1] < k) {
return false ;
}
pq.pop();
}
return true ;
}
const vec = [1, 2, 3, 3, 4, 5];
const k = 3;
if (isPossible(vec, k)) {
console.log( "True" );
} else {
console.log( "False" );
}
|
Time Complexity: O(N*log N), where N is the number of elements in the input array. Auxiliary Space: O(N) used by Heap.
|