【问题标题】:Finding the position of a row element in a 2d ordered array在二维有序数组中查找行元素的位置
【发布时间】:2021-02-02 16:51:58
【问题描述】:

我需要在 Java 中构建一个方法,其中输入是一个 2D 整数数组,并得到一个 2D 整数数组,其中每个元素引用一行中元素的位置。让我用一个例子来解释一下。

将 7x7 的二维数组视为该方法的输入,如下所示:

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}};

我使用了一种方法来根据每一行的值对这个数组进行升序排序。代码如下:

public static int[][] sortRowWise (int m[][]) {
    for (int i = 0; i < m.length; i++) {
        for (int j = 0; j < m[i].length; j++) {
            for (int k = 0; k < m[i].length - j - 1; k++) {
                if (m[i][k] > 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 < m.length; i++) {
        for (int j = 0; j < m[0].length; j++) {
            mR[i][j] = m[i][j];
        }
    }
    return mR;
}

输出是:

现在我需要建立一个新的二维整数数组(我将在下面调用newArray):

  1. “无序”数组中第 0 行的最小值为 103,为 与第 1 列相关联(然后,我需要在 newArray[0][0]
  2. 接下来,“无序”数组中第 0 行的最小值为 226 并与第 3 列相关联(然后,我需要在 newArray[0][3]
  3. 每行以此类推...

如前所述,该方法的最终输出必须类似于以下二维数组。任何帮助将不胜感激。

【问题讨论】:

    标签: java arrays sorting multidimensional-array


    【解决方案1】:
    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();
            }
        }
    }
    

    输出:

    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】:

      您可以遍历已排序的数组,并为每个元素找到原始数组中对应的索引。

      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;
              }
          }
      }
      

      应该适用于第一行(没有测试,但重要的是想法)

      【讨论】:

        【解决方案3】:

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

        假设您实现了左侧数字较小的树,那么您需要遍历左侧节点、当前节点和右侧节点。

        这样的:

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

        最后,list a 应该是一行的结果。

        【讨论】:

          【解决方案4】:

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

          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 -> 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 -> row[j]))
                          .mapToInt(Integer::intValue)
                          // return sorted array of indices
                          .toArray())
                  // get the positions of
                  // elements in a sorted row
                  .map(row -> {
                      int[] arr = new int[row.length];
                      IntStream.range(0, row.length).forEach(j -> {
                          // 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]
          

          另见:Finding indexes of 2d array elements in a sorted 2d array by columns

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2022-11-19
            • 1970-01-01
            • 2017-04-11
            • 1970-01-01
            • 2021-02-03
            • 1970-01-01
            • 1970-01-01
            • 2014-02-27
            相关资源
            最近更新 更多