在一个二维有序数组中寻找行元素的位置。

huangapple go评论82阅读模式
英文:

Finding the position of a row element in a 2d ordered array

问题

public static int[][] buildNewArray(int[][] m) {
    int[][] newArray = new int[m.length][m[0].length];
    
    for (int i = 0; i < m.length; i++) {
        int[] rowCopy = Arrays.copyOf(m[i], m[i].length);
        Arrays.sort(rowCopy);

        for (int j = 0; j < m[i].length; j++) {
            int originalValue = m[i][j];
            int indexInSorted = Arrays.binarySearch(rowCopy, originalValue);
            newArray[i][j] = indexInSorted;
        }
    }

    return newArray;
}

Note: This code assumes that the input 2D array m contains distinct values in each row. If there are duplicate values, you might need to adjust the code to handle those cases.

英文:

I need to build a method in Java where the input is a 2D array of integers and get as a result a 2D array of integers where each element makes reference to a position of an element in a row. Let's me explain that with an example.

Consider as a input for the method a 2D arrays of 7x7 as follow:

int[][] array = new int[][]{
        {280, 103, 351, 226, 451, 563, 507},
        {173, 71, 40, 100, 396, 315, 442},
        {421, 326, 210, 308, 535, 487, 549},
        {87, 165, 0, 19, 213, 405, 281},
        {25, 0, 104, 195, 298, 238, 223},
        {2, 17, 68, 0, 98, 196, 236},
        {356, 225, 454, 408, 567, 681, 604}};

I used a method to order this array in increasing order according to the values of each row. The code is the following:

public static int[][] sortRowWise (int m[][]) {
    for (int i = 0; i &lt; m.length; i++) {
        for (int j = 0; j &lt; m[i].length; j++) {
            for (int k = 0; k &lt; m[i].length - j - 1; k++) {
                if (m[i][k] &gt; m[i][k + 1]) {
                    int t = m[i][k];
                    m[i][k] = m[i][k + 1];
                    m[i][k + 1] = t;
                }
            }
        }
    }

    // printing the sorted matrix
    int[][] mR = new int[m.length][m[0].length];
    for (int i = 0; i &lt; m.length; i++) {
        for (int j = 0; j &lt; m[0].length; j++) {
            mR[i][j] = m[i][j];
        }
    }
    return mR;
}

And the output is:

在一个二维有序数组中寻找行元素的位置。

Now I need to build a new 2D array of integer (I will call newArray in the following) according with:

  1. The minimum value of row 0 in the "not-ordered" array is 103 and is
    associated with column 1 (then, I need to assign a 0 in
    newArray[0][0].
  2. Next, the minimum value of row 0 in the "not-ordered" array is 226
    and is associated with column 3 (then, I need to assign a 1 in
    newArray[0][3].
  3. And so on for each row...

As said before, the final output of the method must be something like the following 2d array. Any help would be highly appreciated.

在一个二维有序数组中寻找行元素的位置。

答案1

得分: 0

public class Foo {
    public static void main(String... args) {
        int[][] matrix = {
            {280, 103, 351, 226, 451, 563, 507},
            {173, 71, 40, 100, 396, 315, 442},
            {421, 326, 210, 308, 535, 487, 549},
            {87, 165, 0, 19, 213, 405, 281},
            {25, 0, 104, 195, 298, 238, 223},
            {2, 17, 68, 0, 98, 196, 236},
            {356, 225, 454, 408, 567, 681, 604}};
        print(matrix);
        System.out.println();
        print(transform(matrix));
    }

    public static int[][] transform(int[][] matrix) {
        class Point {
            final int col;
            final int val;

            public Point(int col, int val) {
                this.col = col;
                this.val = val;
            }
        }

        List<Queue<Point>> queues = new ArrayList<>(matrix.length);

        for (int row = 0; row < matrix.length; row++) {
            Queue<Point> queue = new PriorityQueue<>(
                    Comparator.comparingInt(point -> point.val));

            for (int col = 0; col < matrix[row].length; col++)
                queue.add(new Point(col, matrix[row][col]));

            queues.add(queue);
        }

        int[][] res = new int[matrix.length][];

        for (int row = 0; row < matrix.length; row++) {
            Queue<Point> queue = queues.get(row);
            int col = 0;
            res[row] = new int[queue.size()];

            while (!queue.isEmpty())
                res[row][col++] = queue.remove().col;
        }
        return res;
    }

    public static void print(int[][] matrix) {
        for (int row = 0; row < matrix.length; row++) {
            for (int col = 0; col < matrix[row].length; col++) {
                if (col > 0)
                    System.out.print(' ');
                System.out.format("%3d", matrix[row][col]);
            }
            System.out.println();
        }
    }
}

Output:

280 103 351 226 451 563 507
173  71  40 100 396 315 442
421 326 210 308 535 487 549
87 165   0  19 213 405 281
25   0 104 195 298 238 223
2  17  68   0  98 196 236
356 225 454 408 567 681 604
  1   3   0   2   4   6   5
2   1   3   0   5   4   6
2   3   1   0   5   4   6
2   3   0   1   4   6   5
1   0   2   3   6   5   4
3   0   1   2   4   5   6
1   0   3   2   4   6   5
英文:
public class Foo {
    public static void main(String... args) {
        int[][] matrix = {
                {280, 103, 351, 226, 451, 563, 507},
                {173, 71, 40, 100, 396, 315, 442},
                {421, 326, 210, 308, 535, 487, 549},
                {87, 165, 0, 19, 213, 405, 281},
                {25, 0, 104, 195, 298, 238, 223},
                {2, 17, 68, 0, 98, 196, 236},
                {356, 225, 454, 408, 567, 681, 604}};
        print(matrix);
        System.out.println();
        print(transform(matrix));
    }

    public static int[][] transform(int[][] matrix) {
        class Point {
            final int col;
            final int val;

            public Point(int col, int val) {
                this.col = col;
                this.val = val;
            }
        }

        List&lt;Queue&lt;Point&gt;&gt; queues = new ArrayList&lt;&gt;(matrix.length);

        for (int row = 0; row &lt; matrix.length; row++) {
            Queue&lt;Point&gt; queue = new PriorityQueue&lt;&gt;(
                    Comparator.comparingInt(point -&gt; point.val));

            for (int col = 0; col &lt; matrix[row].length; col++)
                queue.add(new Point(col, matrix[row][col]));

            queues.add(queue);
        }

        int[][] res = new int[matrix.length][];

        for (int row = 0; row &lt; matrix.length; row++) {
            Queue&lt;Point&gt; queue = queues.get(row);
            int col = 0;
            res[row] = new int[queue.size()];

            while (!queue.isEmpty())
                res[row][col++] = queue.remove().col;
        }
        return res;
    }

    public static void print(int[][] matrix) {
        for (int row = 0; row &lt; matrix.length; row++) {
            for (int col = 0; col &lt; matrix[row].length; col++) {
                if (col &gt; 0)
                    System.out.print(&#39; &#39;);
                System.out.format(&quot;%3d&quot;, matrix[row][col]);
            }
            System.out.println();
        }
    }
}

Output:

280 103 351 226 451 563 507
173  71  40 100 396 315 442
421 326 210 308 535 487 549
87 165   0  19 213 405 281
25   0 104 195 298 238 223
2  17  68   0  98 196 236
356 225 454 408 567 681 604
  1   3   0   2   4   6   5
2   1   3   0   5   4   6
2   3   1   0   5   4   6
2   3   0   1   4   6   5
1   0   2   3   6   5   4
3   0   1   2   4   5   6
1   0   3   2   4   6   5

答案2

得分: 0

你可以遍历已排序数组,在每个元素上,找出它在原始数组中对应的索引。

int[][] sortedArray = sortRowWise(array);
int[][] result = new int[array.length][array[0].length];
for (int i = 0; i < sortedArray.length; i++) {
    int current = sortedArray[0][i];
    for (int j = 0; j < array.length; j++) {
        if (array[0][j] == current) {
            result[0][j] = i;
        }
    }
}

应该适用于第一行(没有测试过,但重要的是思路)。

英文:

You could iterate over your sorted array and for each element, find which index corresponds in the original array.

int[][] sortedArray = sortRowWise(array);
int[][] result = new int[array.length][array[0].length];
for (int i = 0; i &lt; sortedArray.length; i++) {
    int current = sortedArray[0][i];
    for (int j = 0; j &lt; array.length; j++) {
        if (array[0][j] == current) {
            result[0][j] = i;
        }
    }
}

Should work for the first line (didn't test it but what matters is the idea)

答案3

得分: 0

你可以使用一颗二叉树,每个节点可以存储数字及其在原始数组中的索引。然后你可以遍历以找到最小的数字。

假设你实现了这样一个树,其中较小的数字位于左侧,那么你需要按照左节点、当前节点和右节点的顺序遍历。

可以使用类似如下的代码:

public static void traverseNode(Node n, List<Integer> a) {
    traverseNode(n.left, a);
    a.append(n.index);
    traverseNode(n.right, a);
}

最终,列表 a 应该是一行的结果。

英文:

You could use a binary tree that each node could store the number and its index in original array. Then you traverse for finding the smallest number.

Lets say you implemented the tree that smaller number is on the left side, then you need to traverse as the left node, current node, and the right node.

With something like this:

public static void traverseNode(Node n, List&lt;Integer&gt; a) {
    traverseNode(n.left, a);
    a.append(n.index);
    traverseNode(n.right, a);
}

In the end, list a should be the result of a row.

答案4

得分: 0

以下是已翻译的内容:

获取此矩阵行中元素在排序后矩阵中的索引矩阵 - 您可以遍历该数组的行,并且对于每一行,遍历其索引并按照相应的元素值对它们进行排序 - 您将获得排序后的索引行。然后遍历排序后行的索引,并且对于每个元素,交换其值和索引:

int[][] arr1 = {
        {280, 103, 351, 226, 451, 563, 507},
        {173, 71, 40, 100, 396, 315, 442},
        {421, 326, 210, 308, 535, 487, 549},
        {87, 165, 0, 19, 213, 405, 281},
        {25, 0, 104, 195, 298, 238, 223},
        {2, 17, 68, 0, 98, 196, 236},
        {356, 225, 454, 408, 567, 681, 604}};
int[][] arr2 = Arrays
        // 遍历数组的行
        .stream(arr1)
        // 获取排序后行的索引数组
        .map(row -> IntStream
                // 遍历行的索引
                .range(0, row.length)
                .boxed()
                // 根据行中元素值对索引进行排序
                .sorted(Comparator.comparingInt(j -> row[j]))
                .mapToInt(Integer::intValue)
                // 返回排序后的索引数组
                .toArray())
        // 获取元素在排序后行中的位置
        .map(row -> {
            int[] arr = new int[row.length];
            IntStream.range(0, row.length).forEach(j -> {
                // 交换行索引和元素值
                int val = row[j];
                arr[val] = j;
            });
            // 返回元素在排序后数组中的位置数组
            return arr;
        }).toArray(int[][]::new);
// 输出
Arrays.stream(arr2).map(Arrays::toString).forEach(System.out::println);
[2, 0, 3, 1, 4, 6, 5]
[3, 1, 0, 2, 5, 4, 6]
[3, 2, 0, 1, 5, 4, 6]
[2, 3, 0, 1, 4, 6, 5]
[1, 0, 2, 3, 6, 5, 4]
[1, 2, 3, 0, 4, 5, 6]
[1, 0, 3, 2, 4, 6, 5]

另请参阅:在排序的二维数组中按列查找二维数组元素的索引

英文:

To get a matrix of indices of elements of rows of this matrix in a sorted matrix - you can iterate over the rows of this array and, for each row, iterate over its indices and sort them by the corresponding element values - you get the sorted row of indices. Then iterate over the indices of the sorted row and, for each element, swap its value and index:

int[][] arr1 = {
        {280, 103, 351, 226, 451, 563, 507},
        {173, 71, 40, 100, 396, 315, 442},
        {421, 326, 210, 308, 535, 487, 549},
        {87, 165, 0, 19, 213, 405, 281},
        {25, 0, 104, 195, 298, 238, 223},
        {2, 17, 68, 0, 98, 196, 236},
        {356, 225, 454, 408, 567, 681, 604}};
int[][] arr2 = Arrays
        // iterate over the rows of the array
        .stream(arr1)
        // get a sorted array
        // of indices of the row
        .map(row -&gt; IntStream
                // iterate over the
                // indices of the row
                .range(0, row.length)
                .boxed()
                // sort indices by element values in the row
                .sorted(Comparator.comparingInt(j -&gt; row[j]))
                .mapToInt(Integer::intValue)
                // return sorted array of indices
                .toArray())
        // get the positions of
        // elements in a sorted row
        .map(row -&gt; {
            int[] arr = new int[row.length];
            IntStream.range(0, row.length).forEach(j -&gt; {
                // swap the row index and
                // the value of the element
                int val = row[j];
                arr[val] = j;
            });
            // return an array of element
            // positions in a sorted array
            return arr;
        }).toArray(int[][]::new);
// output
Arrays.stream(arr2).map(Arrays::toString).forEach(System.out::println);
[2, 0, 3, 1, 4, 6, 5]
[3, 1, 0, 2, 5, 4, 6]
[3, 2, 0, 1, 5, 4, 6]
[2, 3, 0, 1, 4, 6, 5]
[1, 0, 2, 3, 6, 5, 4]
[1, 2, 3, 0, 4, 5, 6]
[1, 0, 3, 2, 4, 6, 5]

<sup>See also: Finding indexes of 2d array elements in a sorted 2d array by columns</sup>

huangapple
  • 本文由 发表于 2020年10月20日 05:32:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/64435355.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定