Showing posts with label cluster of elements in array. Show all posts
Showing posts with label cluster of elements in array. Show all posts

Tuesday, 26 May 2015

Counting Max Consecutive elements in an array!!

Hello friends,

In this post, I would like to present a problem I encountered where we need to find consecutive occurrence of elements in a 2D matrix of N * N size. If  a cell has same element as contained by itself in the  top, bottom , right or left direct neighbor cell, then these two cells are said to have consecutive  occurrence of same element .
The consecutive same elements form a cluster  (sector).
The problem is to find the number of such clusters of same elements and to find the maximum size of the cluster.

For example
Input
N = 5;

Matrix :
{ 1, 1, 1, 0, 0 },
{ 1, 0, 1, 0, 0 },
{ 1, 0, 1, 0, 1 },
{ 1, 0, 0, 0, 1 },
{ 0, 1, 0, 1, 1 }

Solution :

We can see we have three clusters with sizes as 8, 4 and 1.

So we need to output number of clusters followed by a space and then need to output the maximum size;

Output : 3 8



Lets see the code for this problem. I have used a stack for brack-tracing in this problem ( implemented the basic stack using array, although I could have used the java.util.Stack or simply ArrayList which would have reduced few lines of code, but anyways I choose to use basic array based Stack) In the program below I have used 'sector' instead of cluster.


There can be a approach using recursion, but I find understanding the code execution flow better in iterative manner.

public class LargestGridSector {
 /// input starts
 public static int data[][] = 
                                    { { 1, 1, 1, 0, 0 }, 
                                    { 1, 0, 1, 0, 0 }, 
                                    { 1, 0, 1, 0, 1 }, 
                                    { 1, 0, 0, 0, 1 }, 
                                    { 0, 1, 0, 1, 1 } };
 public static int N = 5;
 /// input ends

 public static void main(String[] args) {
  largedtGridSector();
  System.out.println(numOfSectors +" "+maxSectorSize);
 }

 public static class Point {
  int x;
  int y;

  public Point(int x, int y) {
   this.x = x;
   this.y = y;
  }
 }

 public static int largedtGridSector = 0;
 public static final int ONE = 1;
 public static final int ZERO = 0;
 public static final int VISITED = 3;
 public static final int INSTACK = 2;
 public static int numOfSectors = 0;
 public static int maxSectorSize = 0;
 public static int currentSectorSize = 0;
 public static Point[] stack = new Point[N * N];
 public static int stackIndex = -1;

 public static void largedtGridSector() {
  for (int i = 0; i < N; i++) {
   for (int j = 0; j < N; j++) {
    switch (data[i][j]) {
    case ONE:
     int x = i;
     int y = j;
     numOfSectors++;
     currentSectorSize = 0;
     boolean toBreakWhile = false;
     while (true) {
      switch (data[x][y]) {
      case ONE:
       Point p = new Point(x, y);
       push(p);
       data[p.x][p.y] = INSTACK;
       currentSectorSize++;
       if (y < N - 1 && data[x][y + 1] == ONE) {
        y++;
       } else if (y > 0 && data[x][y - 1] == ONE) {
        y--;
       } else if (x < N - 1 && data[x + 1][y] == ONE) {
        x++;
       } else if (x > 0 && data[x - 1][y] == ONE) {
        x--;
       } else if (stackIndex >= 0) {
        Point prePoint = pop();
        data[prePoint.x][prePoint.y] = VISITED;
        if (stackIndex >= 0) {
         x = stack[stackIndex].x;
         y = stack[stackIndex].y;
        }
       }
       break;
      case INSTACK:
       if (y < N - 1 && data[x][y + 1] == ONE) {
        y++;
       } else if (y > 0 && data[x][y - 1] == ONE) {
        y--;
       } else if (x < N - 1 && data[x + 1][y] == ONE) {
        x++;
       } else if (x > 0 && data[x - 1][y] == ONE) {
        x--;
       } else if (stackIndex >= 0) {
        Point prePoint = pop();
        data[prePoint.x][prePoint.y] = VISITED;
        if (stackIndex >= 0) {
         x = stack[stackIndex].x;
         y = stack[stackIndex].y;
        }
       }
       break;
      default:
       toBreakWhile = true;
       break;
      }
      if (stackIndex < 0 || toBreakWhile) {
       break;
      }
     }
     if (currentSectorSize > maxSectorSize) {
      maxSectorSize = currentSectorSize;
     }
     break;
    default:
     continue;
    }
   }
  }
 }

 public static void push(Point p) {
  stackIndex++;
  stack[stackIndex] = p;
 }

 public static Point pop() {
  Point p = stack[stackIndex];
  stack[stackIndex] = null;
  stackIndex--;
  return p;
 }

}