Palindrome Linked List

406 篇文章 0 订阅
406 篇文章 0 订阅

1,题目要求

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

Example 1:
Input: 1->2
Output: false

Example 2:
Input:1->2->2->1
Output: true

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

给出一个单链表,确定它是否是回文。

跟进:
你能在O(n)时间和O(1)空间做吗?

2,题目思路

对于这道题,是判断一个链表是否构成回文形式。
一般来说,判断一个字符串或者一个数组是不是回文比较简单,直接两端向中间依次进行比较即可,但是链表是个比较特殊的形式,尤其是题目中所规定的单链表。

因此,对于这个问题,我们有两种解决思路:
一种比较直观,直接对链表进行遍历,将其中所有的节点的值保存在一个数组中,然后按照数组的标准来实现回文序列的判断。

第二种方法,则是直接在链表上进行操作。
由之前的快慢指针法我们可以得知,当快指针到达尾部时,慢指针恰好走到了链表的中间位置。再由链表反转可得,我们只需要将后半段的链表进行反转,然后再依次对节点的值进行判断,也可以实现回文判断。这种方法不需要辅助内存。

3,代码实现

1,辅助数组

int x = []() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    return 0;
}();

class Solution {
public:
    bool isPalindrome(ListNode* head) {
        if(head == nullptr || head->next == nullptr)
            return true;
        vector<int> listNum;
        while(head!= nullptr)
        {
            listNum.push_back(head->val);
            head = head->next;
        }
        
        int n = listNum.size();
        for(int i = 0;i< n/2;i++){
            if(listNum[i]!= listNum[n-1-i])
                return false;
        }
        return true;
        
    }
};

2,反转后半链表

class Solution {
public:
    bool isPalindrome(ListNode* head) {
        ListNode* slow = head, *fast = head;
        while(fast!=NULL && fast->next!=NULL)
        {
            slow = slow->next;
            fast = fast->next->next;
        }

        if(fast!= NULL) //说明节点的个数为奇数个
            slow = slow->next;  //目的只是为了使得slow找到中间靠后一个的节点

        slow = reverseList(slow);
        fast = head;

        while(slow!=NULL)
        {
            if(slow->val != fast->val)
                return false;
            slow = slow->next;
            fast = fast->next;
        }
        return true;

    }
public:
	//反转链表
    ListNode* reverseList(ListNode* node){
        ListNode* pre = NULL;
        while(node!=NULL){
            ListNode* next = node->next;
            node->next = pre;
            pre = node;
            node = next;
        }
        return pre;
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值