我想知道你们是否可以指出一些更有效的数据结构,我可以代表一个NxN拼图板。
此时,它仍然是一个基本的二维矩阵(int[][]
)。虽然它有用,但我觉得它缺乏整体性能方面。
拼图本身被称为“滑动问题”,例如8puzzle,15puzzle,..
8拼图看起来像这样:
1 3 1 2 3
4 2 5 ---> 4 5 6
7 8 6 7 8
我正在使用的一个操作是O(n ^ 4),我想为此找到一个“解决方案”。 此操作尝试为每个电路板条目找到应该所在的值的坐标。 (距离启发式)
value = 1;
for(int i = 0; i <puzzle.length; i++)
for(int j = 0; j < puzzle[0].length; j++)
getPosition(value++)
getPosition也使用2 for循环:
for (int i = 0; i < puzzle.length; i++)
for (int j = 0; j < puzzle[0].length; j++)
if(puzzle[i][j]==value)
return new int[]{i,j};
我正在考虑使用HashMap,使用new int[]{x_coord, y_coord}
作为每个条目的键。
期待您的建议,提前谢谢!
答案 0 :(得分:1)
为了根据复杂性来优化数据结构(假设您有大小为100x100左右的板,这真的值得考虑),首先必须明确哪些操作将被最频繁地执行。
在这样的难题中可能经常需要的一项操作是
给定坐标(r,c):这些坐标是哪个数字?
阵列已经非常适合这种情况。可以考虑使用一维阵列来强制执行更多的数据局部性,但是需要详细的基准来证明这一决定的合理性。
您提到了另一项操作:
“此操作尝试为每个电路板条目找到应该存在的值的坐标”
这听起来有点不寻常,因为我无法想象你可能需要什么 - 除了,也许,对于某种“距离测量”。但是,此操作的核心可以表述为
给出一个数字x:这个数字的坐标(r,c)是什么?
这可以通过数组再次解决,即两个数组
int rows[] = new int[totalSize];
int cols[] = new int[totalSize];
所以给出你的例子中的董事会:
1 3
4 2 5
7 8 6
这些数组可以包含
rows = { 0, 0, 1, 0, 1, 1, 2, 2, 2 }
cols = { 0, 1, 1, 2, 0, 2, 2, 0, 1 }
也就是说,5
的坐标当前为(rows[5], columns[5]) = (1,2)
当然,您必须为应用于电路板的每次移动更新此数据结构。这意味着每次移动的开销都是恒定的(!)。但是对于较大的电路板,这很快就会付出代价,因为找到某个值的坐标现在只有O(1),与之前的O(n²)相反。