LeetCode brush title notes 1260 title

Subject description:

Give you a  m line of  n two-dimensional grid of columns  grid and an integer  k. You will need to  grid migrate  k times. Every time "migration" operation will lead to the following activities:

 

  • Located  grid[i][j] elements will be moved to  grid[i][j + 1].
  • Located  grid[i][n - 1] elements will be moved to  grid[i + 1][0].
  • Located  grid[m - 1][n - 1] elements will be moved to  grid[0][0].

 

Please return to  k two-dimensional grid after the resulting migration times. Example:

  输入:grid= [[1,2,3], [4,5,6 ], [7,8,9]], k = 1 
  Output: [[9,1,2], [3,4,5], [ 6,7,8]]
  输入:grid= [[3,8,1,9], [19,7,2,5 ], [4,6,11,10], [12,0,21,13]], k = 4 
  Output: [[ 12,0,21,13], [3,8,1,9], [19,7,2,5], [4,6,11,10]]

Restrictions:

  • 1 <= grid.length <= 50
  • 1 <= grid[i].length <= 50
  • -1000 <= grid[i][j] <= 1000
  • 0 <= k <= 100

Problem-solving ideas:

  My idea is to abstract two-dimensional array into a one-dimensional sequence of numbers, then transferred in accordance with the requirements of the subject can know is to actually migrate k times after this number of one-dimensional sequence of k numbers transferred to the front portion of the sequence of numbers, The whole process can be imagined as a circular motion. So I resorted to the first two one-dimensional arrays are stored nk elements and the k elements, then these two serial array traversal, storage element to the collection were to go. The time complexity of O (m * n + (m + n)). Code as follows:

    List<List<Integer>> res_list;

    public List<List<Integer>> shiftGrid(int[][] grid, int k) {
        if (k % (grid.length * grid[0].length) == 0){
            res_list = new LinkedList<>();
            for (int[] g : grid){
          
//Integer[] gg = IntStream.of(g).boxed().collect(Collectors.toList()).toArray(new Integer[0]); List<Integer> ls = IntStream.of(g).boxed().collect(Collectors.toList()); res_list.add(ls); } return res_list; } int temp_len = grid.length * grid[0].length; k = k % (temp_len); int[] temp = new int[temp_len-k]; int[] temp2 = new int[k]; int index = 0; for (int[] ints : grid) { for (int anInt : ints) { if (index < (temp_len-k)) temp[index] = anInt; else{ temp2[index-(temp_len-k)] = anInt; } index++; } } LinkedList<Integer> temp_list = new LinkedList<>(); res_list = new LinkedList<>(); for (int i =0; i <= temp_len; i++) { if (i % grid[0].length == 0 &&(i >= grid[0].length)){ res_list.add(temp_list); temp_list = new LinkedList<>(); } if (i < k) temp_list.add(temp2[i]); else if (i < temp_len) temp_list.add(temp[i-k]); } return res_list; }

note:

  When writing a program committed an error of some knowledge, that is not stored in the basic data types to the collection, storage can only refer to objects. Each collection element is a reference variable, which actual contents are stored in the stack area or method, but the basic data type is allocated on the stack memory space, the data on the stack may be withdrawn at any time. Therefore, by packaging, the basic object type into the data type, storage reference. More convenient, thanks to the automatic unpacking and packing function, data type conversion between the base and the corresponding objects become very convenient, the basic data types can be automatically set into memory, the system will automatically packing as wrapper classes, and then added to the set of them.

  However, in the present ls set calculation program, each row I acquired two-dimensional array of one-dimensional array, when the one-dimensional array I be directly converted into a set by Arrays.asList then be stored sequentially by enhancing the for loop the results compiled into a collection errors occur, suggesting no instance (s) of type variable (s) exist so that int [] conforms to Integer wrong, so I will convert g element in the array is the type of wrapper classes, and then into results set, as shown in the above specific code.

 

Other better solution: a modulo operation

This solution is the official solution Leetcode given, so learning about the time complexity is O (m * n). Specific ideas are as follows:

  Moving the two-dimensional array of problems, in addition to the analog method, a direct calculation of the new position of element transfer more efficient. Calculating a new position in two steps:

  1. What is new column?
  2. What is the new line?

  Assuming a grid in three rows and five columns, located at  i = 1  and  j = 3  value at migration times  K = 88 .

  Step one: calculate new column values

  After migration step k, the k-th column value changes every step, a column value will change, but not infinite grid elements in the transverse direction during the cyclic motion is conceivable, because the number of columns per movement is so 5 5 minor elements will return to the original column position (note the column position, not the exact location).

  Therefore, the migration step k, the column position of the element can be calculated by (88 + 3) 5%, so that a new location for the column;

  Abstract general formula: new_col = (j + k)% num_cols, j starting column value for the element, num_cols the total number of columns of the grid.

  Step two: calculate the value of a new line

  Row value conversion infrequently, and only if the value from the column becomes the last column of row 0 so that the value will be changed, while the element is a circular movement in the longitudinal direction, so to determine the new row values, determined from the last column moving to the number of 0, the number of mobile computing commercially used herein line.

  Abstract of the general formula: new_row = (i + (j + k) / num_cols)% num_rows, i values ​​for the start line element, num_rows number of rows

  code show as below:

public List<List<Integer>> shiftGrid(int[][] grid, int k) {

        int numCols = grid[0].length;
        int numRows = grid.length;

        // Setup the 2d list.
        List<List<Integer>> newGrid = new ArrayList<>();
        for (int row = 0; row < numRows; row++) {
            List<Integer> newRow = new ArrayList<>();
            newGrid.add(newRow);
            for (int col = 0; col < numCols; col++) {
                newRow.add(0);
            }
        }

        for (int row = 0; row < numRows; row++) {
            for (int col = 0; col < numCols; col++) {
                int newCol = (col + k) % numCols;
                int wrapAroundCount = (col + k) / numCols;
                int newRow = (row + wrapAroundCount) % numRows;
                newGrid.get(newRow).set(newCol, grid[row][col]);
            }
        }

        return newGrid;
    }

Note: List collection is indexed, it can be accessed through the collection index.

  

 

Guess you like

Origin www.cnblogs.com/yxym2016/p/12536034.html
Recommended