Anybody knows how to print single-linked list in reverse order (one pass and a fixed and independent of the number of elements RAM).
-
5Define "one pass". Does a recursive implementation that prints as it unwinds count? – Oliver Charlesworth Mar 24 '12 at 01:44
-
Isn't the point of a single linked list that they only have forward references? So as far as I know you would have to make a pass through to get to the last element, and then print backwards (pass 2). Am I wrong? – jdi Mar 24 '12 at 01:45
-
@OliCharlesworth: Hey, I consider that technically "one pass". – jdi Mar 24 '12 at 01:46
-
How can the amount of RAM possibly be independent of the number of elements? – Adam Liss Mar 24 '12 at 01:47
-
recursion is not suitable, its obvious, the point is to print it without saving all the elements in memory – Andrew K. Mar 24 '12 at 01:48
-
1Then I don't see how its possible. If you don't save a reference to the elements, then when you get to the last one you no longer know the previous ones. – jdi Mar 24 '12 at 01:49
-
@AndrewKorshunov: Then I would say that what you are asking for is not possible. You either have to store the input, or the output. – Oliver Charlesworth Mar 24 '12 at 01:50
-
to jdi: I understand that such a single-linked list, I got this question in the interview to work, said it was impossible, they told me I'm wrong – Andrew K. Mar 24 '12 at 01:51
-
Did you then ask them to explain themselves? They must holding out on some trick aspect to it. – jdi Mar 24 '12 at 01:52
-
upd: sorry for my english, its google.translator – Andrew K. Mar 24 '12 at 01:52
-
There are no apologies needed for the english. I dont think anyone here really holds people to that aspect of a question as long as the question is clear. – jdi Mar 24 '12 at 01:54
-
@jdi Yes, I asked. I put up, saying that this is the standard banal question on the interview – Andrew K. Mar 24 '12 at 01:55
-
7Your interviewers are jerks. – jdi Mar 24 '12 at 01:56
-
@jdi thanx for the clarification, I thought so – Andrew K. Mar 24 '12 at 02:01
-
Downvote. How did you get 2 upvotes for asking an impossible question? – GoalBased Mar 24 '12 at 03:37
-
Sorry, I first had a solution which didn't created a new List, but only worked with the list, but kept it in memory. Then I understood the requirement but forgot about the other, and implemented a multi pass solution. Now I see, I don't have a solution, and deleted it. – user unknown Mar 25 '12 at 12:47
10 Answers
My answer. There is no answer that solves this to your specs. It can't be multi-pass, it cant be recursive (which I think is considered single), it has to be constant memory...
I dont think you will discover a solution, and the people who said you could do it obviously have some form of a trick aspect to the question. They aren't obviously using the same set of definitions that this community is using.

- 90,542
- 19
- 167
- 203
-
1
-
*recursive* is not "constant RAM", it'll take `O(n)` RAM on the run-time stack. – Will Ness Jul 25 '12 at 18:06
-
@WillNess: My comment about recursion was not referring to the memory. It was referring to the "one-pass" requirements. The constant memory was a separate requirement. – jdi Jul 25 '12 at 18:32
-
it still is one of the requirements, so recursive was never an option. i.e. it wasn't an additional arbitrary restriction by OP. As it turns out *using files* was an answer. – Will Ness Jul 25 '12 at 18:36
-
@WillNess: I feel you might be mis-interpreting my answer. Also, the OP specifically said in the main comments that recursion is not allowed, which would have made it possible to do it in the stack unwind. I was simply pointing out that the combination of restrictions made the answer unclear to most of us. Many of the answers here kept hitting some of the criteria. If using files was the answer, then my comment on that answer holds true that there is a matter of trickery or lack of definition in the bounds of the question by the interviewers. – jdi Jul 25 '12 at 18:43
-
my point was that stack unwind *wasn't an option in the first place* (even if the OP were to allow it) because the stack needed is O(n), not constant. Of course using files is a *trick*, because they can be used to *simulate* RAM operations (just print all nodes out to a file in normal order, with *markers* between nodes, then read it backwards from that file while printing each node). – Will Ness Jul 26 '12 at 08:52
I think you can do that in O(n) time and O(1) space, but technically it's not "one pass".
- reverse the linked-list: O(n)
- print: O(n)
- reverse the linked-list back: O(n)

- 598
- 6
- 22
-
-
how to reverse a linked-list: http://stackoverflow.com/questions/1801549/reverse-a-singly-linked-list – StanleyZ Mar 25 '12 at 13:33
-
Whats the point of proposing this answer when its clearly another multipass solution? – jdi Mar 25 '12 at 16:06
-
2. and 3. are trivially combined into *one* pass: print each node as you re-link the list back. ***Two*** passes, constant RAM, ***sane*** solution. :) – Will Ness Jul 25 '12 at 18:02
The this option assumes that you know the count (if not that's one pass gone already), or failing that if you must use one pass, then just set count to some reasonable large maximum upper limit value.
long count = 10000; // set this to whatever the count is, or calcualte it
string filename = @"c:\foo.out";
using (StreamWriter writer = new StreamWriter(filename))
{
int index = 0;
long maxLength = 12; // set this to the max length of an item + 2 (for /r/n)
while(values.Next())
{
writer.BaseStream.Seek(maxLength * (count - index - 1), SeekOrigin.Begin);
writer.WriteLine(values[index].ToString().PadLeft(maxLength));
writer.Flush();
index++;
}
}
The output will be in the c:\foo.out
file, padded by spaces. Since the question did not state where you need to output, or what format the output should be in (such as not include blanks lines beforehand). Given it's a linked list the length could be very large (>int.MaxValue
), such that writing output to a file is quite a reasonable transport format.
This answer meets both O(n)
write performance (and indeed one pass), while also using no additional memory than the output stream which is always going to have to be O(n)
because how else will you fit them all on the screen..
A response to this answer would be that you can't seek
backwards in the output stream, then just print a \r
return character and seek backwards that way, failing that reply to the interviewer asking if identifying or meeting impossible requirements are part of the job description.

- 8,472
- 10
- 63
- 94
-
See, this is an example of what I was suggesting about the interviewers knowing some type of trick definition to their question. While the live output is being "printed" to the file in forward order, technically the resulting file will be in reverse order. But then again, one could argue that the file has not yet been "printed". Maybe the interviewers don't mean stdout like you are suggesting. Maybe the output needs to be printed to the terminal as its being accessed, while yours would require a final printing of the file (pass 2). No way to really know for sure. – jdi Mar 25 '12 at 16:11
-
so you trick the trickster, you use file instead of RAM. Nothing is said about files, so why even bother with blank lines - just prepend the lines as you go, using *two* files, even with a `system` call. – Will Ness Jul 25 '12 at 17:48
String s ="";
for(each element el in list)
s=el.data+", "+s;
println(s);
This is one pass.

- 5,873
- 14
- 49
- 72
Here is a solution with the java.util.LinkedList The memory stays the same since you remove and add the element to the same list. I think is reasonable to assume any decent implementation of a singly linked list will keep track of its size, head and tail.
import java.util.Arrays;
import java.util.LinkedList;
class PrintReverse {
public static void main(String[] args) {
Integer[] array = {1, 2, 3, 4};
LinkedList<Integer> list = new LinkedList<Integer>(Arrays.asList(array));
System.out.println(list);
printListBackward(list);
}
public static void printListBackward(LinkedList<Integer> list) {
int size = list.size();
for (int i = 0; i < size; i++) {
Integer n = list.removeLast();
list.push(n);
System.out.println(n.toString());
}
System.out.println(list);
}
}
Which produces the following output...
[1, 2, 3, 4]
4
3
2
1
[1, 2, 3, 4]
What do you think?

- 7,958
- 8
- 39
- 51

- 11
- 1
-
Hi Luis, I expanded on your code to make it complete and also showed the output produced. I think this answer actually satisfies the stated requirement of the OP. Very nice I think. – Rob Kielty Jul 13 '12 at 00:30
-
1wrong. each `removeLast()` is a pass in itself, `n` passes total. The normal re-linking solution is 2 passes, and the OP wants 1 pass - with constant RAM. – Will Ness Jul 25 '12 at 17:43
Well, you didn't say that it had to be efficient. (Plus there probably isn't a constant memory implementation that's more efficient.) Also, as commenters have pointed out, this is one-pass only when length(list) == 1
.
void printReversedLinkedList(listptr root) {
listptr lastPrinted = null;
while (lastPrinted != root) {
listptr ptr = root; // start from the beginning of the list
// follow until next is EoL or already printed
while (ptr->next != null && ptr->next != lastPrinted)
ptr = ptr->next;
// print current node & update last printed
printf("%s", ptr->data);
lastPrinted = ptr;
}
Constant memory, O(n^2) efficiency.

- 33,069
- 21
- 98
- 152
-
2
-
-
This issue here is that its possible to meet SOME of the given criteria from the OP but not ALL – jdi Mar 24 '12 at 01:58
-
@jdi how's that ***2*** passes? It's **n/2** passes, averaged. Two passes is O(n), n passes is O(n^2). – Will Ness Jul 25 '12 at 17:58
void printList(listItem node) {
if (node.next != null) {
printList(node.next);
}
echoOrSystemOutPrintlnOrPrintfOrWhatever(node.data);
}
printList(rootNode);

- 3,632
- 1
- 27
- 39
-
OP said it could not be recursive. Otherwise this would have been an answer already :-/ – jdi Mar 24 '12 at 02:03
-
Go through the singly linked list and push each item onto a stack. Pop the stack until it is empty, while printing out each element that is popped.
node = head of node list
stack = new Stack()
while ( node is not NULL )
{
stack.push( node.data )
node = node.next
}
while ( !stack.empty() )
{
print( stack.pop() )
}

- 76,204
- 83
- 211
- 292
I am really wondering how a singly linked list can be traversed reverse.

- 3,135
- 1
- 23
- 30