import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Test; /** * Remove all elements from a linked list of integers that have value val. * <p> * Example * Given: 1 --> 2 --> 6 --> 3 --> 4 --> 5 --> 6, val = 6 * Return: 1 --> 2 --> 3 --> 4 --> 5 * <p> * Tags: Linked List * Similar Problems: (E) Remove Element, (E) Delete Node in a Linked List */ public class RemoveLinkedListElements { private RemoveLinkedListElements r; /** * Create a dummy head and check the next element. * If the element is head, the head needs to be updated. * If in the middle, we skip this element by connecting previous one to the next next. * If the element is tail, doesn't really matter. */ public ListNode removeElements(ListNode head, int val) { ListNode dummy = new ListNode(-1); dummy.next = head; ListNode cur = dummy, next = head; while (next != null) { if (next.val == val) { cur.next = next.next; } else { cur = cur.next; } next = next.next; } return dummy.next; } /** * Recursive version. * Base case: if head is null, just return null. * Relation: remove elements from current linked list can be divided into two parts: * 1. Remove elements from the rest of the list except head * 2. Check whether head should be removed * The resulted list should be the combination of them. */ public ListNode removeElementsRecursive(ListNode head, int val) { if (head == null) return null; head.next = removeElementsRecursive(head.next, val); return head.val == val ? head.next : head; } @Before public void setUp() { r = new RemoveLinkedListElements(); } @Test public void testEdgeCases() { Assert.assertNull(r.removeElements(null, 0)); ListNode head = new ListNode(1); Assert.assertNull(r.removeElements(head, 1)); Assert.assertNotNull(r.removeElements(head, 0)); Assert.assertEquals(1, r.removeElements(head, 0).val); } @Test public void testExamples() { // 1 --> 1, val 1 ListNode n1 = new ListNode(1); ListNode n2 = new ListNode(1); n1.next = n2; Assert.assertNull(r.removeElements(n1, 1)); // 1 --> 2 --> 6 --> 3 --> 4 --> 5 --> 6, val 6 n1 = new ListNode(1); n2 = new ListNode(2); ListNode n3 = new ListNode(6); ListNode n4 = new ListNode(3); ListNode n5 = new ListNode(4); ListNode n6 = new ListNode(5); ListNode n7 = new ListNode(6); n1.next = n2; n2.next = n3; n3.next = n4; n4.next = n5; n5.next = n6; n6.next = n7; ListNode res = r.removeElements(n1, 6); Assert.assertNotNull(res); int[] vals = {1, 2, 3, 4, 5}; for (int val : vals) { Assert.assertEquals(val, res.val); res = res.next; } } @After public void tearDown() { r = null; } public class ListNode { int val; ListNode next; ListNode(int x) { val = x; } } }