leetcode234_回文链表

20 篇文章 0 订阅
10 篇文章 0 订阅

一. 迭代

1. 边移动快慢指针边反转链表的前半部分,等找到链表中点,再将前半部分与后半部分依次比较,判断是否为回文链表.

//大佬的思路, 反转后半部分.
class Solution {
public:
    //题解:快慢指针法,快指针走两步,慢指针走一步,找到链表的中点。然后,翻转后半部分。最后从头、中点开始判断是否相同。
    bool isPalindrome(ListNode* head) {
        if(!head||!head->next)return true;
        ListNode *fast=head,*slow=head,*pre=nullptr;
        //1、找到链表的中点,链表长度奇偶不影响
        while(fast&&fast->next){
            slow=slow->next;
            fast=fast->next->next;
        }
        //2、将slow之后链表进行断开且反转,最后翻转完成之后pre指向反转链表的头节点
        while(slow){
            ListNode *p=slow->next;
            slow->next=pre;
            pre=slow;
            slow=p;
        }
        //3、前后链表进行比较,注意若为奇数链表,后半部分回比前部分多1一个节点,然而我们只比较相同长度的节点值,巧妙地避开这点判断
        while(head&&pre){
            if(head->val!=pre->val)return false;
            head=head->next;
            pre=pre->next;
        }
        return true;
    }
};
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */

//自己的方法,边移动边反转前半部分的链表.
class Solution {
public:
    bool isPalindrome(ListNode* head) {
        if(head==NULL || head->next==NULL) return true;
        ListNode* pre = NULL;
        ListNode* slow = head;
        ListNode* fast = head;
        while(fast!=NULL && fast->next!=NULL) {
            //fast必须放在前面,因为slow后会反转链表,
            //造成fast->next取不到正确的.
            fast = fast->next->next;
            ListNode* tmp = slow->next;
            slow->next = pre;
            pre = slow;
            slow = tmp;
        }
        //画图可知, 当偶数时是正确的,奇数时需要slow往前next,这样正好比较
        //相同的数字.
        if(fast!=NULL && fast->next==NULL) slow = slow->next;
        while(slow!=NULL) {
            if(slow->val!=pre->val) return false;
            slow = slow->next;
            pre = pre->next;
        }
        return true;
    }
};

二. 递归

1. 我自己的递归方法,特别慢.

class Solution {
public:
    ListNode* findLast(ListNode* head, int len) {
        if(len==1) return head;
        if(len==2) return head->next;
        ListNode* last = findLast(head->next, len-2);
        return last->next;
    }
    bool isPalindromeN(ListNode* head, int len) {
        //递归终止.
        if(len==0 || len==1) return true;
        //head->next,len-2长度是否回文.
        bool flag = isPalindromeN(head->next, len-2);
        //找到末尾节点,进行比较.
        ListNode* last = findLast(head, len);
        if(head->val==last->val) return flag;
        else return false;
    }
    bool isPalindrome(ListNode* head) {
        if(head==NULL || head->next==NULL) return true;
        ListNode* cur = head;
        int len = 0;
        //求出链表长度
        while(cur!=NULL) {
            len++;
            cur = cur->next;
        }
        //函数作用返回head头结点,len长度链表是否回文.
        return isPalindromeN(head, len);
    }
};

2. 参考官方的.

class Solution {
public:
    ListNode* front = NULL;
    bool isPalindromeCheck(ListNode* head) {
        //递归终止.
        if(head==NULL) return true;
        //如果不满足回文,直接false.
        if(!isPalindromeCheck(head->next)) return false;
        //依次比较尾部节点和头结点判断是否回文.
        if(head->val!=front->val) return false;
        //更新头结点.
        front = front->next;
        return true;
    }
    bool isPalindrome(ListNode* head) {
        if(head==NULL || head->next==NULL) return true;
        //定义一个头结点用于比较.
        front = head;
        return isPalindromeCheck(head);
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值