The problem is to write an algorithm to split a given linkedlist efficiently into three almost-equivalent linkedlists, i.e.
if we have a linkedlist {1->5->7->9->2->4->6} the output should be
LL_1={1->5->7}, LL_2={9->2}, LL_3={4->6}
My solution does the following:
1-iterate the given linkedlist from start to end
2-at each node cache the nodes reference into an array, say ll_array
3-now we have the linkedlists size (ll_array.lenght) and all the node references
in an array which we can use to create the three linkedlists in a
straightforward manner
but the above algorithm requires O(n) time and O(n) space. Can this be done better?
Solution: based on hints from ChrisH. This alternative takes O(n) time but constant extra space (for the temporary holders)
Node { String value; Node next; } split(Node rootNode /*root node of input linked-list*/) { // root node of the three resulting linked-lists Node root_1 = rootNode; Node root_2 = null; Node root_3 = null; // previous nodes of linked-lists 2 & 3 (since ours is a singly-linked-list) Node prev_2 = null; Node prev_3 = null; int count = 0; // counter Node currentNode = rootNode; // temp holder while(currentNode != null) { count++; if (count > 3) { int mod = count % 3; if (mod == 1) { prev_2 = root_2; root_2 = root_2.next; prev_3 = root_3; root_3 = root_3.next; } else if (mod == 2) { prev_3 = root_3; root_3 = root_3.next; } } else if (count == 2) { // initialize linked-list-2 root_2 = currentNode; } else if (count == 3) { // initialize linked-list-3 root_3 = currentNode; } currentNode = currentNode.next; } // unlink linked-lists 2 & 3 from the chain prev_2.next = null; prev_3.next = null; }