Java:确定2D数组是否有不连续的值

Java:确定2D数组是否有不连续的值,java,arrays,multidimensional-array,Java,Arrays,Multidimensional Array,我有个问题。我在Java中有一个2D数组,我想检查数组是否有不连续的值 例如: True: 1 2 3 3 1 4 4 5 2 6 6 5 7 7 8 8 上面的数组应该返回true,因为数字2出现在两个不连续的区域(第1列第2列和第3列第1列) 上面的数组应该返回false,因为在2个或更多不连续区域中没有出现值。检查下面的代码。这些评论解释了正在发生的事情。 它包含三个类:ArraysMain、Index和扩展ArrayList的IndexList 已更新 基本上,获取所有不同的值并将其存

我有个问题。我在Java中有一个2D数组,我想检查数组是否有不连续的值

例如:

True:
1 2 3 3
1 4 4 5
2 6 6 5
7 7 8 8
上面的数组应该返回true,因为数字2出现在两个不连续的区域(第1列第2列和第3列第1列)


上面的数组应该返回false,因为在2个或更多不连续区域中没有出现值。

检查下面的代码。这些评论解释了正在发生的事情。 它包含三个类:
ArraysMain
Index
和扩展
ArrayList
IndexList

已更新

基本上,获取所有不同的值并将其存储在地图中。对于每个值(如果它出现多次),将有多个索引(值在数组中的位置)

遍历数组,逐个添加每个值的索引。如果遇到一个索引,其rowIndex与所有其他索引的rowIndex不匹配,并且当前值的columnIndex与之相同,则该值是不连续的

public class ArraysMain {

private static final int[][] values = {{1, 2, 3, 3}, {1, 4, 4, 5}, {2, 6, 6, 5}, {7, 7, 8, 8}};
// private static final int[][] values = {{1, 2, 3, 3}, {1, 4, 4, 5}, {6, 7, 7, 5}, {8, 8, 9, 9}};

public static void main(String[] args) {
    System.out.println("Has Discontigous: " + hasDiscontigous());
}

public static boolean hasDiscontigous() {
    // Initialize a map to hold the indexes for each int found
    // For example the value 3 will be mapped to the indexes as shown below
    // (3) -> [0,2], [0,3]
    // (4) -> [1,1], [1,2]
    Map<Integer, IndexList<Index>> map = new HashMap<>();

    // Iterate through the int array and add the indexes per the value
    for (int i = 0; i < values.length; i++) {
        // Get the i-th row
        int[] row = values[i];

        // Iterate through the current row values and add them to the map with the corresponding indexes
        for (int j = 0; j < row.length; j++) {
            // If the map does not contain the j-th value then that value has not been added yet so 
            // Initialize the List
            if (!map.containsKey(row[j])) {
                // Initialize the list
                map.put(row[j], new IndexList<>());
            }

            // Get the value's indexes list and add this value's index
            // If the value is added to the list, 'true' is returned
            boolean add = map.get(row[j]).add(new Index(i, j));

            if (!add) {
                // If false means a discontiguous value has been found
                System.out.println("Value: " + values[i][j] + " is discontigous");
                return true;
            }
        }
    }

    return false;
}

/**
 * This will hold the indexes i.e rowIndex and columnIndex
 */
public static class Index {

    private int rowIndex;
    private int columnIndex;

    public Index(int rowIndex, int columnIndex) {
        this.rowIndex = rowIndex;
        this.columnIndex = columnIndex;
    }

    public int getRowIndex() {
        return rowIndex;
    }

    public void setRowIndex(int rowIndex) {
        this.rowIndex = rowIndex;
    }

    public int getColumnIndex() {
        return columnIndex;
    }

    public void setColumnIndex(int columnIndex) {
        this.columnIndex = columnIndex;
    }

}

/**
 * Extend the {@code ArrayList} object and override the add() method
 * @param <T> 
 */
public static class IndexList<T> extends ArrayList<Index> {

    /**
     * This method determines if a discontigous value has been found. If a value is not discontigous it's indexes are added to the list, 
     * if not, this method returns false
     * @param e
     * @return 
     */
    @Override
    public boolean add(Index e) {
        // Before adding an index object ensure the row or column do not match

        for (Index thi : this) {
            // Check if the rows match
            if (e.rowIndex != thi.rowIndex && e.columnIndex != thi.columnIndex) {
                // If the rowIndex and columnIndex do not match then don't add the value
                return false;
            }

        }

        return super.add(e); //To change body of generated methods, choose Tools | Templates.
    }

}
公共类ArraysMain{
私有静态final int[][]值={{1,2,3,3},{1,4,4,5},{2,6,6,5},{7,7,8,8};
//私有静态final int[][]值={{1,2,3,3},{1,4,4,5},{6,7,5},{8,8,9,9};
公共静态void main(字符串[]args){
System.out.println(“Has unstrigous:+Has unstrigous());
}
公共静态布尔hasinstrigous(){
//初始化映射以保存找到的每个int的索引
//例如,值3将映射到如下所示的索引
// (3) -> [0,2], [0,3]
// (4) -> [1,1], [1,2]
Map Map=newhashmap();
//遍历int数组并为每个值添加索引
对于(int i=0;i

}这里是另一个解决方案。虽然需要优化,但理解起来有点简单

更新:这只是检查每个值是否不连续,如果是,则检查一个或多个值

public class CheckIfDiscontiguous {
public static void main(String args []){
    CheckIfDiscontiguous so = new CheckIfDiscontiguous();
    int[][] input = {{1,2,3,3}, {1,4,4,5}, {2,7,7,5}, {8,8,9,9}};
    System.out.println(so.discontiguousValueCheck(input));
}
public boolean discontiguousValueCheck(int[][] input){
    int m=4;
    int n=4;
    int flag = 0;
    int count = 1;
    int discontiguousCount = 1;
    int[] discontiguousSuspects = new int[16]; 
    int index = 0;
    for(int i=0; i<4; i++){
        for(int j=0; j<4; j++){

            //check for 1st row starts
            //check for (0,0)
            if(i==0 && j==0){    
                if(!(input[0][0]==input[0][1] || input[0][0]==input[1][0])){
                    discontiguousSuspects[index] = input[0][0];
                }
            }
            //check for (0,1)
            if(i==0 && j==1){
                if(!(input[0][1]==input[0][0] || input[0][1]==input[0][2] || input[0][1]==input[1][1])){
                    //System.out.println("goes");
                    discontiguousSuspects[index] = input[0][1];
                    index++;
                    if(discontiguousSuspects.length>=2){
                        for(int k = 0; k<discontiguousSuspects.length; k++){
                            if(discontiguousSuspects[k]==input[0][1]){
                                if(discontiguousCount==2){
                                return true;
                                }
                            }
                        }
                    }
                }
            }
            //check for (0,2)
            if(i==0 && j==2){
                if(!(input[0][2]==input[0][1] || input[0][2]==input[0][3] || input[0][2]==input[1][2])){
                    discontiguousSuspects[index] = input[0][2];
                    index++;
                    if(discontiguousSuspects.length>=2){
                        for(int k = 0; k<discontiguousSuspects.length; k++){
                            if(discontiguousSuspects[k]==input[0][2]){
                                if(discontiguousCount==2){
                                return true;
                                }
                            }
                        }
                    }
                }
            }
            //check for (0,3)
            if(i==0 && j==3){
                if(!(input[0][3]==input[0][2] || input[0][3]==input[1][3])){
                    discontiguousSuspects[index] = input[0][3];
                    index++;
                    if(discontiguousSuspects.length>=2){
                        for(int k = 0; k<discontiguousSuspects.length; k++){
                            if(discontiguousSuspects[k]==input[0][3]){
                                if(discontiguousCount==2){
                                return true;
                                }
                            }
                        }
                    }
                }
            }
            //check for 1st row ends

            //check for 2nd row elements start
            //check for (1,0)
            if(i==1 && j==0){    
                if(!(input[1][0]==input[0][0] || input[1][0]==input[2][0] || input[1][0]==input[1][1])) {
                    discontiguousSuspects[index] = input[1][0];
                    index++;
                    if(discontiguousSuspects.length>=2){
                        for(int k = 0; k<discontiguousSuspects.length; k++){
                            if(discontiguousSuspects[k]==input[1][0]){
                                if(discontiguousCount==2){
                                return true;
                                }
                            }
                        }
                    }
                }
            }
            //check for (1,1)
            if(i==1 && j==1){
                if(!(input[1][1]==input[1][0] || input[1][1]==input[0][1] || input[1][1]==input[1][2] || input[1][1]==input[2][1])){
                    discontiguousSuspects[index] = input[1][1];
                    index++;
                    if(discontiguousSuspects.length>=2){
                        for(int k = 0; k<discontiguousSuspects.length; k++){
                            if(discontiguousSuspects[k]==input[1][1]){
                                if(discontiguousCount==2){
                                return true;
                                }
                            }
                        }
                    }
                }
            }
            //check for (1,2)
            if(i==1 && j==2){
                if(!(input[1][2]==input[1][1] || input[1][2]==input[0][2] || input[1][2]==input[1][3] || input[1][2]==input[2][2])){
                    discontiguousSuspects[index] = input[1][2];
                    index++;
                    if(discontiguousSuspects.length>=2){
                        for(int k = 0; k<discontiguousSuspects.length; k++){
                            if(discontiguousSuspects[k]==input[1][2]){
                                if(discontiguousCount==2){
                                return true;
                                }
                            }
                        }
                    }
                }
            }
            //check for (1,3)
            if(i==1 && j==3){
                if(!(input[1][3]==input[1][2] || input[1][3]==input[0][3] || input[1][3]==input[2][3])){
                    discontiguousSuspects[index] = input[1][3];
                    index++;
                    if(discontiguousSuspects.length>=2){
                        for(int k = 0; k<discontiguousSuspects.length; k++){
                            if(discontiguousSuspects[k]==input[1][3]){
                                if(discontiguousCount==2){
                                return true;
                                }
                            }
                        }
                    }
                }
            }

            //check for 2nd row elements end


            //check for 3rd row elements start
            //check for (2,0)
            if(i==2 && j==0){    
                if(!(input[2][0]==input[1][0] || input[2][0]==input[3][0] || input[2][0]==input[2][1])) {
                    count++;
                    discontiguousSuspects[index] = input[2][0];
                    index++;
                    if(discontiguousSuspects.length>=2){
                        for(int k = 0; k<discontiguousSuspects.length; k++){
                            if(discontiguousSuspects[k]==input[2][0]){
                                if(discontiguousCount==2){
                                return true;
                                }
                                discontiguousCount++;
                            }
                        }
                    }
                }
            }
            //check for (2,1)
            if(i==2 && j==1){
                if(!(input[2][1]==input[2][0] || input[2][1]==input[1][1] || input[2][1]==input[2][2] || input[2][1]==input[3][1])){
                    discontiguousSuspects[index] = input[2][1];
                    index++;
                    if(discontiguousSuspects.length>=2){
                        for(int k = 0; k<discontiguousSuspects.length; k++){
                            if(discontiguousSuspects[k]==input[2][1]){
                                if(discontiguousCount==2){
                                return true;
                                }
                            }
                        }
                    }
                }
            }
            //check for (2,2)
            if(i==2 && j==2){
                if(!(input[2][2]==input[2][1] || input[2][2]==input[1][2] || input[2][2]==input[2][3] || input[2][2]==input[3][2])){
                    discontiguousSuspects[index] = input[2][2];
                    index++;
                    if(discontiguousSuspects.length>=2){
                        for(int k = 0; k<discontiguousSuspects.length; k++){
                            if(discontiguousSuspects[k]==input[2][2]){
                                if(discontiguousCount==2){
                                return true;
                                }
                            }
                        }
                    }
                }
            }
            //check for (2,3)
            if(i==2 && j==3){
                if(!(input[2][3]==input[2][2] || input[2][3]==input[1][3] || input[2][3]==input[3][3])){
                    discontiguousSuspects[index] = input[1][3];
                    index++;
                    if(discontiguousSuspects.length>=2){
                        for(int k = 0; k<discontiguousSuspects.length; k++){
                            if(discontiguousSuspects[k]==input[2][3]){
                                if(discontiguousCount==2){
                                return true;
                                }
                            }
                        }
                    }
                }
            }

            //check for 3rd row elements end

            //check for 4th row starts
            //check for (3,0)
            if(i==3 && j==0){    
                if(!(input[3][0]==input[3][1] || input[3][0]==input[2][0])){
                    discontiguousSuspects[index] = input[3][0];
                    index++;
                    if(discontiguousSuspects.length>=2){
                        for(int k = 0; k<discontiguousSuspects.length; k++){
                            if(discontiguousSuspects[k]==input[2][3]){
                                if(discontiguousCount==2){
                                return true;
                                }
                            }
                        }
                    }
                }
            }
            //check for (3,1)
            if(i==3 && j==1){
                if(!(input[3][1]==input[3][0] || input[0][1]==input[3][2] || input[3][1]==input[2][1])){
                    discontiguousSuspects[index] = input[3][1];
                    index++;
                    if(discontiguousSuspects.length>=2){
                        for(int k = 0; k<discontiguousSuspects.length; k++){
                            if(discontiguousSuspects[k]==input[3][1]){
                                if(discontiguousCount==2){
                                return true;
                                }
                            }
                        }
                    }
                }
            }
            //check for (3,2)
            if(i==3 && j==2){
                if(!(input[3][2]==input[3][1] || input[3][2]==input[3][3] || input[3][2]==input[2][2])){
                    discontiguousSuspects[index] = input[3][2];
                    index++;
                    if(discontiguousSuspects.length>=2){
                        for(int k = 0; k<discontiguousSuspects.length; k++){
                            if(discontiguousSuspects[k]==input[3][2]){
                                if(discontiguousCount==2){
                                return true;
                                }
                            }
                        }
                    }
                }
            }
            //check for (3,3)
            if(i==0 && j==3){
                if(!(input[3][3]==input[3][2] || input[3][3]==input[2][3])){
                    discontiguousSuspects[index] = input[3][3];
                    index++;
                    if(discontiguousSuspects.length>=2){
                        for(int k = 0; k<discontiguousSuspects.length; k++){
                            if(discontiguousSuspects[k]==input[3][3]){
                                if(discontiguousCount==2){
                                return true;
                                }
                            }
                        }
                    }
                }
            }
            //check for 3rd row ends

        }
    }
    return false;
}
公共类检查不连续{
公共静态void main(字符串参数[]){
checkifuncontriguous so=新的checkifuncontriguous();
int[]input={{1,2,3,3},{1,4,4,5},{2,7,5},{8,8,9,9};
System.out.println(so.uncontigurationvaluecheck(input));
}
公共布尔不连续值检查(int[][]输入){
int m=4;
int n=4;
int标志=0;
整数计数=1;
int不连续计数=1;
int[]不连续嫌疑犯=新int[16];
int指数=0;

对于(int i=0;i基本上,我们需要对每个数组值的位置进行分组。一旦我们知道所有位置,我们需要确定这些位置是否都是相邻的(对于每个位置1,存在距离(位置1,位置2)<2的位置2)


由于它是一个二维数组,我还没有找到一种方法,我无法对数组进行排序,因为我想检查未排序的二维数组中是否有不连续的值。是否接受相邻的数字?值是否可以对角连续?是的,只要数字水平或垂直连续,就可以接受。值不能对角连续y、 让我测试下面的解决方案…它为
private static final int[][]值={{{1,2},{2,2}生成错误的结果
@Kihats感谢您的回答,但是SME\u Dev发现您的解决方案有一个错误。@michaeladrian39 SME\u Dev的示例,
true
false
的预期结果是什么?
int[]input={{1,
2
,3,3},{1,1,4,5},{
2
,7,5},{8,2,9,
public class CheckIfDiscontiguous {
public static void main(String args []){
    CheckIfDiscontiguous so = new CheckIfDiscontiguous();
    int[][] input = {{1,2,3,3}, {1,4,4,5}, {2,7,7,5}, {8,8,9,9}};
    System.out.println(so.discontiguousValueCheck(input));
}
public boolean discontiguousValueCheck(int[][] input){
    int m=4;
    int n=4;
    int flag = 0;
    int count = 1;
    int discontiguousCount = 1;
    int[] discontiguousSuspects = new int[16]; 
    int index = 0;
    for(int i=0; i<4; i++){
        for(int j=0; j<4; j++){

            //check for 1st row starts
            //check for (0,0)
            if(i==0 && j==0){    
                if(!(input[0][0]==input[0][1] || input[0][0]==input[1][0])){
                    discontiguousSuspects[index] = input[0][0];
                }
            }
            //check for (0,1)
            if(i==0 && j==1){
                if(!(input[0][1]==input[0][0] || input[0][1]==input[0][2] || input[0][1]==input[1][1])){
                    //System.out.println("goes");
                    discontiguousSuspects[index] = input[0][1];
                    index++;
                    if(discontiguousSuspects.length>=2){
                        for(int k = 0; k<discontiguousSuspects.length; k++){
                            if(discontiguousSuspects[k]==input[0][1]){
                                if(discontiguousCount==2){
                                return true;
                                }
                            }
                        }
                    }
                }
            }
            //check for (0,2)
            if(i==0 && j==2){
                if(!(input[0][2]==input[0][1] || input[0][2]==input[0][3] || input[0][2]==input[1][2])){
                    discontiguousSuspects[index] = input[0][2];
                    index++;
                    if(discontiguousSuspects.length>=2){
                        for(int k = 0; k<discontiguousSuspects.length; k++){
                            if(discontiguousSuspects[k]==input[0][2]){
                                if(discontiguousCount==2){
                                return true;
                                }
                            }
                        }
                    }
                }
            }
            //check for (0,3)
            if(i==0 && j==3){
                if(!(input[0][3]==input[0][2] || input[0][3]==input[1][3])){
                    discontiguousSuspects[index] = input[0][3];
                    index++;
                    if(discontiguousSuspects.length>=2){
                        for(int k = 0; k<discontiguousSuspects.length; k++){
                            if(discontiguousSuspects[k]==input[0][3]){
                                if(discontiguousCount==2){
                                return true;
                                }
                            }
                        }
                    }
                }
            }
            //check for 1st row ends

            //check for 2nd row elements start
            //check for (1,0)
            if(i==1 && j==0){    
                if(!(input[1][0]==input[0][0] || input[1][0]==input[2][0] || input[1][0]==input[1][1])) {
                    discontiguousSuspects[index] = input[1][0];
                    index++;
                    if(discontiguousSuspects.length>=2){
                        for(int k = 0; k<discontiguousSuspects.length; k++){
                            if(discontiguousSuspects[k]==input[1][0]){
                                if(discontiguousCount==2){
                                return true;
                                }
                            }
                        }
                    }
                }
            }
            //check for (1,1)
            if(i==1 && j==1){
                if(!(input[1][1]==input[1][0] || input[1][1]==input[0][1] || input[1][1]==input[1][2] || input[1][1]==input[2][1])){
                    discontiguousSuspects[index] = input[1][1];
                    index++;
                    if(discontiguousSuspects.length>=2){
                        for(int k = 0; k<discontiguousSuspects.length; k++){
                            if(discontiguousSuspects[k]==input[1][1]){
                                if(discontiguousCount==2){
                                return true;
                                }
                            }
                        }
                    }
                }
            }
            //check for (1,2)
            if(i==1 && j==2){
                if(!(input[1][2]==input[1][1] || input[1][2]==input[0][2] || input[1][2]==input[1][3] || input[1][2]==input[2][2])){
                    discontiguousSuspects[index] = input[1][2];
                    index++;
                    if(discontiguousSuspects.length>=2){
                        for(int k = 0; k<discontiguousSuspects.length; k++){
                            if(discontiguousSuspects[k]==input[1][2]){
                                if(discontiguousCount==2){
                                return true;
                                }
                            }
                        }
                    }
                }
            }
            //check for (1,3)
            if(i==1 && j==3){
                if(!(input[1][3]==input[1][2] || input[1][3]==input[0][3] || input[1][3]==input[2][3])){
                    discontiguousSuspects[index] = input[1][3];
                    index++;
                    if(discontiguousSuspects.length>=2){
                        for(int k = 0; k<discontiguousSuspects.length; k++){
                            if(discontiguousSuspects[k]==input[1][3]){
                                if(discontiguousCount==2){
                                return true;
                                }
                            }
                        }
                    }
                }
            }

            //check for 2nd row elements end


            //check for 3rd row elements start
            //check for (2,0)
            if(i==2 && j==0){    
                if(!(input[2][0]==input[1][0] || input[2][0]==input[3][0] || input[2][0]==input[2][1])) {
                    count++;
                    discontiguousSuspects[index] = input[2][0];
                    index++;
                    if(discontiguousSuspects.length>=2){
                        for(int k = 0; k<discontiguousSuspects.length; k++){
                            if(discontiguousSuspects[k]==input[2][0]){
                                if(discontiguousCount==2){
                                return true;
                                }
                                discontiguousCount++;
                            }
                        }
                    }
                }
            }
            //check for (2,1)
            if(i==2 && j==1){
                if(!(input[2][1]==input[2][0] || input[2][1]==input[1][1] || input[2][1]==input[2][2] || input[2][1]==input[3][1])){
                    discontiguousSuspects[index] = input[2][1];
                    index++;
                    if(discontiguousSuspects.length>=2){
                        for(int k = 0; k<discontiguousSuspects.length; k++){
                            if(discontiguousSuspects[k]==input[2][1]){
                                if(discontiguousCount==2){
                                return true;
                                }
                            }
                        }
                    }
                }
            }
            //check for (2,2)
            if(i==2 && j==2){
                if(!(input[2][2]==input[2][1] || input[2][2]==input[1][2] || input[2][2]==input[2][3] || input[2][2]==input[3][2])){
                    discontiguousSuspects[index] = input[2][2];
                    index++;
                    if(discontiguousSuspects.length>=2){
                        for(int k = 0; k<discontiguousSuspects.length; k++){
                            if(discontiguousSuspects[k]==input[2][2]){
                                if(discontiguousCount==2){
                                return true;
                                }
                            }
                        }
                    }
                }
            }
            //check for (2,3)
            if(i==2 && j==3){
                if(!(input[2][3]==input[2][2] || input[2][3]==input[1][3] || input[2][3]==input[3][3])){
                    discontiguousSuspects[index] = input[1][3];
                    index++;
                    if(discontiguousSuspects.length>=2){
                        for(int k = 0; k<discontiguousSuspects.length; k++){
                            if(discontiguousSuspects[k]==input[2][3]){
                                if(discontiguousCount==2){
                                return true;
                                }
                            }
                        }
                    }
                }
            }

            //check for 3rd row elements end

            //check for 4th row starts
            //check for (3,0)
            if(i==3 && j==0){    
                if(!(input[3][0]==input[3][1] || input[3][0]==input[2][0])){
                    discontiguousSuspects[index] = input[3][0];
                    index++;
                    if(discontiguousSuspects.length>=2){
                        for(int k = 0; k<discontiguousSuspects.length; k++){
                            if(discontiguousSuspects[k]==input[2][3]){
                                if(discontiguousCount==2){
                                return true;
                                }
                            }
                        }
                    }
                }
            }
            //check for (3,1)
            if(i==3 && j==1){
                if(!(input[3][1]==input[3][0] || input[0][1]==input[3][2] || input[3][1]==input[2][1])){
                    discontiguousSuspects[index] = input[3][1];
                    index++;
                    if(discontiguousSuspects.length>=2){
                        for(int k = 0; k<discontiguousSuspects.length; k++){
                            if(discontiguousSuspects[k]==input[3][1]){
                                if(discontiguousCount==2){
                                return true;
                                }
                            }
                        }
                    }
                }
            }
            //check for (3,2)
            if(i==3 && j==2){
                if(!(input[3][2]==input[3][1] || input[3][2]==input[3][3] || input[3][2]==input[2][2])){
                    discontiguousSuspects[index] = input[3][2];
                    index++;
                    if(discontiguousSuspects.length>=2){
                        for(int k = 0; k<discontiguousSuspects.length; k++){
                            if(discontiguousSuspects[k]==input[3][2]){
                                if(discontiguousCount==2){
                                return true;
                                }
                            }
                        }
                    }
                }
            }
            //check for (3,3)
            if(i==0 && j==3){
                if(!(input[3][3]==input[3][2] || input[3][3]==input[2][3])){
                    discontiguousSuspects[index] = input[3][3];
                    index++;
                    if(discontiguousSuspects.length>=2){
                        for(int k = 0; k<discontiguousSuspects.length; k++){
                            if(discontiguousSuspects[k]==input[3][3]){
                                if(discontiguousCount==2){
                                return true;
                                }
                            }
                        }
                    }
                }
            }
            //check for 3rd row ends

        }
    }
    return false;
}
public class ContiguousArray {

    public static <E> boolean isContiguous(E[][] array) {
        Map<E, Collection<Integer[]>> groupedPositions = groupLocations(array);

        return groupedPositions.values().stream().allMatch(ContiguousArray::allContiguous);
    }

    private static <E> Map<E, Collection<Integer[]>> groupLocations(E[][] array) {
        Map<E, Collection<Integer[]>> locations = new HashMap<>();

        for(int x = 0; x < array.length; x++) {
            for(int y = 0; y < array[x].length; y++) {

                Collection<Integer[]> knownIndices;
                Integer[] currentPosition = new Integer[] { x, y };
                E currentElement = array[x][y];

                if(locations.containsKey(currentElement)) {
                    knownIndices = locations.get(currentElement);
                } else {
                    knownIndices = new HashSet<>();

                    locations.put(currentElement, knownIndices);
                }
                knownIndices.add(currentPosition);
            }
        }
        return locations;
    }

    /**
     * @return true, if all of the provided indices have an adjacent index in
     *         the same collection. Also true, if the collection's size < 2.
     *         False, otherwise.
     */
    private static boolean allContiguous(Collection<Integer[]> indices) {
        return indices.stream().allMatch(thisIndex -> hasAdjacent(indices, thisIndex) || indices.size() < 2);
    }

    private static boolean hasAdjacent(Collection<Integer[]> indices, Integer[] thisIndex) {
        return indices.stream().anyMatch(thatIndex -> isAdjacent(thisIndex, thatIndex));
    }

    private static boolean isAdjacent(Integer[] thisIndex, Integer[] thatIndex) {
        return thatIndex != thisIndex && calculateDistance(thisIndex, thatIndex) < 2;
    }

    private static int calculateDistance(Integer[] indexA, Integer[] indexB) {
        int sum = 0;

        for (int i = 0; i < indexA.length; i++) {
            sum += Math.abs(indexA[i] - indexB[i]);
        }
        return sum;
    }
}
public class ContiguousArrayTest {
    @Test
    public void test() {
        assertFalse(ContiguousArray.isContiguous(new Integer[][] { 
            { 1, 2, 3, 3 }, 
            { 1, 4, 4, 5 }, 
            { 2, 6, 6, 5 }, 
            { 7, 7, 8, 8 } 
        }));

        assertFalse(ContiguousArray.isContiguous(new Character[][] { 
            { 'a', 'b' }, 
            { 'b', 'a' }, 
        }));

        assertTrue(ContiguousArray.isContiguous(new Character[][] { 
            { 'a', 'a', 'a' }, 
            { 'b', 'a' }, 
            { 'b' }, 
        }));

        assertTrue(ContiguousArray.isContiguous(new Integer[][] { 
            { 1, 2, 3, 3 }, 
            { 1, 4, 4, 5 }, 
            { 6, 7, 7, 5 }, 
            { 8, 8, 9, 9 } 
        }));

        assertTrue(ContiguousArray.isContiguous(new Integer[][] { 
            { 1, 2, 3, 3 }, 
            { 1, 1, 4, 5 }, 
            { 6, 1, 7, 5 }, 
            { 8, 8, 9, 9 } 
        }));

        assertTrue(ContiguousArray.isContiguous(new Integer[][] { 
            { 1, 2 }, 
            { 2, 2 }
        }));
    }
}