三种方法判断链表是否为回文结构

判断链表是否是回文结构:如1->2->3->2->1则是回文结构

目录

方法1:时间复杂度O(n),空间复杂度O(N),使用N个额外空间 最简单

方法2:时间复杂度O(n),空间复杂度O(N),使用N/2个额外空间

方法3:时间复杂度O(n),空间复杂度O(1),最优解


方法1:时间复杂度O(n),空间复杂度O(N),使用N个额外空间 最简单

将链表元素压入栈,遍历链表的同时弹出栈元素,判断遍历结点和弹出结点的值是否相等,如都相等,则是回文结构。

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};*/
class Palindrome {
public:
    bool isPalindrome(ListNode* pHead) {
        // write code here
        ListNode * p = pHead;
        stack<int> s;
        if(pHead == NULL ||pHead->next == NULL)
            return false;
        while(p){
            s.push(p->val);
            p=p->next;
        }
        ListNode *t = pHead;
        while(!s.empty()){
            if(t->val != s.top()){
                return false;
            }
            else{
                s.pop();
                t=t->next;
            }
        }
        return true;
    }
};

方法2:时间复杂度O(n),空间复杂度O(N),使用N/2个额外空间

用快慢指针遍历链表,快指针一次走两步,慢指针一次走一步,慢指针遍历时将遍历过的结点压入栈中,快指针走完的时候,慢指针到达链表中间,栈顶到栈底是链表前半部分的逆序。

如果是奇数个元素,慢指针当前指向值(也就是中间位置)不压入栈中,偶数个元素时,慢指针当前指向值也要压入栈中。

慢指针继续遍历,同时栈元素弹出,若慢指针到达链表尾部,栈元素和慢指针遍历位置元素都相等,则链表是回文结构。

整个过程相当于把链表左边折过来和链表右边进行比较。

注意链表元素为奇数个和偶数个之间处理上的不同。

扫描二维码关注公众号,回复: 4712768 查看本文章
/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};*/
class Palindrome {
public:
    bool isPalindrome(ListNode* pHead) {
        // write code here
        ListNode * fast = pHead;
        ListNode * slow = pHead;
        stack<int> s;
       
        if(pHead == NULL ||pHead->next == NULL)
            return false;
        while(fast && fast->next){
            s.push(slow->val);
           
            slow = slow->next;
            fast = fast->next->next;
        }
           ListNode * p ;
////这里有差别
          if (fast== NULL)//链表个数为偶数
			p = slow;
			
		else
			p = slow->next;
////
        while(p && !s.empty()){
            if(s.top()==p->val){
                s.pop();
                p= p->next;
            }
            else
                return false;
        }
        return true;
    }
};

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};*/
class Palindrome {
public:
    bool isPalindrome(ListNode* pHead) {
        // write code here
        ListNode * fast = pHead;
        ListNode * slow = pHead;
        stack<int> s;
       
        if(pHead == NULL ||pHead->next == NULL)
            return false;
        while(fast && fast->next){
            s.push(slow->val);
           
            slow = slow->next;
            fast = fast->next->next;
        }
           ListNode * p = slow;
////这里有差别
          if (fast!= NULL)//链表个数为奇数
			 s.push(slow->val);
///
        while(p && !s.empty()){
            if(s.top()==p->val){
                s.pop();
                p= p->next;
            }
            else
                return false;
        }
        return true;
    }
};

方法3:时间复杂度O(n),空间复杂度O(1),最优解

找到链表中间值,链表右半部分做逆序。从链表两段开始进行比较,如果两个指针相遇前,对应元素都相等,则是回文结构。

注意在做逆序的时候 ,设置逆序之后右边链表的最后一个元素的next指向null,并以此作为循环判断条件。

/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};*/
class Palindrome {
public:
    bool isPalindrome(ListNode* pHead) {
        // write code here
        ListNode* fast  = pHead;
        ListNode* slow  = pHead;
        while(fast&&fast->next){
            fast = fast->next->next;
            slow = slow->next;
        }
        ListNode *res = NULL;//逆序时遍历值
        ListNode *next;
        ListNode* p = pHead;
        while(slow){
            next = slow->next;
            slow->next = res;
            res = slow;
            slow = next;
        }
        while(res){
            if(p->val == res->val){
                p=p->next;
                res = res->next;
            }
            else{
                return false;
            }
            
        }
        return true;
        
    }
};

猜你喜欢

转载自blog.csdn.net/gulaixiangjuejue/article/details/85197422
今日推荐