题目描述:
就像骨头哥讲的那样,当你没有思路的时候我们仍然是先将常见的数据结构和算法思想想一遍,看看谁能解决问题。
他也给出了很多的解决方法:
- 将链表元素都赋值到数组中,然后可以从数组两端向中间对比。这种方法会被视为逃避链表,面试不能这么干。
- 将链表元素全部压栈,然后一边出栈,一边重新遍历链表,一边比较两者元素值,只要有一个不相等,那就不是。
- 优化方法2,先遍历第一遍,得到总长度。之后一边遍历链表,一边压栈。到达链表长度一半后就不再压栈,而是一边出栈,一边遍历,一边比较,只要有一个不相等,就不是回文链表。这样可以节省一半的空间。
- 优化方法3:既然要得到长度,那还是要遍历一次链表才可以,那是不是可以一边遍历一边全部压栈,然后第二遍比较的时候,只比较一半的元素呢?也就是只有一半的元素出栈, 链表也只遍历一半,当然可以。
- 反转链表法, 先创建一个链表newList,将原始链表oldList的元素值逆序保存到newList中,然后重新一边遍历两个链表,一遍比较元素的值,只要有一个位置的元素值不一样,就不是回文链表。
- 优化方法5,我们只反转一半的元素就行了。先遍历一遍,得到总长度。然后重新遍历,到达一半的位置后不再反转,就开始比较两个链表。
- 优化方法6,我们使用双指针思想里的快慢指针 ,fast一次走两步,slow一次走一步。当fast到达表尾的时候,slow正好到达一半的位置,那么接下来可以从头开始逆序一半的元素,或者从slow开始逆序一半的元素,都可以。
- 在遍历的时候使用递归来反转一半链表可以吗?当然可以,再组合一下我们还能想出更多的方法,解决问题的思路不止这些了,此时单纯增加解法数量没啥意义了。
回到自己。我当时看一眼就知道是力扣热题100中的题目(好早之前刷过),但是看到骨头哥给的解决方法中并没有我当时看到的解决方法。因此选择这个题目简单回顾一下之前的那种解决方法。
代码:
public static boolean isPalindromeByStack(ListNode head){
ListNode curr = head.next;
Stack<Integer> stack = new Stack<>();
while(temp != null){
if(stack.isEmpty() || stack.peek() != curr.val){
stack.push(curr.val);
} else {
stack.pop();
}
curr= curr.next;
}
return (stack.isEmpty());
}
只需要循环一遍,判断栈是否为空即可。 如果栈为空或者当前栈顶元素不等于当前节点的值就将当前节点的值入栈,若栈顶的值和当前节点的值相同那么就出栈。最后若栈为空则说明是回文序列,反之则不是。