leetcode- 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?

题意分析

  判断一个链表是否是回文链表。

  所谓回文,即从左往右和从右往左读都是一样的。例如:

  “abcdefgfedcba”

  1->2->3->3->2->1

  我们现在要做的,就是判断给定的链表是否满足这个特性。

  这题还有一个难点,就是时间复杂度与空间复杂度的限制。特别是空间复杂度限制太严格了。

 

解法一:

使用一个栈把遍历一遍的节点全存下来.

class Solution {
public:
    bool isPalindrome(ListNode* head) {
        ListNode *l=head;
        stack<ListNode *> s;
        while(head)
        {
            s.push(head);
            head=head->next;
            
        }
        int n=s.size()/2;
        for(int i=0;i<n;i++)
       // while(!s.empty())
        {
            ///cout<<i<<"   "<<s.size()/2<<endl;
            cout<<s.top()->val<<endl;
            cout<<l->val<<endl;
            if(s.top()->val==l->val)
            {
                
                l=l->next;
                s.pop();
            }
            else 
                return false;
                
                
        }
        return true;
    }
};

 

但是空间复杂度为N, 因此考虑怎么减少空间复杂度,

解法二: 使用递归的方法,虽然有局部的空间占用,但是可以规避空间复杂度的问题:

  • 终止条件:到达中间节点
  • 判断  链表: n2->n3->n4->...->n(size()-1)&&n1==n(size()); 
        ListNode* temp=head;
        int length=0;
        while(temp)
        {
            length++;
            temp=temp->next;
        }
        int mid=(length+1)/2;
        if(head==NULL||head->next==NULL)
            return true;
        
        ListNode * result=isEqual(head,1,mid,length);
        if(result!=NULL)
        {
            return true;
        }
        else
            return false;

    }
    ListNode * isEqual(ListNode *head, int index,int mid, int length)
    {
        if(mid==index&& length%2==1)
        {
            return head->next;
        }
            
        else if(mid==index && length%2==0)
        {
            if(head->val==head->next->val)
            {
                if(head->next->next!=NULL)
                    return head->next->next;
                else
                    return head->next;
            }
            else
                return NULL;
        }
        else
        {
            ListNode *t=isEqual(head->next,(index+1),mid,length);
            if(t==NULL)
                return NULL;
            else if(head->val==t->val)
            {
                if(t->next!=NULL)
                    return t->next;
                else
                    return t;
            }
            else
                return NULL;
            
            
            
            
        }

  

解法三:

  • 得到中点作为截止条件
  • 将后半段链表逆序
  • 遍历前半段与后半段
    
    ListNode * reverse(ListNode * head, int mid)
    {
        while(mid!=0)
        {
            head=head->next;
            mid--;
        }
        ListNode * a=NULL;
        while(head!=NULL)
        {
            
            ListNode *t=head;
            head=head->next;
            t->next=a;
            a=t;
            cout<<a->val<<endl;
           
         //   cout<<head->val<<endl;
        }
        return a;
    }
    bool isPalindrome(ListNode* head) {
 if(head==NULL||head->next==NULL)
            return true;
        int length=0;
        ListNode *c=head;
        while(c)
        {
            length++;
            c=c->next;
        }
        cout<<(length+1)/2<<endl;
        ListNode * a=reverse(head,(length+1)/2);
        while(a)
        {
            if(head->val==a->val)
            {
                head=head->next;
                a=a->next;
            }
            else
                return false;
        }
            
          return true;  
            
            
        }
    

  

posted @ 2017-08-02 17:05  hahahaf  阅读(123)  评论(0编辑  收藏  举报