234. Palindrome Linked List

题目描述:

Given a singly linked list, determine if it is a palindrome.

Follow up:
Could you do it in O(n) time and O(1) space?

----------------------------------------------------------------------------------------------------------------------------

由于单链表不支持反向查找,因此不能像数组一样直接一个指针从前往后,一个指针从后往前。但是单链表却可以在线性时间内逆序并且不需要额外的空间,因此这道题的思路就是将链表一分为二,将后半部分进行逆序,然后比较前半部分和逆序后的链表是否值全部相等。但是需要注意的是要对链表长度是偶数和奇数进行判断,奇数的话,中间节点不需要判断。

现将代码粘贴如下:

class Solution {
public:
    bool isPalindrome(ListNode* head) {
        //可以将链表平均截成两段,将一段进行逆序,然后再遍历两个链表,看是否相等
        //当链表节点个数为奇数2n+1时,中间节点省略,前半部分1-n, 后半部分n+2到2n+1
        //当链表个数为偶数2n时,前面的n个节点不变,最后一个节点的next变为NULL,第n+1各节点开始逆序
        if(head == NULL || head->next == NULL)  //空节点或者只有一个节点肯定为回文
            return true;
        int length=0;
        ListNode *p=head;
        ListNode *head2 = head;
        while(p != NULL)
        {
            length++;
            p = p->next;
        }
        if(length%2 == 0)   //偶数
        {
            for(int i=0; i<length/2; i++)
                head2 = head2->next;
        }
        else    //奇数
        {
            for(int i=0; i<length/2; i++)
                head2 = head2->next;
            head2 = head2->next;    //还要往后挪一位
        }
        head2 = reverseList(head2);     //将后面的链表进行逆序
        for(int i=0; i<length/2; i++)
        {
            if(head->val != head2->val)
                return false;
            else
            {
                head = head->next;
                head2 = head2->next;
            }
        }
        return true;
    }
    
    ListNode* reverseList(ListNode *head)
    {
        if(head == NULL || head->next == NULL)  //空节点或者一个节点,直接返回
            return head;
        ListNode *pre = NULL;
        ListNode *cur = head;
        ListNode *after = head->next;
        while(after->next != NULL)
        {
            cur->next = pre;
            pre = cur;
            cur = after;
            after = after->next;
        }
        //最后还剩下最后两个节点没有逆序
        cur->next = pre;
        after->next = cur;
        return after;
    }
};



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值