// use three references, pre, current, runner. No space consume static void doRemove2(SinglyLinkedList<Character> s) { SinglyLinkedList.Node<Character> pre = null; SinglyLinkedList.Node<Character> current = null; SinglyLinkedList.Node<Character> runner = null; pre = s.getHead(); current = pre.next; while (current != null) { runner = s.getHead(); while (runner != current) { if (runner.item == current.item) { pre.next = current.next; current = current.next; s.decreaseSize(); break; } runner = runner.next; } if (runner == current) { pre = current; current = current.next; } } }
// used for Object, null included // and here use hashmap rather than hashtable, // for any null object can not be used as a key or as a value in hashtable. static void doRemove1(SinglyLinkedList<Character> s) { HashMap<Character, Boolean> map = new HashMap<Character, Boolean>(); SinglyLinkedList.Node<Character> pre = null; SinglyLinkedList.Node<Character> node = s.getHead(); while (node != null) { if (map.containsKey(node.item)) { pre.next = node.next; s.decreaseSize(); } else { map.put(node.item, true); // 发现新值后再改变pre,不需要把head单独考虑,因为是从后面开始删除 pre = node; } // pre = node; node = node.next; } }
// only for Character, assume all ascii, without null static void doRemove(SinglyLinkedList<Character> s) { boolean[] check = new boolean[256]; SinglyLinkedList.Node<Character> pre = null; SinglyLinkedList.Node<Character> node = s.getHead(); while (node != null) { if (node.item == null) { System.out.println("---- Warning: null included! remove fail, use function doRemove1()"); return; } if (check[node.item]) { pre.next = node.next; s.decreaseSize(); } else // else 可以节省运算次数 check[node.item] = true; pre = node; node = node.next; } }