请判断一个链表是否为回文链表。
示例1:
示例 2:
进阶:
你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
题解:
转换为数组
本题是非常经典的链表的题目,通过多种方法可以很好地训练思维。一般判断字符串是不是回文的非常容易,就是双指针法,一个指向头,一个指向尾,同时向中间遍历,如果不等直接返回false即可,链表我们也可以用相同的思路,将链表转换为数组然后进行判断
具体代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
|
class Solution { public boolean isPalindrome(ListNode head) { ListNode currNode = head; List<Integer> list = new ArrayList<>(); while (currNode != null) { list.add(currNode.val); currNode = currNode.next; }
int i = 0, j = list.size() - 1; while (i <= j) {
if (!list.get(i).equals(list.get(j))) { return false; } i++; j--; } return true; } }
|
栈
当然,利用栈的后进先出的特点,我们也可以达到目的
具体代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
|
class Solution { public boolean isPalindrome(ListNode head) { if (head == null) return true;
Deque<Integer> stack = new ArrayDeque<>(); ListNode curr = head; while (curr != null) { stack.push(curr.val); curr = curr.next; }
while (head != null) { if (head.val != stack.pop()) return false; head = head.next; } return true; } }
|
递归
一般的递归都可以改成栈的迭代方法,这里同样可以借助栈的思想来完成递归,具体思路大同小异。我们不断地递归直到链表的尾部停止,然后和另一个头节点进行比较,如果相等,则头节点后移,而递归栈中自然而然的返回尾节点的前一个节点,如果不等则返回false
具体代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
|
class Solution { ListNode temp;
public boolean isPalindrome(ListNode head) { temp = head; return help(head); }
private boolean help(ListNode node) { if (node == null) return true;
boolean flags = help(node.next) && (temp.val == node.val); temp = temp.next; return flags; } }
|
快慢指针
快慢指针思想很妙,但是本题中需要改变链表结构,而且官方也说了,实际工程中,如果多线程的话这种方法也不能使用。快慢指针的具体思想就是利用一快一慢指针找到链表的中点,然后将后半部分的链表翻转,这样一个指针从头开始,一个指针从尾开始进行遍历,遇到值不相同的就返回false
具体代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
|
class Solution { public boolean isPalindrome(ListNode head) { ListNode quick = head; ListNode slow = head; while (quick != null && quick.next != null) { quick = quick.next.next; slow = slow.next; } if (quick != null) { slow = slow.next; }
ListNode tail = reverse(slow);
while (tail != null) { if (head.val != tail.val) return false; head = head.next; tail = tail.next; } return true; }
private ListNode reverse(ListNode head) { ListNode pre = null; ListNode curr = head; while (curr != null) { ListNode temp = curr.next; curr.next = pre; pre = curr; curr = temp; } return pre; } }
|