设计一个高效的算法,从一个数组中删除所有的first-name重复的元素。
解:一个暴力的方法是用一个哈希表。对于名字的例子,我们需要一个哈希函数与一个仅用first name的相等函数。我们首先创建哈希表,然后遍历它把元素写入结果数组。时间复杂度为O(n),其中n为元素的个数。哈希表最坏情况的空间复杂度为O(n)。
如果我们复用输入数组来存储最终结果,则可以避免额外的空间复杂度。我们首先给数组排序,把相等的元素放到一起。排序用O(nlogn)的时间可以完成。接下来移除重复元素花费O(n)的时间。注意给数组排序要求元素是可比较的。
struct Name {
bool operator==(const Name &that) const {
return first_name == that.first_name;
}
bool operator<(const Name &that) const {
if(first_name != that.first_name) {
return first_name < that.first_name;
}
return last_name < that.last_name;
}
string first_name, last_name;
};
void EliminateDuplicate(vector<Name> *A) {
sort(A->begin(), A->end()); // 让相等的元素成为邻居
// unique()移除相邻的重复元素,返回最后一个没被删除元素后面的迭代器。erase()的作用是限制A仅有不重复元素
A->erase(unique(A->begin(), A->end()), A->end());
}
Python代码:
class Name:
def __init__(self, first_name, last_name):
self.first_name, self.last_name = first_name, last_name
def __eq__(self, other):
return self.first_name == other.first_name
def __lt__(self, other):
return (self.first_name < other.first_name
if self.first_name != other.first_name else
self.last_name < other.last_name)
def eliminate_duplicate(A):
A.sort()
for cand in A[1:]:
if cand != A[write_idx - 1]:
A[write_idx] = cand
write_idx += 1
def A[write_idx:]
Java代码:
public static class Name implements Comparable<Name> {
String firstName;
String lastName;
public int compareTo(Name name) {
int cmpFirst = firstName.compareTo(name.firstName);
if(cmpFirst != 0) {
return cmpFirst;
}
return lastName.compareTo(name.lastName);
}
}
public static void eliminateDuplicate(List<Name> A) {
Collections.sort(A);
int writeIdx = 1;
for (int i = 1; i < A.size(); i++) {
if (!A.get(i).firstName.equals(A.get(writeIdx).firstName)) {
A.set(++writeIdx, A.get(i));
}
}
A.subList(++writeIdx, A.size()).clear();
}
时间复杂度为O(nlogn),空间复杂度为O(1)。