Skip to main content

Find minimum sub-array which has 1 to k numbers in java


Suppose we have one array:
4, 5, 6, 7, 1, 2,1,, 4, 5, 3, 6, 7, 10, 1, 2, 3, 4
And k=4, that means we have to find the sub array which has all the elements 1, 2, 3, 4
and the array length should be minimum.
Intuition: First we will just find the index till where we can get all the numbers then we will proceed to minimize the size of the sub-array.
So as we can see till index we can get all the desired numbers. Then we will try to minimize this length. And by minimizing means we can get another sub array which is minimum as in this case which is: 1,2,3,4 at last in the array.
So we go ahead using this method we can get the minimum sub array having 1 to k numbers.
Code in Java:
public class NumbersfromOnetoK {
    public static void main(String[] args) {
 NumbersfromOnetoK m = new NumbersfromOnetoK();
        int[] arr={4, 5, 6, 1, 7, 1, 2, 4, 5, 3, 6, 7, 10, 1, 2, 3, 4}; 
        int k=4;
        m.findSubArrayWith_1_to_K_Numbers();
    }


    private void findSubArrayWith_1_to_K_Numbers(int[] arr, int k){
 int strtInd=0,endInd=0,digCount=0;
 int[] kArr=new int[k+1];
        /*
  * First find the sub array in which 1 to k number exist, it may 
  * not be the minimal
  * */
 for(int i=0;i<arr.length;i++){  
     if(arr[i] <=k && arr[i] >=1){
  if(kArr[arr[i]]==0) digCount++;    // count of digits from 1...k
  kArr[arr[i]]++;
  if(digCount == k) {endInd=i;break;}
     }
 }
 
 int min_len=endInd-strtInd+1; // initially we let this is min 
        int tempInd=endInd;
 int i=strtInd;
 
        while(tempInd<arr.length){
     if(arr[i]<=k){
  kArr[arr[i]]--;
  if(kArr[arr[i]] == 0){
      kArr[arr[i]]++; // retain digits's count

                    // calculating new minimum
      if(tempInd-i+1 < min_len){
   min_len=tempInd-i+1;
   strtInd=i;endInd=tempInd;
      }
                    
                    // increase tempInd when it is under array length
      if(tempInd < arr.length)
   tempInd++;

                    // skipping nos which are not in range 1..k
      while(tempInd < arr.length && arr[tempInd] > k)tempInd++;

      // if no is in 1..k then increment its count in kArray
                    if(tempInd < arr.length)
   kArr[arr[tempInd]]++;
  }
  else
       i++; // increase i when the dig count in not reduced
     }
     else
  i++; // increase i if no is out of range 1..k
     
 }
        //print start and end index of sub array
 System.out.println(strtInd+" "+endInd+" len="+min_len); // final answer
    }
}
Time Complexity : O(n) 
Space Complexity : O(k) 

Logic: The whole logic includes below points:


Phase 1:



  1. make an array of size k+1 to store count of numbers from 1..k , skipping index 0 as we are not including 0 Array name in code is : kArr 
  2. Run the loop and increase count as : kArr[arr[i]]++; 
  3. Also unique digits(under 1..k) count using digCount 
  4. When diCount becomes k then stop the loop. 
Phase 2:


  1. Assign the below values to variables: tempInd = end index where we have stopped the loop min_len = endInd - strtind +1 ; i = strtInd; 
  2. Run a while loop till the end of array in search of minimum length of sub-array containing 1..k
  3. Treat the sub-array which we got from phase 1 as window. 
  4. Now we will try to decrease window from left as in our case after phase 1 we have kArray as (digit - count): endInd = 9, strtInd = 0, min_len = 11 1 - 2, 2 - 1, 3 - 1, 4 - 2 
  5. When we try to reduce the window, we have 4 on left so reducing the count is not making the count of 4 as 0 in kArray so that means we can reduce the window. kArray : 1 - 2, 2 - 1, 3 - 1, 4 - 1 and index i = 4 
  6. Now we will increment i=1 from i=0; 
  7. We again try to decrease window from left, we get 5 which is not our number, index i = 2 
  8. We got 6 which is again not our number(in range 1..k) and index i = 3 
  9. We got 1, can we reduce it ? Yes as we have count = 2 for 1 The kArray : 1 - 1, 2 - 1, 3 - 1, 4 - 1 and index i = 4 
  10. Again we try to reduce, at i = 4 we have 7 so just increment i at i = 5 we have 1, but when we try to reduce the count in kArray will become 0 for 1 
  11. That means we cannot reduce from left now.
  12. So we will increase the window from right And we will accommodate new numbers(in 1..k) in search of minimum sub-array 
  13. Update minimum length if possible 
  14. In this case we have skipped number 6, 7, 10 as they are out of range. 
  15. And tempInd increased to 13 and we got 1 so we incremented count of 1 from 1 to 2The kArray : 1 - 2, 2 - 1, 3 - 1, 4 - 1 
  16. And again we will try to decrease window from left 
  17. Means we can as i = 5 is 1 and we can decrease count of 1 to 1 from 2, index i = 6 
  18. Now again try to decrease window from left, i = 6 is 2 The kArray : 1 - 1, 2 - 1, 3 - 1, 4 - 1 and index i = 6 
  19. Count in kArray for 2 will become 0, so we will update min_len 
  20. And then increase window to right 
  21. We got 2 at tempInd = 14 and increase count of 2 in kArray: The kArray : 1 - 1, 2 - 2, 3 - 1, 4 - 1 and index i = 6, tempInd = 14 
  22. Now we can decrease window form left so : The kArray : 1 - 1, 2 - 1, 3 - 1, 4 - 1 and index i = 7 
  23. @Index i = 7, we have 4, when we try to decrease window from left count of 4 will become 0 so we will try to increase window from right 
  24. Update min_len, increment tempInd to 15 and we get number 3, The kArray : 1 - 1, 2 - 1, 3 - 2, 4 - 1 and index i = 7 
  25. We can't decrease window from left as same problem described in point 25 
  26. Update min_len, increment tempInd to 16 and we get number 4 The kArray : 1 - 1, 2 - 1, 3 - 2, 4 - 2 and index i = 7 
  27. Now we can reduce array from left and index i = 8 The kArray : 1 - 1, 2 - 1, 3 - 2, 4 - 1 and index i = 8 
  28. Again try to reduce from left: YES we can The kArray : 1 - 1, 2 - 1, 3 - 1, 4 - 1 and index i = 9
  29. And i will get incremented to 12 as numbers are out of range. 
  30. Now when we will try to decrease window from left which we cannot 
  31. Update minimum length which is min_len= tempInd - i +1 = 16 - 13 + 1 = 4 
  32. We increase tempInd but tempInd will become 17 which is > arr.length 
  33. We come out of the while loop, print the strtInd and endInd updated during the process and length of the sub-array

Thanks for Reading! 

Have a good one :)

Comments

Popular posts from this blog

Goodness of Fit Test for normal and poisson distribution

Meaning of Goodness of fit test: We find out which distribution fits the sample data the most. And this is achieved using chi-square distribution (Snedecor and Cochran, 1989). How to apply: There are 4 steps to follow: State the hypothesis:  Data follows a distribution or not Criteria to reject null hypothesis: if Χ 2  > Χ 2 (k,1-α) then reject null hypothesis. Analyze sample data: Compute the chi-square value using below formula: ∑(Oi- Ei) 2 /Ei        : Oi is observed frequency and Ei is expected frequency Interpret the results: Declare the results after comparing the values of Χ 2 and Χ 2 (k,1-α), where k is degree of freedom and  α is significance level. Degree of Freedom: It is  =  n - 1 - m m: number of parameter in the distribution. So in case of normal distribution m is 2 ( μ ,α) and in case of poisson dist. m is = 1 ( λ). Example 1: Goodness of fit test for Normal Distribution Year wise data is given about number of car accidents, find out w

classification of database indexing

Dense Index: For every records we are having one entry in the index file. Sparse Index: Only one record for each block we will have it in the index file. Primary Index ( Primary Key + Ordered Data )  A primary index is an ordered file whose records are fixed length size with 2 fields. First field is same as primary key and the second field is pointer to the data block.  Here index entry is created for first record of each block, called ‘block anchor’. Number of index entries thus are equal to number of blocks Average number of block accesses are = logB (worst case) + 1 (best case),  So on average it will be O(logB) The type of index is called sparse index because index is not created for all the records, only the first records of every block the entry is made into the index file. Example on Primary Index Number of Records = 30000, Block Size = 1024 Bytes, Strategy = Unspanned, Record Size = 100 Bytes, Key Size = 6 Bytes, Pointer Size = 9 Bytes, Then find avera

Red Black Tree Insertion in Java

Red Black Tree is a binary search tree. With extra property with each node having color either RED or BLACK. It has following properties: Every node is either RED or BLACK Root element will have BLACK color. Every RED node has BLACK children. Every path from root to leaf will have same number of BLACK nodes. We have few theorems over RB tree: Note: Height of RB tree is θ(logn). Insertion: Insertion in RB tree is little tricky as compared to BST, we have following cases to insert a node in RB tree: When tree is null just insert the node and it will be root, color will be BLACK. To insert an element first find its position: if key <= node.key then move to left else move to right Once we find the correct place to insert, we insert the node with color RED. But if the parent of the node just inserted has color RED then it will violate 3 property. So we have to fix this issue. We call it double RED problem, we resolve it using following few cases. DOUBLE R