[英]Given a set of objects that have 2 values. Sort the set with respect to the 1st value and then with the 2nd value
例如。:
{2,3},{1,2},(2,2},{3,1},{2,1} to {1,2},{2,1},{2,2},{2,3},{3,1}
这就是我的想法:
对第一列值进行合并排序。 迭代集合以查看第一列中是否存在任何重复值。 如果有,请将它们列入列表。
合并在第二列上对此列表进行排序,然后将它们集成到主集中。 虽然看起来确实可行,但似乎过于复杂。 这应该在O(NlogN)
运行,所以如果有人能想到更快/更复杂的算法也更简单,请发布它!
谢谢!
只需实现一个Comparator<T>
,它通过首先比较第一个字段,然后在第一个字段相等的情况下移动到第二个字段来比较您的类型的任何两个对象。 然后,您可以将该集复制到一个列表中,调用Collections.sort
并将其列入列表和比较器。 没有必要自己实现排序。
比较器将是这样的:
public class TwoFieldComparator implements Comparator<Foo>
{
public int compare(Foo first, Foo second)
{
// TODO: null checks
int firstComparison = Integer.compare(first.x, second.x);
return firstComparison != 0 ? firstComparison
: Integer.compare(first.y, second.y);
}
}
或者,您可以使您的类以相同的方式实现Comparable<T>
。
您需要做的是在第二列上执行稳定排序,然后在第一列上再次执行。
如果可以确定数字的范围,则可以通过某种线性排序来实现O(N)。
编辑:
以'merge sort'为例(因为它稳定):
1,在第二列上运行合并排序,然后根据第二列的值排列数字对。
2,在第一列上再次运行合并排序,数字对将按第一列值的顺序排列。 但是,因为排序方法是稳定的,这意味着如果第一个数字是相同的,第二个数字也将被排序(我们在第一个排序中进行了排序)。
因此,num对数组现在是有序的。 不再需要采取任何行动。
合并排序为O(NlogN),因此2 * O(NlogN)仍为O(NlogN)。
EDIT2:
好吧,我可能会让这个问题变得复杂。 即使需要由我们自己实现排序方法,只要确定了数据结构,Jon Skeet在手工制作排序方法的相应部分填充比较代码将是最方便的方法。
正如你在其中一篇文章中提到的,这是面试问题。 John Skeet的解决方案表明,您不必担心项目中有两个值 - 只需实现正确的比较器即可。
假设您在2011年被问到这一点,那么最好了解您的排序是如何使用的。 根据将使用此类型的环境,您可以考虑并行处理(使用多个线程)。 这可能会推动您选择排序算法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.