回文链表的判断C++

我们先简单看一下题目与demo

题目描述: 给你一个单链表的头节点 head ,请你判断该链表是否为回文链表。如果是,返回 true ;否则,返回 false 。

回文链表的判断C++_第1张图片
这是一道比较简单的题目,按照回文的定义,要判断是否为回文链表,我们应该从链表的头和尾分别向中间靠拢,判断各对node的值是否都相等,大体思路是这样的。确定好大体思路后,我们开始来思考实现方式。
给题解之前,我想说说我做的过程中的一些想法。由于在做这道题之前,我做过一道回文数组的判断,这两有什么区别呢?无非就是数组头和尾在向中间靠拢的时候,可以直接用下标加减一的方式来实现,而链表(此时是指单链表)却好像只能用 head = head->next 从头向中间靠拢,而没法反方向过来从尾向中间靠拢,所以当时我就想,那我把链表遍历一遍建立一个新的数组,再判断这个数组是否为回文数组不就行了吗?越想越觉得有道理!直到我看见了这个tips.……回文链表的判断C++_第2张图片
最多10的5次方个节点,意思是如果我要采取这种做法,我初始化要建立的数组至少也要10的5次方,而且……可能这个做法也不是这道题真正想要考的

因此我改变了思路,还是要从链表来入手。当时我是这么想的,既然问题在于我无法从尾向中间靠拢,那我能不能重新建一个链表,让这个链表是跟原链表的右半段是相反的呢,似乎非常的合理。
这个时候我转过来考虑如何创建一个反过来的链表,创建链表其实就是向一个空链表插入一个或多个节点的过程,链表的插入我们有头插法和尾插法(不懂链表头插法与尾插法的请点 这里 ),很明显,头插法刚好可以实现我们的功能,也就是遍历一遍可以生成一个反转过来的链表,到这里我们大概有了一个大体的实现流程,接下来请看下面的代码:


// 链表长这样

struct ListNode {
	int val;
	ListNode *next;
	ListNode() : val(0), next(nullptr) {}
	ListNode(int x) : val(x), next(nullptr) {}
	ListNode(int x, ListNode *next) : val(x), next(next) {}
};

class Solution {
public:
    bool isPalindrome(ListNode* head) {
		//如果传进来的是空指针或者只有一个值 直接返回true
        if(head->next == nullptr||head == nullptr)
            return true;
        struct ListNode *slow = head;
        struct ListNode *fast = head;
        struct ListNode *rhead = nullptr;
        struct ListNode *store;
        //通过快慢指针找出右半边链表的头
        while(fast->next != nullptr && fast->next->next != nullptr){
                slow = slow->next;
                fast = fast->next->next;
        }
        slow = slow->next;	 //此时slow为右半链表的头
        //下面是实现右半链表的反转
        //注意 以下代码不是用我们上面所说的建一个新的链表 而是原地反转(很好的降低了空间复杂度)
        //算法详解会在代码下给出
        while(temp != nullptr){
            store = slow->next;
            slow->next = rhead;
            rhead = slow;
            slow = store;
        }
        //最终就是从头到尾开始注意比较各结点的值啦 如果出现不相等的则return false
        while(rhead != nullptr){
            if(rhead->val != head->val)
                return false;
            rhead = rhead->next;
            head = head->next;
        }
        return true;
    }
};

关于原地反转链表的算法大家可以看一下这篇文章,讲得很棒!
谢谢大家的阅读,有什么问题请在评论区评论

你可能感兴趣的:(编程,题解,链表,c++,数据结构)