判断回文链表

问题描述

请判断一个链表是否为回文链表。链表为单向无环链表

示例 1:

 

输入: 1->2
输出: false

 

示例 2:

输入: 1->2->2->1
输出: true

 

解法一:

这题是让判断链表是否是回文链表,所谓的回文链表就是以链表中间为中心点两边对称。我们常见的有判断一个字符串是否是回文字符串,这个比较简单,可以使用两个指针,一个最左边一个最右边,两个指针同时往中间靠,判断所指的字符是否相等。

但这题判断的是链表,因为这里是单向链表,只能从前往后访问,不能从后往前访问,所以使用判断字符串的那种方式是行不通的。但我们可以通过找到链表的中间节点然后把链表后半部分反转,最后再用后半部分反转的链表和前半部分一个个比较即可。这里以示例2为例画个图看一下。

 

 

 

 

 

 最后再来看下代码:

 public boolean isPalindrome(ListNode head) {
        ListNode slow = head, fast = head;
        //快慢指针
        while (fast != null && fast.next != null) {
            slow = slow.next;
            fast = fast.next.next;
        }
        //如果fast不为空,说明链表的长度是奇数个
        if (fast != null) {
           slow=slow.next;
        }
        //反转后半部分链表
        slow = reverse(slow);
        fast=head;
        while (slow!=null){
            //不是回文
            if (fast.val!=slow.val){
                return false;
            }
            slow=slow.next;
            fast=fast.next;
        }
        return true;
    }

    //反转链表
    public ListNode reverse(ListNode head) {
        ListNode pre = null;
        while (head != null) {
            ListNode next = head.next;
            head.next = pre;
            pre = next;
            head = next;
        }
        return pre;
    }

 

解法二:

我们知道栈是先进后出的一种数据结构,这里还可以使用栈先把链表的节点全部存放到栈中,然后再一个个出栈,这样就相当于链表从后往前访问了,通过这种方式也能解决,看下代码:

public boolean isPalindrome1(ListNode head) {
        if (head == null) {
            return true;
        }
        ListNode temp = head;
        Stack<Integer> stack = new Stack();
        int len = 0;
        while (temp != null) {
            stack.push(temp.val);
            temp = temp.next;
            len++;
        }
        //长度除以2
        len >>= 1;
        while (len-- > 0) {
            if (head.val != stack.pop()) {
                return false;
            }
            head = head.next;
        }
        return true;
    }

 

解法三(递归):

  ListNode temp;
    public boolean isPalindrome2(ListNode head) {
        temp = head;
        return  check(temp);
    }
    private boolean check(ListNode head) {
        if (head == null){
            return  true;
        }
        //逆序打印链表
        boolean res = check(head.next) && (temp.val == head.val);
        temp = temp.next;
        return res;
    }

 

总结:

回文链表的判断,相比回文字符串的判断稍微要麻烦一点,但难度也不是很大,如果对链表比较熟悉的话,这3种解决方式都很容易想到,如果不熟悉的话,可能最容易想到的就是第2种了,也就是栈和链表的结合。

posted @ 2020-11-06 17:15  泉水姐姐。  阅读(100)  评论(0编辑  收藏  举报