我目前正在解决一个必须优化一些代码的问题。最慢的方法之一是在列表中查找重复元素的方法。
方案中的重复项的工作方式如下:假设您有一个元素列表,每个元素都有两个ID,x和y。每个x值只能与一个y值配对,否则会将其视为重复值,并且原始值和重复值都必须添加到列表中。
例如,元素列表为(1,2)(1,2)(1,3)在这种情况下,重复列表将包含4个元素,(1,2,(1,3)和(1,2)(1,3),因为它们都具有相同的x值,但具有不同的y值。 (1,2)(1,2)不会被归类为重复项,因为x和y值相同。
当前代码使用嵌套的for循环,该循环检查两个元素的x值是否相等,但y值不同,但这很慢。
在实际情况中,要素是与患者匹配的肾脏供体。因此,每个捐赠者只能向单个患者捐赠。 X和Y是代表患者和供体ID的字符串。
如果有人知道更快的方法。
答案 0 :(得分:0)
只需检查x
或y
值中的任何重复。
class Person{
int id;
}
class Donor extends Person {}
class Patient extends Person {}
class Match {
Donor donor;
Patient patient;
}
private void test() {
List<Match> matches = new ArrayList<>();
list.addAll(...); // ID of donor-patient : (1, 2), (1, 2), (1, 3)
List<Match> duplicates = new ArrayList<>();
Set<Integer> donors = new HashSet<>();
Set<Integer> patients = new HashSet<>();
Set<Integer> duplicateDonors = new HashSet<>();
Set<Integer> duplicatePatients = new HashSet<>();
for (Match match : matches) {
if (!donors.add(match.donor.id)) {
duplicateDonors.add(match.donor.id);
}
if (!patients.add(match.patient.id)) {
duplicatePatients.add(match.patient.id);
}
}
for (Match match : matches) {
if (duplicateDonors.contains(match.donor.id) || duplicatePatients.contains(match.patient.id)) {
duplicates.add(match);
}
}
}
这使用了大量的HashSet
,因为HashSet
和add()
的{{1}}的时间复杂度(以大O表示)是contains()
。从理论上讲,这种方法是O(1)
,但是您需要做一个基准测试,看看它是否真的更快。