简体   繁体   中英

Searching an element in a 'circular sorted' 2d array

For the past few days I've been trying to find a way to efficiently binary search this kind of array and get it to work on any given 2d array of this kind.

Instructions: In this question, you will refer to quadratic two-dimensional arrays, that is, the number of rows and columns is equal to the number of rows and columns equal to n. defining a split into four quarters of n/2 size as follows:阵列的插图

Given this kind of array, I was asked to search an element with logarithmic time complexity, and if it was found I should print the row and column of the element in the array.

Does anyone have a solution for this? A full solution would be amazing, but any answer would be appreciated.

I will share the piece of code that is very messy but this is where I got so far and it works for most of the array elements, which is not good enough since it means whole logic is wrong.

int[][] mat = {
            {1, 2, 3, 4, 17, 18, 19, 20},
            {8, 7, 6, 5, 24, 23, 22, 21},
            {12, 11, 10, 9, 28, 27, 26, 25},
            {16, 15, 14, 13, 32, 31, 30, 29},
            {49, 50, 51, 52, 33, 34, 35, 36},
            {56, 55, 54, 53, 40, 39, 38, 37},
            {60, 59, 58, 57, 45, 46, 41, 42},
            {64, 63, 62, 61, 48, 47, 44, 43}};
public static boolean search(int[][] mat, int num) {
    int n = mat.length;
    int i = 0;
    int j = 0;
    int[] indic = {-1, -1};
    if (num > mat[n - 1][0] || num < mat[0][0]) {
        return false;
    }
    while (n > 1) {
        int minS1 = mat[i][j];
        int maxS1 = mat[(n / 2) - 1 + i][j];
        int minS2 = mat[i][(n / 2) + j];
        int maxS2 = mat[(n / 2) - 1 + i][(n / 2) + j];
        int minS3 = mat[(n / 2) + i][(n / 2) + j];
        int maxS3 = mat[(n - 1) + i][(n / 2) + j];

        int minS4 = mat[(n / 2) + i][j];
        int maxS4 = mat[(n - 1) + i][j];
        checkSquare(num, n, indic, i, j, minS1, minS2, minS3, minS4, maxS1, maxS2, maxS3, maxS4);
        if (indic[0] != -1 && indic[1] != -1) {
            System.out.println("num=" + num);
            System.out.println("row=" + indic[0]);
            System.out.println("col=" + indic[1]);
            return true;
        }
        boolean x = false;
        if (num > maxS2) {
            if (num > maxS3) {
                i += n / 2;
            } else {
                if (n <= mat.length / 2 && i <= (n / 2)) {
                    x = true;
                    i += 1;
                    j += 1;
                } else {
                    if (i >= n / 2 && j < n / 2 && ((i < n) && (j < n))) {
                        i += 1;
                        j += 1;
                    } else {

                        System.out.println(minS1);
                        System.out.println(minS2);
                        System.out.println(minS3);
                        i += 1;
                        j += 1;
                    }
                }
            }
        } else {
            if (num > maxS1) {
                j += n / 2;
            } else {

                if (num > minS2) {
                    if (j > (mat.length / 2))
                        j = 0;
                    j += 1;
                    x = true;
                } else j += 1;
            }
        }
        if (num == mat[i][j]) {
            System.out.println("num=" + num);
            System.out.println("row=" + i);
            System.out.println("col=" + j);
            return true;
        }
        if (!x)
            n = (n / 2);
    }
    return false;
}

I don't think the 2D array you have given is correct according to the picture you've provided. All values in a higher quadrant (numbered clock-wise, starting from the top left) need to be bigger than all values in a lower quadrant. And this rule also applies for all sub-arrays until a size of 1x1 is reached. For example:

Element 24 is placed in position 2-1-3, meaning position 3 in the first sub-quadrant of the second main-quadrant.

Likewise, element 19 is placed in position 2-2-1, so after 2-1-3

I hope I understood correctly.

 public static boolean search (int [][] mat, int num)
{
    int size=mat.length;
    int currentQuadrantRow=0;
    int currentQuadrantCol=0;
    int minQ1=mat[0][0];
    int minQ2=mat[0][size/2];
    int minQ3=mat[size/2][size/2];
    int minQ4=mat[size/2][0];
    int maxQ1;
    int maxQ2;
    int maxQ3;
    int maxQ4;
    if (size / 2 == 0)
    {
        maxQ1 = minQ1;
        maxQ2 = minQ2;
        maxQ3=minQ3;
        maxQ4=minQ4;
    }
    else
    {
        maxQ1 = mat[(size/ 2)-1][0];
        maxQ2 = mat[((size/ 2) - 1)][0+(size / 2)];
        maxQ3 = mat[(size - 1)][0+(size / 2)];
        maxQ4 = mat[(size - 1)][0];
    }
    while (size>1)
    {
        if (minQ1 > num) {
            return false;
        } else if (num <= maxQ1) {
            size = size/ 2;
        } else if (minQ2 > num) {
            return false;
        } else if (num <= maxQ2) {
            size = size/ 2;
            currentQuadrantCol = currentQuadrantCol + size;
        } else if (minQ3 > num) {
            return false;
        } else if (num <= maxQ3) {
            size = size/ 2;
            currentQuadrantRow = currentQuadrantRow + size;
            currentQuadrantCol = currentQuadrantCol + size;
        } else if (minQ4 > num) {
            return false;
        } else if (num <= maxQ4) {
            size = size/ 2;
            currentQuadrantRow = currentQuadrantRow + size;
        } else if (num > maxQ4) {
            return false;
        }
        System.out.println(currentQuadrantRow);
        System.out.println(currentQuadrantCol);
        minQ1 = mat[currentQuadrantRow][currentQuadrantCol];
        minQ2 = mat[currentQuadrantRow][currentQuadrantCol+(size / 2)];
        minQ3 = mat[currentQuadrantRow+(size / 2)][currentQuadrantCol+(size / 2)];
        minQ4 = mat[currentQuadrantRow+(size / 2)][currentQuadrantCol];
        if (size / 2 == 0)
        {
            maxQ1 = minQ1;
            maxQ2 = minQ2;
            maxQ3=minQ3;
            maxQ4=minQ4;
        }
        else
        {
            maxQ1 = mat[currentQuadrantRow+((size/ 2) - 1)][currentQuadrantCol];
            maxQ2 = mat[currentQuadrantRow+((size/ 2) - 1)][currentQuadrantCol+(size / 2)];
            maxQ3 = mat[currentQuadrantRow+(size - 1)][currentQuadrantCol+(size / 2)];
            maxQ4 = mat[currentQuadrantRow+(size - 1)][currentQuadrantCol];
        }
    }
    if(mat[currentQuadrantRow][currentQuadrantCol]==num)
    {
        return true;
    }
    return false;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM