LeetCode 206. Reverse Linked List(单链表的逆置) LeetCode234_PalindromeLinkedList (判断是否为回文链表)

单链表的逆置

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode *p1,*p2,*p3;
        if(head==NULL||head->next==NULL) return head;
        p1=head;
        p2=p1->next;
        while(p2)
        {
            p3=p2->next;
            p2->next=p1;
            p1=p2;
            p2=p3;
        }
        head->next=NULL;
        head=p1;
        return head;
    }
};


下一道题就是它的应用。

LeetCode234_PalindromeLinkedList (判断是否为回文链表)

题目:


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?


题解:
判断一个链表是不是回文的,这里要求O(n)时间复杂度和O(1)的空间时间复杂度,总共想了三种办法,三种办法都用到了两个指针,符合题目要求的只有最后一种。


第一种办法:用数组倒着存前半段的链表的值,然后和后半段链表的值进行比较。这种解法运行的时间最久可能是因为数组倒着插入比较耗时。

第二种解法:在第一种的思路的基础上,我们要实现一个倒序,我们干嘛不用现成的数据结构-栈,于是把链表前半段压栈,然后出栈和后面的链表依次比较,这种运行时间最短,但因为用到了栈还是不符合题目要求。
代码:

class Solution {
public:
    bool isPalindrome(ListNode* head) {
        if(head==NULL||head->next==NULL) return true;
        stack<ListNode> s;
        ListNode *fast=head;
        ListNode *slow=head;
        while(fast!=NULL&&fast->next!=NULL)
        {
            s.push(slow->val);
            slow=slow->next;
            fast=fast->next->next;
        }
        if(fast!=NULL&&fast->next==NULL)
        {
            slow=slow->next;
        }
        while(slow!=NULL)
        {
            int top=s.top().val;
            s.pop();
            if(top!=slow->val) return false;
            slow=slow->next;
        }
      return true;
    }
};
第三种:我们这样想,我们可不可以不借助外在的存储实现倒序呢,其实是可以的,链表反转的时候我们就没有借助外在存储。思路是把后半段的原地链表反转然后和前半段进行比较(当然你也可以反转前半段)运行时间稍微比第二种慢一些,但是符合题目O(1)空间复杂度的要求

代码:

class Solution {
public:
    bool isPalindrome(ListNode* head) {

        if(head==NULL||head->next==NULL) return true;
        ListNode *slow=head;
        ListNode *fast=head;
        while(fast!=NULL&&fast->next!=NULL)
        {
            slow=slow->next;
            fast=fast->next->next;
        }
        if(fast!=NULL&&fast->next==NULL)//奇数个节点
        {
            slow=slow->next;//指向了后半段的开始
        }
        //翻转后半段。
        ListNode *p1=slow;
        ListNode *p2=p1->next;
        while(p2)
        {
            ListNode *p3=p2->next;
            p2->next=p1;
            p1=p2;
            p2=p3;
        }
        slow->next=NULL;
        ListNode *newhead=p1;
        p2=head;
        while(p1!=NULL)
        {
            if(p1->val!=p2->val) return false;
            p1=p1->next;
            p2=p2->next;
        }
        return true;
    }
};

猜你喜欢

转载自blog.csdn.net/momo_mo520/article/details/80376905