[英]Matrix Summation Challenge
下面的算法用于将“下矩阵”转换为“后矩阵”。 给定“后矩阵”,找到“前矩阵”。
该算法针对每个 after(x,y) 运行以确定它们的值。 给定之后,找到之前的原始值
例子
之后 = [[2,5],[7,17]]
从之前计算之后的值
after[0][0] = before[0][0] = 2
after[0][1] = before[0][0] + before[0][1] = 2 + 3 = 5
after[1][0] = before[0][0] + before[1][0] = 2 + 5 = 7
after[1][1] = before[0][0] + before[0][1] + before[1][0] + before[1][1] = 2 + 3 + 5 + 7 = 17
完成 function 找到前矩阵有以下参数 after[n][m]:一个 nxm 整数数组
返回: int[n][m] 表示前矩阵的 nxm 整数数组
约束
再输入一个样本
到目前为止我尝试过的
n = gets.to_i
m = gets.to_i
arr = Array.new(n){Array.new(m,0)}
sum = 0
arr_last = 0
arr_first = 0
len = 0
a.each_with_index do |d, outer_index|
len = d.length - 1
d.each_with_index do |b, index|
arr_sum = d[0..index].sum
if index > 0
arr[outer_index][index] = sum + arr_sum
else
arr[outer_index][index] = arr_first + b
end
arr_first += b if index == 0
arr_last = arr_sum if index == len
end
sum += arr_last
end
print arr
但是对于少数测试用例它没有在时间限制内执行并且对于少数测试用例我得到了错误的答案
After 网格中的每个值都是其 Before 值和其左侧和/或上方的所有 Before 值的总和。 在图中:
B
是红色区域内所有Before值的总和,Y
是绿色和红色区域中所有之前值的总和,X
是蓝色和红色区域中所有之前值的总和,并且A
是紫色、蓝色、绿色和红色区域中所有之前值的总和。 由于X
和Y
与B
重叠,添加X
和Y
将使B
计数两次。 因此,如果我们从A
开始,减去X
和Y
,然后加上B
(以抵消加倍),我们得到A
的 Before 值,如下所示: A' = A - X - Y + B
。
现在我们知道了,代码非常简单:
def before(after)
before = []
after.each_with_index do |row,j|
before[j] = []
row.each_with_index do |v,i|
up = j <= 0 ? 0 : after[j-1][i]
left = i <= 0 ? 0 : after[j][i-1]
up_left = i <= 0 || j <= 0 ? 0 : after[j-1][i-1]
before[j][i] = v - up - left + up_left
end
end
before
end
这只是提到了组织@Ouroborus 出色答案的计算的另一种方法。
认为
after = [
[ 2, 5, 4, 5],
[ 7, 17, 13, 10],
[11, 19, 14, 15]
]
通过首先构造以下数组,从after
我们避免了检查元素是否在after
的第一行或第一列中的需要。
aft = [
[0, 0, 0, 0, 0],
[0, 2, 5, 4, 5],
[0, 7, 17, 13, 10],
[0, 11, 19, 14, 15]
]
这是因为,对于任何i
、 j
、 i > 0
、 j > 0
,可以看出:
aft[i][j] = before[i-1][j-1] + aft[i][j-1] + aft[i-1][j] - aft[i-1][j-1]
意思是:
before[i-1][j-1] = aft[i][j] - aft[i][j-1] - aft[i-1][j] + aft[i-1][j-1]
数组aft
不需要实际构造,因为我们可以使用方法返回元素aft[i][j]
def aftmap(after, i, j)
i.zero? || j.zero? ? 0 : after[i-1][j-1]
end
aftmap(after, 0, 0) #=> 0
aftmap(after, 1, 0) #=> 0
aftmap(after, 0, 1) #=> 0
aftmap(after, 2, 2) #=> 17
aftmap(after, 3, 4) #=> 15
这可以以如下方法实现。
def before(after)
nrows = after.size
ncols = after.first.size
(1..nrows).each_with_object(Array.new(nrows) { Array.new(ncols) }) do |i,before|
(1..ncols).each do |j|
before[i-1][j-1] = aftmap(after,i,j) - aftmap(after,i,j-1) -
aftmap(after,i-1,j) + aftmap(after,i-1,j-1)
end
end
end
before(after)
#=> [[2, 3, -1, 1],
# [5, 7, -3, -4],
# [4, -2, -1, 4]]
线
(1..nrows).each_with_object(Array.new(nrows) { Array.new(ncols) }) do |i,before|
可以写
(1..nrows).each_with_object([]) do |i,before|
但我希望前者更有效,因为它避免了before
不断扩大数组的需要。
在涉及 arrays 描述矩形网格的其他情况下(例如 Mindcraft 游戏),可以通过概念上在第一行之前和/或最后一行之后添加一行,和/或在第一列之前和/或最后之后。
如果您使用的是 Java,这是代码
通过使用基本方法
私有 static List<List> beforeFromAfter()
List<List<Integer>> after = Arrays.asList(Arrays.asList(2,5), Arrays.asList(7,17));
int s=0;
List<List<Integer>> before = new ArrayList<List<Integer>>();
for (int i = 0; i<=after.size()-1; i++) {
List<Integer> bRow = new ArrayList<Integer>();
for (int j=0; j<=after.get(i).size()-1; j++) {
//bRow.add(j,after.get(i).get(j));
if(i<1 && j<1) {
bRow.add(j,after.get(i).get(j));
s=s+after.get(i).get(j);
} else if(i>0 && j>0) {
bRow.add(j,after.get(i).get(j)-s);
} else {
bRow.add(j,after.get(i).get(j)-after.get(0).get(0));
s=s+after.get(i).get(j)-after.get(0).get(0);
}
}
before.add(i, bRow);
}
return before;
}
在 java 中尝试了一些东西。 只需将矩阵、n 和 m 作为方法中的参数传递。 它将返回您之前的矩阵。
public static int[][] getAfterMarix(int[][] before,int n, int m)
{
int initiate = before[0][0];
int temp = initiate;
for(int i=0; i<n ;i++)
{
for(int j=0;j<m;j++)
{
if(before[i][j]!=initiate)
{
if(before[i][j] == before[n-1][m-1])
{
before[i][j] = Math.abs(temp - before[i][j]) ;
}
else
{
temp += before[i][j];
before[i][j] -= initiate;
}
}
}
}
return before;
}
希望这可以进一步简化这个问题。
vector<vector<int>> getBeforeMatrix(vector<vector<int>> after) {
auto before = after;
int maxRows = after.size();
int maxCols = after[0].size();
for (int row = 0; row < maxRows; row++) {
for(int col = 0; col < maxCols; col++) {
if (row > 0) before[row][col] -= after[row - 1][col];
if (col > 0) before[row][col] -= after[row][col - 1];
if (row > 0 && col > 0) before[row][col] += after[row - 1][col - 1];
}
}
return before;
}
具有 O(N*M) 时间复杂度和 O(1) 空间复杂度的简单解决方案。
function findMatrix(mat) {
for(let i = 0; i < mat.length; i++)
{
for(let j = 0; j < mat[i].length; j++)
{
const after = mat[i][j];
const before = (i - 1 >= 0 ? mat[i - 1][j] : 0) + (j - 1 >= 0 ? mat[i][j - 1] : 0) + (i > 0 && j > 0 ? mat[i - 1][j - 1] : 0);
mat[i][j] = after - before;
}
}
return mat;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.