# 2.6. Palindrome

## Check if a linked list is a palindrome

> 1 -> 2 -> 3 -> 2 -> 1, yes

## First idea

We need to know list length. Get a pointer to go to the end of the list, and another from the beginning, and get one pointer going forward and another going backward. Problem, singly linked list. How to go backward?

Iteratively create doubly linked list? But that defeats the purpose of a single linked list. Rough algorithm idea:

1. Iterate all list to know length
2. Calculate middle node, or middle point
3. Iterate to middle point, create reverse linked list
4. From middle point onwards, check if nums[i] == reverse_list[i-middle]

```java
public void check_permutation(LinkedListNode a){
    // Obtain length
    int len = 0;
    LinkedListNode head = a;
    while (head != null){
        head = head.next;
        len += 1;
    }

    // Obtain middle node or point
    // Obtain reverse list
    int middle = len/2;
    LinkedListNode middle_node = a;
    LinkedListNode reverse_list = null;
    while(middle >= 0){
        middle_node = a.next;
        reverse_list.data = a.data;
        reverse_list = null;
        reverse_list.next = a;
        middle -= 1;
    }
    reverse_list = reverse_list.next;

    // Check if all elements match
    while(middle_node != null){
        if (middle_node.data != reverse_list.data){
            return False;
        }
        middle_node = middle_node.next;
    }
    return True;
}
```

This has O(n + n/2 + n/2) = O(2n) time complexity, O(n) space complexity. But... should work. O(n) and O(n) isn't that bad.

## Hint 1

> A palindrome is something which is the same way forwards and backwards, what if you reverse the linked list?

Already reversed it, but only half. The other half isn't necessary. I think.

## Hint 2

> Try using a stack

A stack? Like a hash table?

> Stack is a linear data structure which follows a particular order in which the operations are performed. The order may be LIFO(Last In First Out) or FILO(First In Last Out).

I don't know how I could use this

## Hint 3

> Assume you have the length of the linked list, can you implement this recursively?

I would need to go backwards from the last node, and I don't know how to do that. As per my implementation, I can only start comparing once I have saved all the reverse half-list.

## Hint 4

> In the recursive approach, the middle is the base case: isPermutation(middle) is true. The node x to the immediate left of the middle: what can that node do to check if x -> middle -> y forms a palindrome= Now suppose that checks out, what about the previous node a? If x -> middle -> y is a palindrome, how can it check that a -> x -> middle -> y -> b is a palindrome?

Getting lost here... My problem is, how can we iterate backwards if this is a single linked list. If x -> middle -> y  is a palindrome, then we only need to check `a==b` for the next step, no need to check everything again. But how do I come to `x` from `middle` is my question. If I have to iterate from head to this node each time, it's not computationally effective at all!

## Hint 5

> There are ways to return multiple values, you can do this with a new class

Whattt

## Solution

### Reverse and compare

Reverse whole list, then compare only first half of both. Code somewhat similar to mine

### Iterative approach

Reverse the front half of the list, with a stack. We need to push the first half of the elements onto a stack, 2 ways to do this depending on whether or not we know the size of the linked list.

If we do, iterate through the first half of the elements in a standard for loop, pushing each element onto a stack. Careful when the length of the linked list is odd.

If we don't, iterate through the linked list using the fast runner/slow runner technique. At each step in the loop, push the data from the slow runner onto a stack. When the fast runner hits the end, the slow runner will have reached the middle. By then, the stack will have all the elements from the front of the linked list, but in reverse order.

Then simply iterate through the rest of the linked list, at each iteration compare the node to the top of the stack.

> This is what I was trying to do, but without knowing how to use stacks.

Stacks can be managed with push and pop. Code in [Github CTCI repo](https://github.com/careercup/CtCI-6th-Edition/blob/master/Java/Ch%2002.%20Linked%20Lists/Q2_06_Palindrome/QuestionB.java).

### Recursive approach

First we need to know when we've reached the middle element. We can do this by passing `length - 2` to each recursive function, if we do this N/2 times, we'll reach the middle. We still need to compare the node `i` to node `n-i`, how to do that?

The long explanation about the algorithm can be seen in book p219.
