原文:
Write code to remove duplicates from an unsorted linked list.
FOLLOW UP
How would you solve this problem if a temporary buffer is not allowed?
译文:
从一个未排序的链表中移除重复的项
进一步地,
如果不允许使用临时的缓存,你如何解决这个问题?
链表问题基本上考虑:1 Hashtable神器 2 双指针大法
这题也不例外。如果用Hashtable Time: O(n), Space: O(n)
如果用双指针,Time: O(n^2), Space: O(1)
package LinkLists;
import java.util.Hashtable;
import CtCILibrary.LinkedListNode;
public class S2_1 {
// 利用Hashtable存储已经出现过的节点
// Time: O(n), Space: O(1)
public static void deleteDups1(LinkedListNode head) {
Hashtable<Integer, Boolean> ht = new Hashtable<Integer, Boolean>();
LinkedListNode pre = head;
LinkedListNode cur = head;
while(cur != null) {
if(ht.containsKey(cur.data)) { // 发现是重复元素,则跳过
pre.next = cur.next;
} else{ // 不是重复元素,记录到ht,并更新pre指针为当前指针
ht.put(cur.data, true);
pre = cur;
}
cur = cur.next;
}
}
// 用双指针,一个cur一个probe,对于某一个cur指针,用probe检查cur之后的所有指针
// 跳过相同部分。Time: O(n^2), Space: O(1)
public static void deleteDups2(LinkedListNode head) {
if( head == null ){
return;
}
LinkedListNode cur = head;
while(cur != null) {
LinkedListNode probe = cur;
while(probe.next != null) {
if(probe.next.data == cur.data) { // 检查到重复的,删掉
probe.next = probe.next.next;
} else{ // 没有重复的就直接检查下一个
probe = probe.next;
}
}
cur = cur.next;
}
}
public static void main(String[] args) {
LinkedListNode first = new LinkedListNode(0, null, null); //AssortedMethods.randomLinkedList(1000, 0, 2);
LinkedListNode head = first;
LinkedListNode second = first;
for (int i = 1; i < 10; i+=1) {
second = new LinkedListNode(i % 2, null, null);
first.setNext(second);
second.setPrevious(first);
first = second;
}
System.out.println(head.printForward());
LinkedListNode clone = head.clone();
deleteDups1(head);
deleteDups2(clone);
System.out.println(head.printForward());
System.out.println(clone.printForward());
}
}