1.The 9 puzzle描述
2.代码分析部分
3.延伸N宫格
The 9 puzzle描述
Dispatch the integers from 0 to 8, with 0 possibly changed to None, as a list of 3 lists of size 3, to represent a 9 puzzle.
For instance, let [[4, 0, 8], [1, 3, 7], [5, 2, 6]] or [[4, None ,8], [1, 3, 7], [5, 2, 6]] represent the 9 puzzle
with the 8 integers being printed on 8 tiles that are placed in a frame with one location being tile free.
The aim is to slide tiles horizontally or vertically so as to eventually reach the configuration
It can be shown that the puzzle is solvable iff the permutation of the integers 1, …, 8, determined by reading those integers off the puzzle from top to bottom and from left to right, is even. This is clearly a necessary condition since:
sliding a tile horizontally does not change the number of inversions;
sliding a tile vertically changes the number of inversions by -2, 0 or 2;
the parity of the identity is even.
Complete the program nine_puzzle.py so as to have the functionality of the two functions:
validate_9_puzzle(grid) that prints out whether or not grid is a valid representation of a solvable 9 puzzle
solve_9_puzzle(grid) that, assuming that grid is a valid representation of a solvable 9 puzzle, outputs a solution to the puzzle, with a minimal number of moves.
代码分析部分
这道题其实就是判断给定九宫格是否是合法的,并且是可求解的。
如果是可以求解的,就求解。
对于是否合法,如果存在None,置换为0,如果不是1-8的数字和0/None构成,则不成立。
接下来判断是否有解,使用这段代码
1 | # sum为奇数时return |
判断可解的复杂度是O(N)
延伸N宫格
对于N宫格来说,判断是否有解。主要是判断反转(disorder)的个数。
反转:对于每一个格子来说,指的是在他之后(也就是从上到下,从左到右)的拥有更低的数字的格子。
对于奇数的盘,例如33的9宫格,则只需要判断反转数是否为奇数。为奇数,则有解。
对于偶数的盘,例如44的16宫格,需要判断反转数以及空格子的行数的和是否是偶数。为偶数,则有解。
最简单的算法也就是O(N^2),也就是上面的python代码。之后我用C写了一个O(NlogN)的,利用了归并排序。
1 | int mergeSort(int *arr,int size,int left,int right){ |
具体思路:由于每次归并,都是排好序的,所以当如果有个格子的左边比右边大时,在这个左边格子的之后所有格子都比右边要大,因此就可以计算出反转的个数。