Check if given Array can be divided into subsequences of K increasing consecutive integers
Last Updated :
10 Feb, 2023
Given an array arr[] of N integers and a positive integer K, the task is to check if it is possible to divide the array into increasing subsequences of K consecutive integers such each element can contribute in only a single subsequence.
Example:
Input: arr[] = {1, 2, 1, 3, 2, 3}, K = 3
Output: Yes
Explanation: The given array can be divided as {1, 2, 1, 3, 2, 3} => {1, 2, 3} and {1, 2, 1, 3, 2, 3} => {1, 2, 3}. Both subsequences have 3 consecutive integers in increasing order.
Input: arr[] = {4, 3, 1, 2}, K = 2
Output: No
Approach: The above problem can be solved using a Greedy Approach using Binary Search. It can be observed that for any integer arr[i], the most optimal choice is to choose the smallest index of arr[i] + 1 in the subarray arr[i+1, N). Using this observation, follow the below steps to solve the given problem:
- If K is not a divisor of N, no possible set of required subsequences exist. Hence, print No.
- Store the indices of each integer in a Set data structure. It can be efficiently stored using a map that has the structure of key-set pair.
- Maintain a visited array to keep track of indices that are already included in a subsequence.
- Iterate for each i in the range [0, N), and if the integer at the current index is not already visited, perform the following steps:
- Using the upper_bound function, find the smallest index of arr[i] + 1 in the range [i+1, N) and update the value of the last element of the current subsequence with it.
- Repeat the above-mentioned step K-1 number of times until a complete subsequence of K integers has been created.
- During any iteration, if the required integer does not exist, no possible set of required subsequences exist. Hence, print No. Otherwise, print Yes.
Below is the implementation of the above approach:
C++
// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
// Function to check if the array can
// be divided into subsequences of K
// consecutive integers in increasing order
bool isPossible(vector<int> nums, int K)
{
int N = nums.size();
// If N is not divisible by K or
// K>N, no possible set of required
// subsequences exist
if (N % K != 0 || K > N) {
return false;
}
// Stores the indices of each
// element in a set
map<int, set<int> > idx;
// Stores the index of each number
for (int i = 0; i < nums.size(); i++) {
idx[nums[i]].insert(i);
}
// Stores if the integer at current
// index is already included in
// a subsequence
int visited[N] = { 0 };
// Stores the count of total
// visited elements
int total_visited = 0;
for (int i = 0; i < nums.size(); i++) {
// If current integer is already
// in a subsequence
if (visited[i]) {
continue;
}
// Stores the value of last element
// of the current subsequence
int num = nums[i];
// Stores the index of last element
// of the current subsequence
int last_index = i;
// Mark Visited
visited[i] = 1;
// Increment the visited count
total_visited++;
// Find the next K-1 elements of the
// subsequence starting from index i
for (int j = num + 1; j < num + K; j++) {
// No valid index found
if (idx[j].size() == 0) {
return false;
}
// Find index of j such that it
// is greater than last_index
auto it = idx[j].upper_bound(last_index);
// if no such index found,
// return false
if (it == idx[j].end()
|| *it <= last_index) {
return false;
}
// Update last_index
last_index = *it;
// Mark current index as visited
visited[last_index] = 1;
// Increment total_visited by 1
total_visited++;
// Remove the index from set because
// it has been already used
idx[j].erase(it);
}
}
// Return the result
return total_visited == N;
}
// Driver Code
int main()
{
vector<int> arr = { 4, 3, 1, 2 };
int K = 2;
cout << (isPossible(arr, K) ? "Yes" : "No");
return 0;
}
Java
import java.util.*;
class GFG {
// Function to check if the array can
// be divided into subsequences of K
// consecutive integers in increasing order
public static boolean isPossible(List<Integer> nums, int K) {
int N = nums.size();
// If N is not divisible by K or
// K>N, no possible set of required
// subsequences exist
if (N % K != 0 || K > N) {
return false;
}
// Stores the indices of each
// element in a set
Map<Integer, TreeSet<Integer>> idx = new HashMap<>();
// Stores the index of each number
for (int i = 0; i < nums.size(); i++) {
idx.computeIfAbsent(nums.get(i), k -> new TreeSet<>()).add(i);
}
// Stores if the integer at current
// index is already included in
// a subsequence
boolean[] visited = new boolean[N];
// Stores the count of total
// visited elements
int total_visited = 0;
for (int i = 0; i < nums.size(); i++) {
// If current integer is already
// in a subsequence
if (visited[i]) {
continue;
}
// Stores the value of last element
// of the current subsequence
int num = nums.get(i);
// Stores the index of last element
// of the current subsequence
int last_index = i;
// Mark Visited
visited[i] = true;
// Increment the visited count
total_visited++;
// Find the next K-1 elements of the
// subsequence starting from index i
for (int j = num + 1; j < num + K; j++) {
// No valid index found
if (!idx.containsKey(j) || idx.get(j).size() == 0) {
return false;
}
// Find index of j such that it
// is greater than last_index
int next_index = idx.get(j).tailSet(last_index + 1).first();
// if no such index found,
// return false
if (next_index <= last_index) {
return false;
}
// Update last_index
last_index = next_index;
// Mark current index as visited
visited[last_index] = true;
// Increment total_visited by 1
total_visited++;
// Remove the index from set because
// it has been already used
idx.get(j).remove(last_index);
}
}
// Return the result
return total_visited == N;
}
// Driver Code
public static void main(String[] args) {
List<Integer> arr = Arrays.asList(4, 3, 1, 2);
int K = 2;
System.out.println(isPossible(arr, K) ? "Yes" : "No");
}
}
Python3
# Python3 program for the above approach
# Function to check if the array can
# be divided into subsequences of K
# consecutive integers in increasing order
def isPossible(nums, K):
N = len(nums)
# If N is not divisible by K or
# K>N, no possible set of required
# subsequences exist
if (N % K != 0 or K > N):
return False
# Stores the indices of each
# element in a set
idx = {}
# Stores the index of each number
for i in range(N):
if nums[i] in idx:
idx[nums[i]].add(i)
else:
idx[nums[i]] = {i}
# Stores if the integer at current
# index is already included in
# a subsequence
visited = [0]*N
# Stores the count of total
# visited elements
total_visited = 0
for i in range(N):
# If current integer is already
# in a subsequence
if(visited[i]):
continue
# Stores the value of last element
# of the current subsequence
num = nums[i]
# Stores the index of last element
# of the current subsequence
last_index = i
# Marked visited
visited[i] = 1
# Increment the visited count
total_visited += 1
# Find the next K-1 elements of the
# subsequence starting from index i
for j in range(num+1, num+K):
# No valid index found
if j not in idx or len(idx[j]) == 0:
return False
temp = False
# Find index of j such that it
# is greater than last_index
for it in idx[j]:
if it > last_index:
last_index = it
temp = True
break
if(temp == False):
return False
# Update last index
visited[last_index] = 1
# Mark current index as visited
# Increment total_visited by 1
total_visited += 1
# Remove the index
idx[j].remove(it)
# Return the result
return total_visited == N
# Driver code
arr = [4, 3, 1, 2]
K = 2
if (isPossible(arr, K)):
print("Yes")
else:
print("No")
# This code is contributed by parthmanchanda81
C#
using System;
using System.Collections.Generic;
using System.Linq;
public class GFG
{
// Function to check if the array can
// be divided into subsequences of K
// consecutive integers in increasing order
public static bool isPossible(List<int> nums, int K)
{
int N = nums.Count;
// If N is not divisible by K or
// K>N, no possible set of required
// subsequences exist
if (N % K != 0 || K > N) {
return false;
}
// Stores the indices of each
// element in a set
Dictionary<int, SortedSet<int> > idx
= new Dictionary<int, SortedSet<int> >();
// Stores the index of each number
for (int i = 0; i < nums.Count; i++) {
if (!idx.ContainsKey(nums[i])) {
idx.Add(nums[i], new SortedSet<int>());
}
idx[nums[i]].Add(i);
}
// Stores if the integer at current
// index is already included in
// a subsequence
bool[] visited = new bool[N];
// Stores the count of total
// visited elements
int total_visited = 0;
for (int i = 0; i < nums.Count; i++) {
// If current integer is already
// in a subsequence
if (visited[i]) {
continue;
}
// Stores the value of last element
// of the current subsequence
int num = nums[i];
// Stores the index of last element
// of the current subsequence
int last_index = i;
// Mark Visited
visited[i] = true;
// Increment the visited count
total_visited++;
// Find the next K-1 elements of the
// subsequence starting from index i
for (int j = num + 1; j < num + K; j++) {
// No valid index found
if (!idx.ContainsKey(j)
|| idx[j].Count == 0) {
return false;
}
// Find index of j such that it
// is greater than last_index
int next_index
= idx[j]
.Where(x => x > last_index + 1)
.First();
// if no such index found,
// return false
if (next_index <= last_index) {
return false;
}
// Update last_index
last_index = next_index;
// Mark current index as visited
visited[last_index] = true;
// Increment total_visited by 1
total_visited++;
// Remove the index from set because
// it has been already used
idx[j].Remove(last_index);
}
}
// Return the result
return total_visited == N;
}
// Driver Code
static public void Main()
{
List<int> arr = new List<int>{ 4, 3, 1, 2 };
int K = 2;
Console.WriteLine(isPossible(arr, K) ? "Yes"
: "No");
}
}
// This code is contributed by akashish__
JavaScript
<script>
// JavaScript program for the above approach
// Function to check if the array can
// be divided into subsequences of K
// consecutive integers in increasing order
function isPossible(nums, K){
let N = nums.length
// If N is not divisible by K or
// K>N, no possible set of required
// subsequences exist
if (N % K != 0 || K > N)
return false
// Stores the indices of each
// element in a set
let idx = new Map()
// Stores the index of each number
for(let i = 0; i < N; i++){
if(idx.has(nums[i]))
idx.get(nums[i]).add(i)
else{
idx.set(nums[i],new Set())
idx.get(nums[i]).add(i)
}
}
// Stores if the integer at current
// index is already included in
// a subsequence
let visited = new Array(N).fill(0)
// Stores the count of total
// visited elements
total_visited = 0
for(let i=0;i<N;i++){
// If current integer is already
// in a subsequence
if(visited[i])
continue
// Stores the value of last element
// of the current subsequence
let num = nums[i]
// Stores the index of last element
// of the current subsequence
let last_index = i
// Marked visited
visited[i] = 1
// Increment the visited count
total_visited += 1
// Find the next K-1 elements of the
// subsequence starting from index i
for(let j=num+1;j<num+K;j++){
// No valid index found
if(idx.has(j) == false || idx[j].length == 0)
return false
temp = false
// Find index of j such that it
// is greater than last_index
for(let it of idx[j]){
if(it > last_index){
last_index = it
temp = true
break
}
if(temp == false)
return false
}
// Update last index
visited[last_index] = 1
// Mark current index as visited
// Increment total_visited by 1
total_visited += 1
// Remove the index
idx[j].delete(it)
// Return the result
}
}
return (total_visited == N)
}
// Driver code
let arr = [4, 3, 1, 2]
let K = 2
if (isPossible(arr, K))
document.write("Yes","</br>")
else
document.write("No","</br>")
// This code is contributed by shinjanpatra
</script>
Time Complexity: O(N*log N)
Auxiliary Space: O(N)
Similar Reads
Check if an array can be split into subsets of K consecutive elements Given an array arr[] and integer K, the task is to split the array into subsets of size K, such that each subset consists of K consecutive elements. Examples: Input: arr[] = {1, 2, 3, 6, 2, 3, 4, 7, 8}, K = 3 Output: true Explanation: The given array of length 9 can be split into 3 subsets {1, 2, 3}
5 min read
Check if N can be divided into K consecutive elements with a sum equal to N Given an integer N, our task is to check if N can be divided into K consecutive elements with a sum equal to N. Print -1 if it is not possible to divide in this manner, otherwise print the value K.Examples: Input: N = 12 Output: 3 Explanation: The integer N = 12 can be divided into 3 consecutive ele
5 min read
Count subsequences of Array having single digit integer sum K Given an array arr[] and integer K, the task is to count the number of subsequences of the array such that after adding all the elements of that subsequences their single digit integer sum is exactly K. Note: Single digit integer sum is obtained by replacing a number with its digit sum until the num
8 min read
Split Array into Consecutive Subsequences of Size K or more. 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 mor
10 min read
Check if a sorted array can be divided in pairs whose sum is k Given a sorted array of integers and a number k, write a function that returns true if given array can be divided into pairs such that sum of every pair k.Expected time complexity O(n) and extra space O(1). This problem is a variation of below problem, but has a different interesting solution that r
11 min read