2022.4.10 回文链表

文章目录

  • 一、234. 回文链表
    • 1.题目
    • 2.分析
    • 3.代码


一、234. 回文链表

1.题目

给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false 。

2022.4.10 回文链表_第1张图片


2.分析

参考文章

先回忆判断一个字符串是不是回文串:双指针法从两端向中间逼近

bool isPalindrome(string s) {
    int left = 0, right = s.length - 1;
    while (left < right) {
        if (s[left] != s[right])
            return false;
        left++; right--;
    }
    return true;
}

但是单链表无法倒着遍历,无法使用双指针技巧,需要使用以下方法:
1、先通过 双指针技巧 中的快慢指针来找到链表的中点:
2022.4.10 回文链表_第2张图片

2、如果fast指针没有指向null,说明链表长度为奇数,slow还要再前进一步:
2022.4.10 回文链表_第3张图片

3、从slow开始反转后面的链表,现在就可以使用双指针法开始比较回文串了:
2022.4.10 回文链表_第4张图片

(还有一种思路是把原始链表反转存入一条新的链表,然后比较这两条链表是否相同。)

3.代码

package LinkedList;

/**
 * @author: LYZ
 * @date: 2022/4/10 15:26
 * @description:
 */
public class IsPalindrome {
    public static void main(String[] args) {
        ListNode head = new ListNode(1, new ListNode(2, new ListNode(2, new ListNode(1))));
        IsPalindrome isPalindrome = new IsPalindrome();
        boolean ans = isPalindrome.isPalindrome(head);
        System.out.println(ans);
    }

    public boolean isPalindrome(ListNode head) {
        ListNode fast = head;
        ListNode slow = head;

        while (fast != null && fast.next != null) {
            fast = fast.next.next;
            slow = slow.next;
        }

        // 当fast!=0时跳出循环,即fast.next=null,此时链表节点个数为奇数
        // 将slow再前进一位是为奇数链表的反转并用快慢指针做回文判断做准备
        if (fast != null) {
            slow = slow.next;
        }

        ListNode left = head;
        ListNode right = reverse(slow);
        while (right != null) {
            if (left.val != right.val) {
                // 注意比较的是左右指针指向的链表节点的val,不能比较指针(指针对应的是链表的节点及其后续所有节点)
                return false;
            }
            left = left.next;
            right = right.next;
        }

        return true;
    }

    ListNode reverse(ListNode head) {
        ListNode pre = null;
        ListNode cur = head;

        while (cur != null) {
            ListNode tmp = cur.next;
            cur.next = pre;
            pre = cur;
            cur = tmp;
        }
        // 初始化pre的值为null是因为链表最终应以null结尾,原地反转链表时需要让原链表的头节点指向null
        // 当while循环结束时cur的值为null,所以很容易理解为什么return pre
        return pre;
    }
}

你可能感兴趣的:(leetcode,算法,数据结构,职场和发展,java)