LeetCode.234 回文链表

题目描述:请判断一个链表是否为回文链表。

 

回文的意思就是,正着读跟反着读都是一样的。

 

题目地址:https://leetcode-cn.com/problems/palindrome-linked-list/

解法一:栈

 

既然是正反进行比较,刚好利用栈的“先进后出”特点,出栈的顺序刚好就是反着读。

 

出栈节点和原链表节点同时进行比较,有任意一个节点不相同,就不是回文。

 

时间复杂度:遍历链表O(N),出栈O(N),总计O(2N),去常数项O(N)

空间复杂度:调用系统栈需要额外空间O(N)

class Solution {
    public boolean isPalindrome(ListNode head) {
        Stack<Integer> stack = new Stack<>();

        ListNode temp = head;
        while(temp != null){
            stack.push(temp.val);
            temp = temp.next;
        }
        
        while (!stack.isEmpty()){
            if (head.val != stack.pop()){
                return false;
            }
            head = head.next;
        }
        return true;
    }
}

方法二:快慢指针+反转链表

 

快指针一次走2步,慢指针一次走1步,快指针走到null时,慢指针停下,此时慢指针就是中间节点。

 

将中间节点的下一个节点进行反转,此时如果是一个回文链表,将以中间节点为对称轴。

 

使用两个新的指针,一个从链表头开始,一个从反转部分的表头开始,走一步比较一次,如果有一个节点不想等就不是回文链表。

class Solution {
    public boolean isPalindrome(ListNode head) {
        if(head == null){
            return true;
        }
        ListNode leftHeadNode = head;
        ListNode midNode = findMidNode(head);
        ListNode rightHeadNode = reverseLinkedList(midNode.next);

        while (leftHeadNode !=null && rightHeadNode !=null){
            if (leftHeadNode.val != rightHeadNode.val){
                return false;
            }
            leftHeadNode = leftHeadNode.next;
            rightHeadNode = rightHeadNode.next;
        }

        return true;
    }
    /*
        反转链表:返回反转后的链表头节点
     */
    public ListNode reverseLinkedList(ListNode head){
        ListNode temp = null;
        ListNode cur = head;
        ListNode prevNode = null;
        while (cur != null){
            temp = cur.next;
            cur.next = prevNode;
            prevNode = cur;
            cur = temp;
        }
        return prevNode;
    }
    /*
        寻找中间节点
     */
    public ListNode findMidNode(ListNode head){
        ListNode fast = head;
        ListNode low = head;
        /**
         * 快指针一次走2步,慢指针一次走1步。
         * 快指针走到null时,慢指针停止,此时慢指针就是中间节点。
         */
        while (fast.next !=null && fast.next.next!=null){
            fast = fast.next.next;
            low = low.next;
        }
        return low;
    }
}

 

posted @ 2020-09-26 15:30  硬盘红了  阅读(90)  评论(0编辑  收藏  举报