任务:
鉴于包含整个非负数的2D数组m
,我们将"路径" 定义为相邻单元格的集合(对角线步骤不算作邻居)从row == 0 && col == 0
开始,以row == m.length - 1 && col == m[0].length - 1
结束。
"路径的费用"是"路径"。
的每个单元格中的值的总和示例:
数组中的两个可能路径:
路径1(虚线)的成本:8 + 4 + 2 + 8 + 9 + 9 + 7 + 5 = 52;
路径2的成本(实线):8 + 6 + 3 + 8 + 9 + 4 + 1 + 2 + 1 + 7 + 6 + 5 = 60
要做:
编写一个static
递归方法,接受一个填充了整个非负值的二维数组m
,并输出所有可能路径成本的总和(您可以假设m
不是null
也不是空的。
方法签名是(允许重载):
public static void printPathWeights(int [][] m)
我的代码:
public class Main {
public static void main(String[] args) {
int arr[][] = { { 1, 1, 1 },
{ 1, 1, 1 },
{ 1, 1, 1 }
};
printPathWeights(arr);
}
public static void printPathWeights(int[][] m) {
System.out.println(printPathWeights(m, 0, 0, new int[m.length][m[0].length], 0));
}
/*
* @param map marks the visited cells
*/
private static int printPathWeights(int[][] m, int row, int col, int[][] map, int carrier) {
if (row < 0 || col < 0 || row >= m.length || col >= m[0].length || map[row][col] == 1)
return 0;
if (row == m.length - 1 && col == m[0].length - 1)
return m[row][col] + carrier;
map[row][col] = 1;
return printPathWeights(m, row + 1, col, map, carrier + m[row][col]) +
printPathWeights(m, row - 1, col, map, carrier + m[row][col]) +
printPathWeights(m, row, col + 1, map, carrier + m[row][col]) +
printPathWeights(m, row, col - 1, map, carrier + m[row][col]);
}
}
上述代码的印刷值为:14
这比预期的少!
使用以下命令运行时
int arr[][] = { { 1, 1 },
{ 1, 1 }
};
结果是预期的6。
我的代码有什么问题?
PS:请不要向我提供解决作业的代码,但要解释我的代码有什么问题。
答案 0 :(得分:4)
代码标记一旦任意路径到达该单元格就访问的单元格。但是此细胞随后被标记为所有其他细胞的访问,并且不再被访问。这意味着该算法仅完成路径的子集,并且一些遍历在阵列中间的某处中断以获得更大的阵列。您必须将单元格标记为每条路径单独访问。
每次访问新单元格后,只需重置地图:
ULLONG_MAX
这将是最有效和最简单的方法。由于在访问单元格后复位了cellstate,因此它将永远不会从上一个路径中保留标记。
答案 1 :(得分:1)
正如Paul所说,您的代码所需的更改是在递归调用之后还原已访问的单元格集。它会按预期打印public class Main {
public static void main(String[] args) {
int arr[][] = { { 1, 1, 1 },
{ 1, 1, 1 },
{ 1, 1, 1 }
};
printPathWeights(arr);
}
public static void printPathWeights(int[][] m) {
System.out.println(printPathWeights(m, 0, 0, new int[m.length][m[0].length], 0));
}
/*
* @param map marks the visited cells
*/
private static int printPathWeights(int[][] m, int row, int col, int[][] map, int carrier) {
if (row < 0 || col < 0 || row >= m.length || col >= m[0].length || map[row][col] == 1)
return 0;
if (row == m.length - 1 && col == m[0].length - 1)
return m[row][col] + carrier;
map[row][col] = 1;
int result = printPathWeights(m, row + 1, col, map, carrier + m[row][col]) +
printPathWeights(m, row - 1, col, map, carrier + m[row][col]) +
printPathWeights(m, row, col + 1, map, carrier + m[row][col]) +
printPathWeights(m, row, col - 1, map, carrier + m[row][col]);
map[row][col] = 0; // Here
return result;
}
}
。
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="98" Width="128"
xmlns:local="clr-namespace:WpfApplication1">
<Window.DataContext>
<!-- This will auto create an instance of ViewModel -->
<local:ViewModel />
</Window.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Label Name="lblTimer" Grid.Row="1" Content="{Binding Path=CurrentTime}"></Label>
</Grid>
</Window>
答案 2 :(得分:0)
正如我所看到的那样,您只在一次递归中计算所有单元格的权重总和。但不考虑路径可能相交的事实,并且任何两条路径都可以有共同的单元格。就像图中所示的两条路径有共同的单元格并且必须添加两次