If the linked list is 1->2->3->4 then the output should be 1->3. If the linked list is 1->2->3->4->5, then the output should be 1->3->5.
The question is attributed to GeeksForGeeks. I'm looking for code-review, best practices and optimizations.
public class DeleteAlternate<T> {
private Node<T> first;
private Node<T> last;
private int size;
public DeleteAlternate(List<T> items) {
for (T item : items) {
create(item);
}
}
private void create (T item) {
Node<T> n = new Node<>(item);
if (first == null) {
first = last = n;
} else {
last.next = n;
last = n;
}
size++;
}
private final class Node<T> {
private Node<T> next;
private T item;
Node (T item) {
this.item = item;
}
}
public void deleteAlternate ( ) {
if (first == null) {
throw new IllegalStateException("The first node is null.");
}
Node<T> node = first;
// node == null, if even nodes are present in LL
// node.next == null, if odd nodes are present in LL
while (node != null && node.next != null) {
node.next = node.next.next;
node = node.next;
}
}
// size of new linkedlist is unknown to us, in such a case simply return the list rather than an array.
public List<T> toList() {
final List<T> list = new ArrayList<>();
if (first == null) return list;
for (Node<T> x = first; x != null; x = x.next) {
list.add(x.item);
}
return list;
}
@Override
public int hashCode() {
int hashCode = 1;
for (Node<T> x = first; x != null; x = x.next)
hashCode = 31*hashCode + x.hashCode();
return hashCode;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
DeleteAlternate<T> other = (DeleteAlternate<T>) obj;
Node<T> currentListNode = first;
Node<T> otherListNode = other.first;
while (currentListNode != null && otherListNode != null) {
if (currentListNode.item != otherListNode.item) return false;
currentListNode = currentListNode.next;
otherListNode = otherListNode.next;
}
return currentListNode == null && otherListNode == null;
}
}
public class DeleteAlternateTest {
@Test
public void test1() {
DeleteAlternate<Integer> dAlternate1 = new DeleteAlternate<>(Arrays.asList(1));
dAlternate1.deleteAlternate();
assertEquals(new DeleteAlternate<>(Arrays.asList(1)), dAlternate1);
}
@Test
public void test2() {
DeleteAlternate<Integer> dAlternate2 = new DeleteAlternate<>(Arrays.asList(1, 2));
dAlternate2.deleteAlternate();
assertEquals(new DeleteAlternate<>(Arrays.asList(1)), dAlternate2);
}
@Test
public void test3() {
DeleteAlternate<Integer> dAlternate3 = new DeleteAlternate<>(Arrays.asList(1, 2, 3));
dAlternate3.deleteAlternate();
assertEquals(new DeleteAlternate<>(Arrays.asList(1, 3)), dAlternate3);
}
@Test
public void test4() {
DeleteAlternate<Integer> dAlternate4 = new DeleteAlternate<>(Arrays.asList(1, 2, 3, 4));
dAlternate4.deleteAlternate();
assertEquals(new DeleteAlternate<>(Arrays.asList(1, 3)), dAlternate4);
}
@Test
public void test5() {
DeleteAlternate<Integer> dAlternate5 = new DeleteAlternate<>(Arrays.asList(1, 2, 3, 4, 5));
dAlternate5.deleteAlternate();
assertEquals(new DeleteAlternate<>(Arrays.asList(1, 3, 5)), dAlternate5);
}
}
1->2->3->4->5
really become1->2->5
? I assume that2
is a typo and should be3
. \$\endgroup\$