您的位置:首页 > 其它

leetcode 数组array之566. Reshape the Matrix

2017-08-29 11:57 393 查看
问题如下描述:

In MATLAB, there is a very useful function called 'reshape', which can reshape a matrix into a new one with different size but keep its original data.

You're given a matrix represented by a two-dimensional array, and two positive integers r and c representing the row number
and column number of the wanted reshaped matrix, respectively.

The reshaped matrix need to be filled with all the elements of the original matrix in the same row-traversing order as they were.

If the 'reshape' operation with given parameters is possible and legal, output the new reshaped matrix; Otherwise, output the original matrix.

Example 1:

Input:
nums =
[[1,2],
[3,4]]
r = 1, c = 4
Output:
[[1,2,3,4]]
Explanation:
The row-traversing of nums is [1,2,3,4]. The new reshaped matrix is a 1 * 4 matrix, fill it row by row by using the previous list.


Example 2:

Input:
nums =
[[1,2],
[3,4]]
r = 2, c = 4
Output:
[[1,2],
[3,4]]
Explanation:
There is no way to reshape a 2 * 2 matrix to a 2 * 4 matrix. So output the original matrix.


Note:

The height and width of the given matrix is in range [1, 100].
The given r and c are all positive.

思路解析:感觉也不是特别简单,就是让你变换矩阵的,按照规定的行和列,变换成特定的矩阵。一开始看到这个题目时,还以为要用到numpy,毕竟是矩阵嘛。后来试一下发现,不允许用模块,只能根据数组(Python中的列表)最基本的一些操作来实现,一开始什么想法没有。后来想了想,想出自己的思路:

 首先要判断数组包含的元素的数目和所要变换的矩阵的行列成绩是否相等,如果不相等, 直接输出原数组,这里还要判断输入数组是不是一个空数组。
 如果相等的话,就把原数组的所有元素都取出来放到一个数组newlist里。
根据所要新建的矩阵的行r,建立一个包含r个元素的数组finalist。
然后根据所要新建的矩阵的列c,把newlist的元素按组分片,比如:newlist[0,c],newlist[c,2c],newlist[2c,3c],,,new[(r-1)c,rc],分别赋值给finallist[0],finallist[1],,,finallist[r-1].
最后返回finallist,得到最终的结果。
以上是我的思路,最终用Python编码,得出结果被LeetCode接受了。

方法一:  runtime:32ms

class Solution(object):
def matrixReshape(self, nums, r, c):
"""
:type nums: List[List[int]]
:type r: int
:type c: int
:rtype: List[List[int]]
"""
nums_r = len(nums)
nums_c = len(nums[0])
newlist = []
finallist = range(r)
for i in xrange(nums_r):     #
for j in xrange(nums_c):
newlist.append(nums[i][j])

if (nums_r * nums_c != r * c)|(len(nums)==0):
return nums
else:
for i in xrange(r):
finallist[i] = newlist[i * c:(i + 1) * c]
return finallist


方法二:runtime:32ms

class Solution(object):
def matrixReshape(self, nums, r, c):
"""
:type nums: List[List[int]]
:type r: int
:type c: int
:rtype: List[List[int]]
"""
nums_r = len(nums)
nums_c = len(nums[0])
newlist = []
finallist = range(r)
for i in xrange(nums_r):
newlist.extend(nums[i])
if (nums_r * nums_c != r * c)|(len(nums)==0):
return nums else: for i in xrange(r): finallist[i] = newlist[i * c:(i + 1) * c] return finallist

方法三:这是根据官方给出的第二种Java方法改的,不需要额外数组空间来放置所有的元素。

class Solution(object):
def matrixReshape(self, nums, r, c):
"""
:type nums: List[List[int]]
:type r: int
:type c: int
:rtype: List[List[int]]
"""
nums_r = len(nums)
nums_c = len(nums[0])
#newlist = []
rows = 0
cols = 0
finallist = range(r)
for i in xrange(r):
finallist[i]=range(c)

#for i in xrange(len(nums)):
#   newlist.extend(nums[i])
if ((nums_r== 0)|nums_r * nums_c != r * c):
return nums

for i in xrange(nums_r):
for j in xrange(nums_c):
#finallist[i]=[]
finallist[rows][cols]=nums[i][j]
cols+=1
if cols==c:
cols=0
rows+=1
#finallist[i] = newlist[i * c:(i + 1) * c]
return finallist


总结:还是那个问题,自己的基础薄弱。就拿这题来说,你必须对Python中列表的基本方法了熟于心 ,最基本的操作必须要知道,然后才能根据自己想的算法按步骤写出代码。写代码,想提高性能,就要从降低时间复杂度和内存占用空间为目标,尽可能的增加效率。同时还要把代码可能遇到的所有情况都要考虑进去,比如这题,我没有考虑给定的原数组为空数组,就少了一个判定条件(当然在本题中,题目明确说不会给出空的数组,而且r和c的值必须为整数,所以不需要考虑空数组情况)。

还有,这题还有没有别的方法?我看LeetCode给出的三个方法,用Java写的,其中有一个方法是不需要把原数组所有的元素提出来放到一个新的数组的,直接在原数组上操作,把元素赋值给要新建的数组。我有机会用Python尝试一下这种方法,看能不能实现。

LeetCode给出的方法,用Java写的:

方法一:


Approach #1 Using queue [Accepted]

Algorithm

The simplest method is to extract all the elements of the given matrix by reading the elements in a row-wise fashion. In this implementation, we use a queue to put the extracted elements. Then, we can take out the elements of the queue formed in a serial order
and arrange the elements in the resultant required matrix in a row-by-row order again.

The formation of the resultant matrix won't be possible if the number of elements in the original matrix isn't equal to the number of elements in the resultant matrix.

Java

public class Solution {
public int[][] matrixReshape(int[][] nums, int r, int c) {
int[][] res = new int[r][c];
if (nums.length == 0 || r * c != nums.length * nums[0].length)
return nums;
int count = 0;
Queue < Integer > queue = new LinkedList < > ();
for (int i = 0; i < nums.length; i++) {
for (int j = 0; j < nums[0].length; j++) {
queue.add(nums[i][j]);
}
}
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
res[i][j] = queue.remove();
}
}
return res;
}
}


Complexity Analysis

Time complexity : O(m*n)O(m∗n).
We traverse over m*nm∗n elements
twice. Here, mm and nn refer
to the number of rows and columns of the given matrix respectively.

Space complexity : O(m*n)O(m∗n).
The queue formed will be of size m*nm∗n.

方法二:


Approach #2 Without using extra Space [Accepted]

Algorithm

Instead of unnecessarily using the queue as in the brute force approach, we can keep putting the numbers in the resultant matrix directly while iterating over the given matrix in a row-by-row order. While putting the numbers in the resultant array, we fix a
particular row and keep on incrementing the column numbers only till we reach the end of the required columns indicated by cc.
At this moment, we update the row index by incrementing it and reset the column index to start from 0 again. Thus, we can save the space consumed by the queue for storing the data that just needs to be copied into a new array.

Java

public class Solution {
public int[][] matrixReshape(int[][] nums, int r, int c) {
int[][] res = new int[r][c];
if (nums.length == 0 || r * c != nums.length * nums[0].length)
return nums;
int rows = 0, cols = 0;
for (int i = 0; i < nums.length; i++) {
for (int j = 0; j < nums[0].length; j++) {
res[rows][cols] = nums[i][j];
cols++;
if (cols == c) {
rows++;
cols = 0;
}
}
}
return res;
}
}


Complexity Analysis

Time complexity : O(m*n)O(m∗n).
We traverse the entire matrix of size m*nm∗n once
only. Here, mm and nn refers
to the number of rows and columns in the given matrix.

Space complexity : O(m*n)O(m∗n).
The resultant matrix of size m*nm∗n is
used.

方法三:


Approach #3 Using division and modulus [Accepted]

Algorithm

In the last approach, we needed to keep a track of when we reached the end of columns for the resultant matrix and needed to update the current row and column number for putting the extracted elements by checking the current indices every time. Instead of doing
these limit checks at every step, we can make use of maths to help ease the situation.

The idea behind this approach is as follows. Do you know how a 2-D array is stored in the main memory(which is 1-D in nature)? It is internally represented as a 1-D array only. The element nums[i][j]nums[i][j] of numsnums array
is represented in the form of a one dimensional array by using the index in the form: nums[n*i
+ j]nums[n∗i+j],
where mm is
the number of columns in the given matrix. Looking at the same in the reverse order, while putting the elements in the elements in the resultant matrix, we can make use of a countcount variable
which gets incremented for every element traversed as if we are putting the elements in a 1-D resultant array. But, to convert the countcount back
into 2-D matrix indices with a column count of cc,
we can obtain the indices as res[count/c][count\%c]res[count/c][count%c] where count/ccount/c is
the row number and count\%ccount%c is
the coloumn number. Thus, we can save the extra checking required at each step.

Java

public class Solution {
public int[][] matrixReshape(int[][] nums, int r, int c) {
int[][] res = new int[r][c];
if (nums.length == 0 || r * c != nums.length * nums[0].length)
return nums;
int count = 0;
for (int i = 0; i < nums.length; i++) {
for (int j = 0; j < nums[0].length; j++) {
res[count / c][count % c] = nums[i][j];
count++;
}
}
return res;
}
}


Complexity Analysis

Time complexity : O(m*n)O(m∗n).
We traverse the entire matrix of size m*nm∗n once
only. Here, mm and nn refers
to the number of rows and columns in the given matrix.

Space complexity : O(m*n)O(m∗n).
The resultant matrix of size m*nm∗n is
used.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  leetcode array matrix easy