234. 回文链表

  1. 快慢指针找中间节点
  2. 然后翻转中间节点起始的后半部分链表
  3. 再用双指针遍历比较值是否相等
  4. 返回原链表
找中间节点
  1. 两个快慢指针slow和fast指向head
  2. fast每次走两步,slow每次走一步
  3. 终止条件fast.next=null(奇数链表的结束)或fast.next.next=null(偶数链表的结束)
    中间.png
反转链表
  1. 三个指针当前节点cur,当前节点的后一个节点curNext,当前的节点前一个节点curPre
  2. 开始反转cur指向curPre,全部后移
  3. 终止条件cur不为空
    反转.png

代码

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public boolean isPalindrome(ListNode head) {
        if(head==null){
            return true;
        }

        //找中间节点
        ListNode halfNode=half(head);
        //翻转后一半链表
        ListNode lastNode=reverse(halfNode.next);
        //双指针比较
        while(lastNode!=null){
            if(head.val!=lastNode.val){
                return false;
            }
            head=head.next;
            lastNode=lastNode.next;
        }

        return true;
    }

    //中间节点
    public ListNode half(ListNode head){
        ListNode f=head;
        ListNode s=head;
        //f.next!=null奇数链表结束同时s指向中间节点
        //f.next.next!=null偶数链表结束s指向最中间两个节点的左节点
        while(f.next!=null&&f.next.next!=null){
            s=s.next;
            f=f.next.next;
        }

        return s;
    }

    //翻转链表
    public ListNode reverse(ListNode head){
        ListNode pre=null;
        ListNode cur=head;
        while(cur!=null){
        //临时保存cur.next因为后序 cur.next=pre;改变了
            ListNode curNext=cur.next;
            cur.next=pre;
            pre=cur;
            cur=curNext;
        }
        return pre;
    }

}

复杂度

时间复杂度O(n) n指的是链表的大小
空间复杂度O(1) 只会修改原本链表中节点的指向,而在堆栈上的堆栈帧不超过 O(1)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值