import java.util.ArrayDeque;
import java.util.HashMap;
public class SpecialSubstring {
/*
* Question 1 / 2 (Amazon Campus(8): SpecialSubstring)
find the longest substring that has at most 3 different characters.
for example:
the special substring of "abbcddefghhh" is "bbcdd".
*/
static String findsubstring(String a) {
if(a==null) return null;
HashMap<Integer,Integer> map = new HashMap<Integer, Integer>();
int len = a.length(), start=0, end=0, sublen = 0;
for(int i=0,j=0; i<len && j<len; j++){
int tail = a.charAt(j);
if(map.size()<3){//移动j
if(map.containsKey(tail))
map.put(tail, map.get(tail)+1);
else
map.put(tail, 1);
}else if(map.size()==3){
if(map.containsKey(tail))
map.put(tail, map.get(tail)+1);
else{//新的字符,移动i
while(map.size()==3){
int head = a.charAt(i++);
map.put(head, map.get(head)-1);
if(map.get(head)==0)
map.remove(head);
}
map.put(tail, 1);
}
}
//更新
if(j-i+1>sublen){
start = i;
end = j;
sublen=j-i+1;
}
}
if(sublen==0) return null;
else return a.substring(start, end+1);
}
/*
* Question 2 / 2 (Amazon Campus(8): elimination game)
have you played the elimination game before? When you hit a rectangle, other rectangles which are adjacent and in same color will be cleared. We could use a n*m matrix to indicate the game board. Numbers in the matrix indicate different color. Same number means same color.
For example: this is a 5*4 game board:
1 1 2 4
2 3 3 3
2 2 3 5
3 3 3 3
1 2 3 4
The matrix index starts from 0. After you hit the rectangle at (3, 3), all the adjacent rectangle with number 3 will be cleared. We use number 0 to mark the cleared rectangle. The result will be:
1 1 2 4
2 0 0 0
2 2 0 5
0 0 0 0
1 2 0 4
Put gravity into consideration, rectangles which locates on top of the 0-rect will fall down and the result will be like this:
0 0 0 0
1 0 0 0
2 1 0 4
2 2 0 5
1 2 2 4
The question is, given a m*n matrix and a (x,y) indicate which rectangle is hit, compute the result of this hit.
Input:
4 // the number of the columns
5 // the number of the rows
1 1 2 4 // each line of the metrix. Number are separated by space.
2 3 3 3
2 2 3 5
3 3 3 3
1 2 3 4
3 // the x index of the hit position
3 // the y index of the hit position
Output:
0 0 0 0
1 0 0 0
2 1 0 4
2 2 0 5
1 2 2 4
The output should be the matrix status line by line. Within each line, the numbers are separate by space.
*/
static String[] GetEliminationResult(String[] matrixString, int numOfColumn, int numOfRow, int hitXIndex, int hitYIndex) {
/*
matrixString_size is the number of strings stored in the matrixString.
matrixString is an array of strings. Each string is a space seperated string like this "1 1 2 4".
It is a row of the matrix
numOfColumn: Number of the columns in the matrix
numOfRow: Number of rows in the matrix
hitXIndex: the x index of the hit position
hitYIndex: the y index of the hit position
*/
int[][] matrix = new int[numOfRow][numOfColumn];
for(int i=0; i<numOfRow; i++){
String[] row = matrixString[i].split(" ");
for(int j=0; j<numOfColumn; j++)
matrix[i][j]=Integer.parseInt(row[j]);
}
class IntPair{
int x;
int y;
IntPair(int x, int y){
this.x = x;
this.y = y;
}
}
int color = matrix[hitXIndex][hitYIndex];
if(color!=0){
ArrayDeque<IntPair> queue = new ArrayDeque<IntPair>();
matrix[hitXIndex][hitYIndex]=0;
queue.add(new IntPair(hitXIndex, hitYIndex));
while(!queue.isEmpty()){
IntPair cell = queue.poll();
int ax = cell.x, ay = cell.y;
if(ax+1<numOfRow){
if(matrix[ax+1][ay]==color){
matrix[ax+1][ay]=0;
queue.add(new IntPair(ax+1, ay));
}
}
if(ax-1>=0){
if(matrix[ax-1][ay]==color){
matrix[ax-1][ay]=0;
queue.add(new IntPair(ax-1, ay));
}
}
if(ay+1<numOfColumn && matrix[ax][ay+1]==color){
matrix[ax][ay+1]=0;
queue.add(new IntPair(ax, ay+1));
}
if(ay-1>=0 && matrix[ax][ay-1]==color){
matrix[ax][ay-1]=0;
queue.add(new IntPair(ax, ay-1));
}
}
}
//shift matrix
for(int j=0; j<numOfColumn; j++){
int z=numOfRow-1, i=z-1;
while(true){
while(z>=0 && matrix[z][j]!=0) z--;
if(z < 0) break; i=z-1;
while(i>=0 && matrix[i][j]==0) i--;
if(i < 0) break;
matrix[z--][j]=matrix[i][j];
matrix[i--][j]=0;
}
}
//return result
String[] res = new String[numOfRow];
for(int i=0; i<numOfRow; i++){
String row = ""+matrix[i][0];
for(int j=1; j<numOfColumn; j++)
row += " "+matrix[i][j];
res[i] = row;
}
return res;
}
public static void main(String[] args){
String a = "abbcddefghhh";
System.out.println(findsubstring(a));
String[] matrix = new String[]{"1 1 2 4","2 3 3 3","2 2 3 5","3 3 3 3","1 2 3 4"};
String[] res = GetEliminationResult(matrix, 4, 5, 3, 3);
for(String row : res)
System.out.println(row);
}
}