[英]Generalize hourglass movement in 2D Array - DS in Python
在通过这个 HackerRank 挑战为面试做准备时,偶然发现了一个障碍。
基本上想创建一个 function hourglassSum,它应该返回一个 integer(数组中的最大沙漏总和)。 给定一个 6 x 6 二维数组,arr:
1 1 1 0 0 0
0 1 0 0 0 0
1 1 1 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
arr 中有 16 个沙漏,沙漏总和是沙漏值的总和。 在这种情况下,沙漏的总和为 7。
这是我目前拥有的代码(它已被注释,因此也应该很容易理解所做的决定)
def hourglassSum(arr):
#print(f"arr: {arr}")
#print(f"arr[1]: {arr[1]}")
#print(f"arr[1][1]: {arr[1][1]}")
num_rows = len(arr)
num_cols = len(arr[0])
hg_total = 0
hg_current_sum = 0
hg_max_sum = 0
i = 0
j = 0
# There's no hourglass
if 0 <= num_rows <= 3 or 0 <= num_cols <= 3:
hg_total = 0
hg_max_sum = 0
# There's hourglass
else:
if num_rows > num_cols:
# hg_total = num_cols - 2 + ( num_rows - num_cols )
hg_total = num_rows - 2
#elif num_cols > num_rows:
else:
# hg_total = num_rows - 2 + ( num_cols - num_rows )
hg_total = num_cols - 2
# irrelevant and could be added to any of the others, transforming the elif into else
# else:
# hg_total = num_rows - 2
# only one hourglass
if hg_total == 1:
# calculate hg_current_sum
row_1 = arr[0][0:3]
row_2 = arr[1][1]
row_3 = arr[2][0:3]
#input
"""
1 1 1 0 0 0
0 1 0 0 0 0
1 1 1 0 0 0
0 0 2 4 4 0
0 0 0 2 0 0
0 0 1 2 4 0
"""
#print(f"row_1: {row_1}")
#print(f"row_2: {row_2}")
#print(f"row_3: {row_3}")
#output
"""
row_1: [1, 1, 1]
row_2: 1
row_3: [1, 1, 1]
"""
# Note that row_2 won't have sum() because it'll be always int and not a list of numbers
hg_current_sum = sum(row_1) + row_2 + sum(row_3)
hg_max_sum = hg_current_sum
return hg_max_sum
# Generalize
while i < num_rows:
row_1 = arr[i][0:3]
row_2 = arr[i+1][1]
row_3 = arr[i+2][0:3]
hg_current_sum = sum(row_1) + row_2 + sum(row_3)
# 9 is the highest value for a cell
# 7 is the amount of cells in each hourglass
# lowest_sum = -9 * 7
# Hightest_sum = 9 * 7
if hg_current_sum == 9*7:
hg_max_sum = hg_current_sum
break
elif hg_current_sum > hg_max_sum:
hg_max_sum = hg_current_sum
i = i + 2
while j < num_cols:
row_1 = arr[0][j:j+2]
row_2 = arr[1][j+1]
row_3 = arr[2][j:j+2]
hg_current_sum = sum(row_1) + row_2 + sum(row_3)
# 9 is the highest value for a cell
# 7 is the amount of cells in each hourglass
# lowest_sum = -9 * 7
# Hightest_sum = 9 * 7
if hg_current_sum == 9*7:
hg_max_sum = hg_current_sum
break
elif hg_current_sum > hg_max_sum:
hg_max_sum = hg_current_sum
j = j + 2
return hg_max_sum
如果我执行这个,它会给出一个
错误 (stderr) 回溯(最近调用最后一次):文件
“Solution.py”,第 119 行,在
结果 = hourglassSum(arr) 文件“Solution.py”,第 74 行,在 hourglassSum 中
row_3 = arr[i+2][0:3] IndexError: 列表索引超出范围
我遇到的问题是行为的泛化,从评论# Generalize
开始。 那一刻起,开始了不止一个沙漏的场景。
我可以看到沙漏的移动方式:左上角 -> 右上角(向右移动 1 个单元格,直到沙漏中最右边的单元格到达数组中最后一个现有列)并重复此过程,向下移动 1 个单元格直到沙漏中最下方的单元格到达数组的最后一行/底部。
可以看到它可以通过 for 循环(从顶部 -> 底部)内部的 for 循环(从左 -> 右)来完成。 所以,像
for i in range(num_rows)
# do stuff
for j in range(num_cells)
# do stuff
这通常会使循环内的部分几乎没有必要; 我把它们放在这里的唯一原因是可视化每个单元格向右或向底部的移动。
然后怎样呢?
向右移动,我会将沙漏的每个部分更新为“滑动 window”,减去之前最左边的元素并添加新的最右边元素。 将沙漏向下移动一行时开始一个新的沙漏。
这是 JavaScript 代码,可轻松转换为 Python:
function f(m){ if (m.length < 3 || m[0].length < 3) return null; let row1, row2, row3; let best = -Infinity; for (let i=0; i<m.length-2; i++){ // Update the hourglass moving down row1 = m[i][0] + m[i][1] + m[i][2]; row2 = m[i+1][1]; row3 = m[i+2][0] + m[i+2][1] + m[i+2][2]; best = Math.max(best, row1 + row2 + row3); for (let j=1; j<m[0].length-2; j++){ // Update the hourglass moving to the right row1 += m[i][j+2] - m[i][j-1]; row2 = m[i+1][j+1]; row3 += m[i+2][j+2] - m[i+2][j-1]; best = Math.max(best, row1 + row2 + row3); } } return best; } var m = [ [1, 1, 1, 0, 0, 0], [0, 1, 0, 0, 0, 0], [1, 1, 1, 0, 0, 0], [0, 0, 2, 4, 4, 0], [0, 0, 0, 2, 0, 0], [0, 0, 1, 2, 4, 0] ]; console.log(f(m));
这是 Python 代码:
def hourglassSum(arr):
#print(f"arr: {arr}")
#print(f"arr[1]: {arr[1]}")
#print(f"arr[1][1]: {arr[1][1]}")
num_rows = len(arr)
num_cols = len(arr[0])
hg_max_sum = -float('Inf') #-inf
hg_current_sum = 0
i = 0
j = 1
# There's no hourglass
if 0 <= num_rows <= 3 or 0 <= num_cols <= 3:
hg_max_sum = 0
for i in range(0,num_rows - 2):
# Update the hourglass moving down
row1 = arr[i][0] + arr[i][1] + arr[i][2];
row2 = arr[i+1][1];
row3 = arr[i+2][0] + arr[i+2][1] + arr[i+2][2];
hg_current_sum = row1 + row2 + row3
#print(f"1_ hg_current_sum: {hg_current_sum}")
hg_max_sum = max(hg_max_sum, hg_current_sum);
#print(f"1_ hg_max_sum: {hg_max_sum}")
for j in range(1,num_cols - 2):
# Update the hourglass moving to the right
row1 += arr[i][j+2] - arr[i][j-1];
row2 = arr[i+1][j+1];
row3 += arr[i+2][j+2] - arr[i+2][j-1];
hg_current_sum = row1 + row2 + row3
#print(f"2_ hg_current_sum: {hg_current_sum}")
hg_max_sum = max(hg_max_sum, hg_current_sum);
#print(f"2_ hg_max_sum: {hg_max_sum}")
return hg_max_sum
基本上不同的是现在
这将通过所有当前测试
public static int hourglassSum(List<List<int>> arr)
{
int[] sum = new int[16];
int hourglass = 0;
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
sum[hourglass] =
arr[i][j] + arr[i][j + 1] + arr[i][j + 2]
+ arr[i + 1][j + 1]
+ arr[i + 2][j] + arr[i + 2][j + 1] + arr[i + 2][j + 2];
hourglass++;
}
}
return sum.Max();;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.