Sunday, April 3, 2016

Find the smallest window within an array that contains all the elements of another array

Java Program:

package com.sourabh.test;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;

public class MinimumArrayContains {
 class Interval
 {
  private int start;
  private int end;
  public Interval()
  {
   super();
  }
  public Interval(int start, int end) {
   super();
   this.start = start;
   this.end = end;
  }
  public int getStart() {
   return start;
  }
  public void setStart(int start) {
   this.start = start;
  }
  public int getEnd() {
   return end;
  }
  public void setEnd(int end) {
   this.end = end;
  }
 }
 
 Map<Integer, Boolean> map = new HashMap<>();
 Queue<Integer> queue = new LinkedList<>();
 public void resetMap(int... A) {
  for(int i=0;i<A.length;i++) {
   map.put(A[i], false);
  }
 }
 
 public Interval resetQueue() {
  int start = queue.peek();
  int end = 0;
  while(!queue.isEmpty()) {
   end = queue.remove();
  }
  return new Interval(start, end);
 }
 
 public List<Interval> getIntervals(int[] A1, int[] A2) {
  int found = 0;
  int end = 0;
  List<Interval> intervalsContainingAllElementsOfA2 = new ArrayList<>();
  resetMap(A2);
  for(int i=0; i<A1.length; i++) {
   if(map.containsKey(A1[i])) {
    if(map.get(A1[i]) == false) {
     found++;
     map.put(A1[i], true);
    }
    if(queue.peek()!= null && A1[i] == A1[queue.peek()]) {
     queue.remove();
    }
    queue.add(i);
    end = i;
   }
   if(found == A2.length) {
    int start = queue.peek();
    intervalsContainingAllElementsOfA2.add(new Interval(start, end));
    int prevIndex = queue.remove();
    map.put(A1[prevIndex], false);
    found--;
    int currIndex = queue.remove();
    map.put(A1[currIndex], false);
    found--;
    while(currIndex - prevIndex ==1) {
     prevIndex = currIndex;
     currIndex = queue.remove();
     found--;
     map.put(A1[currIndex], false);
    }
    i = currIndex;
    queue.add(currIndex);
    map.put(A1[currIndex], true);
    found++;
   }
  }
  return intervalsContainingAllElementsOfA2;
 }
 
 public Interval getMinimumInterval(int[] A1, int[] A2) {
  List<Interval> intervalsList = getIntervals(A1, A2);
  Interval minInterval = intervalsList.get(0);
  for(Interval interval : intervalsList) {
   if(interval.getEnd() - interval.getStart() < minInterval.getEnd() - minInterval.getStart()) {
    minInterval = interval;
   }
  }
  return minInterval;
 }
}

Unit Tests:
package com.sourabh.test;

import java.util.LinkedList;
import java.util.List;
import java.util.Queue;

import org.junit.Test;
import org.junit.Assert;
import com.sourabh.test.MinimumArrayContains.Interval;

public class QueueTest {

 Queue<Integer> queue = new LinkedList<>();
 MinimumArrayContains instance = new MinimumArrayContains();
 
 @Test
 public void testQueueFunctions() {
  queue.add(1);
  queue.add(2);
  queue.add(3);
  queue.add(4);
  Assert.assertTrue(queue.peek() == 1);
  Assert.assertTrue(queue.remove() == 1);
  Assert.assertTrue(queue.peek() == 2);
  Assert.assertTrue(queue.remove() == 2);
 }
 
 @Test
 public void testGetMinInterval1() {
  int[] A1 = {1,2,3,1,2,1,4,6,5,4,2,3,4,1};
  int[] A2 = {1,2,4,5};
  Interval interval = instance.getMinimumInterval(A1, A2);
  Assert.assertEquals(4, interval.getStart());
  Assert.assertEquals(8, interval.getEnd());
 }
 
 @Test
 public void testGetMinInterval2() {
  int[] A1 = {6, 7, 1, 3, 2, 4, 5, 2, 3, 1, 2, 5};
  int[] A2 = {1, 3, 5};
  Interval interval = instance.getMinimumInterval(A1, A2);
  Assert.assertEquals(3, interval.getEnd() - interval.getStart());
 }
}

1 comment: