leetcode 题号#234 回文链表

查看题目详情可点击此处

题目

请判断一个链表是否为回文链表。

示例 1:

输入: 1->2
输出: false

示例 2:

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

解题思路

首先理解回文的意思,回文就是正着读和反着读得到的结果都一样,那最直接的解题思路就是拷贝一份反转的链表,再与原链表从头结点开始比对,如果完全一致就是回文链表,但空间复杂度和时间复杂度都为 O ( n ) O(n) O(n),为了把空间复杂度降低需要重新转换思路。

仔细思考,其实回文还有另外一种判断方式,就是从中间结点往头结点和尾结点方向读取,得到的结果是一样的,但题目给出的是单链表,如果是双向链表操作就会简单很多,单链表的情况只能把前半段链表反转,以中间结点作为头结点,头结点为前半段的尾结点,后半段链表也以中间结点为头结点,尾结点作为尾结点,这样循环比对每个结点,就可以判断回文。

要知晓链表的中间结点只能先获取整个链表的长度,奇数长度的链表中间结点分别是第 n / 2 n/2 n/2 n / 2 + 2 n/2+2 n/2+2个结点,偶数结点的中间结点分别是第 n / 2 n/2 n/2 n / 2 + 1 n/2+1 n/2+1个结点,得知中间结点的是链表中的第几个结点后,可以遍历获取中间结点作为头结点的同时对前半段链表进行反转,最后进行相应链表结点的比对即可,代码如下。

class Solution {
    public boolean isPalindrome(ListNode head) {
        if(head == null || head.next == null) {return true;}
        int len = getLinkLen(head);

        int leftHeadCounter = len / 2;

        ListNode[] halfHeads = findHalfHead(head, leftHeadCounter, len);

        ListNode leftHalfHead = halfHeads[0];
        ListNode rightHalfHead = halfHeads[1];
        ListNode leftCurr = leftHalfHead;
        ListNode rightCurr = rightHalfHead;

        while(leftCurr != null && rightCurr != null) {
            if(leftCurr.val != rightCurr.val) {
                break;
            }

            leftCurr = leftCurr.next;
            rightCurr = rightCurr.next;
        }


        return leftCurr == null && rightCurr == null;
    }
    
    public ListNode[] findHalfHead(ListNode head, int leftHeadCounter, int len) {
        ListNode[] halfHeads = new ListNode[2];

        ListNode curr = head;
        ListNode prevNode = null;
        ListNode reverseNode = null;
        int counter = 0;
        while(curr != null) {
            counter++;
            if(leftHeadCounter == counter) {
                halfHeads[0] = curr;
                break;
            }

            reverseNode = curr;
            curr = curr.next;
            prevNode = reverseLink(reverseNode, prevNode);
        }

        ListNode rightHalfHead = halfHeads[0].next;
        if(len % 2 == 1) {
            rightHalfHead = rightHalfHead.next;
        }
        halfHeads[1] = rightHalfHead;
        reverseLink(halfHeads[0], prevNode);

        return halfHeads;
    }

    public ListNode reverseLink(ListNode reverseNode, ListNode prevNode) {
        reverseNode.next = prevNode;
        return reverseNode;
    }

    public int getLinkLen(ListNode head) {
        int len = 0;

        ListNode curr = head;
        while(curr != null) {
            len++;
            curr = curr.next;
        }

        return len;
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值