37. Split Array into Consecutive Subsequences

Topic :

hashing

Difficulty :

medium

Problem Link :


problem statement

You are given an integer array nums that is sorted in non-decreasing order.

Determine if it is possible to split nums 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 3 or more.

Return true if you can split nums according to the above conditions, or false otherwise.

A subsequence of an array is a new array that is formed from the original array by deleting some (can be none) of the elements without disturbing the relative positions of the remaining elements. (i.e., [1,3,5] is a subsequence of [1,2,3,4,5] while [1,3,2] is not).

Example 1:

Input: nums = [1,2,3,3,4,5]
Output: true
Explanation: nums 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
Example 2:

Input: nums = [1,2,3,3,4,4,5,5]
Output: true
Explanation: nums can be split into the following subsequences:
[1,2,3,3,4,4,5,5] --> 1, 2, 3, 4, 5
[1,2,3,3,4,4,5,5] --> 3, 4, 5
Example 3:

Input: nums = [1,2,3,4,4,5]
Output: false
Explanation: It is impossible to split nums into consecutive increasing 
subsequences of length 3 or more.

Constraints:

  • 1 <= nums.length <= 104
  • -1000 <= nums[i] <= 1000
  • nums is sorted in non-decreasing order.

solution

APPROACH: USING 2 HASHMAPS

TIME COMPLEXITY : O(N)

SPACE COMPLEXITY: O(N)+O(N)

import java.io.*;
import java.util.*; 
class Split_Array_into_Consecutive_Subsequences
{
 public static void main(String args[]){
    int nums[]={1,2,3,3,4,5};
    System.out.println(isPossible(nums));
 }
 static boolean isPossible(int[] nums) {
     //isAvailable map shows if a ele is available to be part of a subsequence
     // ele-->0 that means this element is not availabe to be a part of a subsequence
     // as it might already be present in another subsequence
     // ele--> >0 that means the ele is present to be a part of the subsequence
     // for e.g ele-->x means there are x no.of ele that are present to be part of a subsequence 
     HashMap<Integer,Integer> isAvailable=new HashMap<>();
     
     //isNeeded map shows if an ele is needed in a particular subsequence
     //if an element is present in the isNeeded map that means there exists a sequence
     //ending with ele-1 and hence ele can be a part of this subsequence    
     // suppose there is a subsequence 1--2--3
     //then isNeeded map will have 4-->1
     //which means there is a subsequence ending with 3 and hence 4 can be a part of it   
     HashMap<Integer,Integer> isNeeded=new HashMap<>();
     
     //initially all elements in the nums array are available to form a subsequence
     for(int ele :nums){
       isAvailable.put(ele,isAvailable.getOrDefault(ele,0)+1);
       isNeeded.put(ele,0);// initially no ele is needed as there are no existing subsequences  
     }
     
     //traverse all elements in the array   
     for(int ele:nums){
       //check if ele is available if not then continue
         
       if(isAvailable.get(ele)<=0)// ele is not available 
       continue;  
      
       else // ele is available
       {
         //check if this ele is needed by an existing subsequence
         //if this ele is needed by an existing subsequence then use it for the subsequence  
         if(isNeeded.get(ele)>0){
           // reduce its freq from the isNeeded map  
           isNeeded.put(ele,isNeeded.get(ele)-1);
           //since this ele is now used hence reduce its availability  
           isAvailable.put(ele,isAvailable.get(ele)-1);  
           // now ele+1 is needed for this subsequence
           isNeeded.put(ele+1,isNeeded.getOrDefault(ele+1,0)+1);  
         }
         
          // ele is not wanted by any pre exisiting subsequence
         //hence we can start a new subsequence with this ele
         //if and only if ele+1,ele+2 are also available
         // so the new probale subsequence will be ele,ele+1,ele+2  
         
         else 
         { // ele+1,ele+2 are available
           if(isAvailable.containsKey(ele+1) && isAvailable.get(ele+1)>0 && 
              isAvailable.containsKey(ele+2) && isAvailable.get(ele+2)>0)
           {  // since ele, ele+1,ele+2 are now used
              // reduce their availability 
              isAvailable.put(ele,isAvailable.get(ele)-1);
              isAvailable.put(ele+1,isAvailable.get(ele+1)-1);
              isAvailable.put(ele+2,isAvailable.get(ele+2)-1); 
              
              //now the next element that is needed for this subsequence is ele+3 
              isNeeded.put(ele+3,isNeeded.getOrDefault(ele+3,0)+1); 
           }
           
           else // we couldn't start a new subsequence from this ele
               return false;
         }  
       }  
     }
        return true;
    }
}
Copyright © 2023 KIZLE. - All Rights Reserved.
Website by Kounik Maitra