我有以下代码用于在棋盘游戏中对动作进行排序。在我看来它可以高度优化:
private List<Move> sortMoves(List<Move> moves, int depth)
{
List<Move> sorted = new ArrayList<Move>();
if (moves.size() == 0)
return sorted;
List<Move> primary = new ArrayList<Move>();
List<Move> rest = new ArrayList<Move>();
for(int i = 0; i < moves.size(); i++)
{
if (killers.primary[depth] != null && moves.get(i).equals(killers.primary[depth]))
primary.add(moves.get(i));
else
rest.add(moves.get(i));
}
sorted.addAll(primary);
sorted.addAll(rest);
return sorted;
}
上面是否有更好更有效的方法(即两个列表相交并返回一个排序列表)?
注意:该功能的目标是移除在移动列表中找到的杀手移动(主要),然后返回一个新的列表,其中首先移动杀手,然后移动原始移动列表中的列表。
答案 0 :(得分:2)
答案 1 :(得分:1)
如果您的moves
不是太大,那么当前的实现看起来不错。其复杂性为O(n)。只有这里是由于三个额外的列表即空间复杂性。 primary
,rest
和sorted
。
使用Collections.sort(List<T> list, Comparator<? super T> c)
可以节省一些空间复杂性。
private void sortMoves(final List<Move> moves, final int depth)
{
Collections.sort(moves, new Comparator<Move>() {
@Override
public int compare(Move o1, Move o2) {
if(killers.primary[depth] != null && moves.get(i).equals(killers.primary[depth])) {
return 0;
} else {
return 1;
}
}
});
}
这不使用任何额外空间,但时间复杂度为O(nlog(n))。此外,它的实现简洁。
更新:以下是另一个优雅的解决方案,没有额外的空间复杂性和O(n)时间复杂度。
private void sortMoves(final List<Move> moves, final int depth)
{
int i = 0;
int j = moves.size() - 1;
while(i < j) {
while(equalsKillersPrimary(moves.get(i), depth))
i++;
while(!equalsKillersPrimary(moves.get(j), depth))
j--;
swap(moves, i, j);
}
}
private boolean equalsKillersPrimary(Move move, int depth) {
return killers.primary[depth] != null && move.equals(killers.primary[depth]);
}
为简洁起见,我遗漏了swap()
的实施。它只是交换给定指标上的元素。