I see a lot of checks here, how can I reduce those and make my code more readable and covering all the edge cases?
Using a sentinel that points to the head can help reduce many of the checks:
Node insertNth(Node head, int data, int position) {
Node sentinel = new Node();
sentinel.next = head;
Node runner = sentinel;
for (int i = 0; i < position; ++i) {
runner = runner.next;
}
Node node = new Node();
node.data = data;
node.next = runner.next;
runner.next = node;
return sentinel.next;
}
Also, is there any recursive version possible for the given code because list is a recursive data structure hence, there should be some recursive way, right?
Naturally, a recursive solution is also possible:
Node insertNthRecursive(Node head, int data, int position) {
if (position == 0) {
Node node = new Node();
node.data = data;
node.next = head;
return node;
}
head.next = insertNthRecursive(head.next, data, position - 1);
return head;
}
Input validation
Keep in mind that both of these implementation assume sane input: position should be between 0 and the number of nodes in the list (inclusive). Unless the problem definition explicitly states that you can assume this, you should add input validation.