其他分享
首页 > 其他分享> > 力扣234、回文链表

力扣234、回文链表

作者:互联网

1、转成数组处理(208ms,33%;125MB,14%)

时间复杂度O(n):复制处是O(n),判断处是O(n/2)即O(n),相加即为O(n)

空间复杂度O(n):复制处用了大小为n的数组存链表数据,即O(n)

 1  bool isPalindrome(ListNode* head) {
 2         //直接对链表处理不方便,将其转化为动态数组处理
 3         vector<int>vec;
 4         while(head!=NULL){
 5             //push_back()在数组的最后添加一个数据
 6             vec.push_back(head->val);
 7             head=head->next;
 8         }
 9         //从头尾往中间包围
10         for(int i=0,j=vec.size()-1;i<=j;i++,j--){
11             if(vec[i]!=vec[j])
12             return false;
13         }
14         return true;
15     }

2、递归(204ms,40%;120MB,38%):看懂了写不出

时间复杂度O(n):用于比较了

空间复杂度O(n):回文检查前创建了n个堆栈帧

class Solution {
    ListNode* frontPointer;
public:
    //这个函数的特点是第二个if()错一次就全都会错
    bool recursivelyCheck(ListNode* head) {
        if (head != nullptr) {
            //先用这个if()到达链表最后一个数据
            if (!recursivelyCheck(head->next)) {
                return false;
            }
            //head从最后一个数据依次往前面返回,一旦不符合条件则会产生连锁反应
            if (head->val != frontPointer->val) {
                return false;
            }
            //如果第二个if()处的两者相同时把前指针frontPointer往后移
            //如果两者不相同则后面再也不会执行这一语句了
            frontPointer = frontPointer->next;
        }
        //作用1是当第一次到达尾部时返回真值以便不通过第一个if()去执行第二个if()
        //作用2是当后面程序中第二个if()的两个值相同时再次执行作用1的类似功能
        return true;
    }

    bool isPalindrome(ListNode* head) {
        frontPointer = head;
        return recursivelyCheck(head);
    }
};

3、快慢指针+链表反转(192ms,59%;115MB,62%)

时间复杂度O(n):快慢指针处、链表反转处、判断处都为O(n),综合也为O(n)

空间复杂度O(1):因为反转只是对原链表处理,堆栈帧不超过O(1)

 1 class Solution {
 2 public:
 3     bool isPalindrome(ListNode* head) {
 4         //先用first指向链表中间
 5         ListNode* first=FastAndSlow(head);
 6         //再用second保存后半部分链表反转后的首地址
 7         ListNode* second1=InversList(first->next);
 8         ListNode* second2=second1;
 9         //用begin指向整个链表的首地址
10         ListNode* begin=head;
11         bool flag=true;
12         while(flag&&second1!=NULL){
13             if(begin->val!=second1->val){
14                 flag=false;
15             }
16             begin=begin->next;
17             second1=second1->next;
18         }
19         //将后半部分链表重新反转为原来的样子
20         first->next=InversList(second2);
21         return flag;
22     }
23 
24     //快慢指针,该函数作用是定位到链表的中间
25     ListNode* FastAndSlow(ListNode* head){
26         ListNode* fast=head;
27         ListNode* slow=head;
28         while(fast->next!=NULL&&fast->next->next!=NULL){
29             //快指针每次走两格,慢指针每次走一个,结束则慢指针走一半
30             fast=fast->next->next;
31             slow=slow->next;
32         }
33         return slow;
34     }
35 
36     //链表反转,使用三个指针即可办到
37     ListNode* InversList(ListNode* head){
38         //front指向前一个数据,rear指向后一个数据,temp用于过渡
39         ListNode* front=head;
40         ListNode* rear=NULL;
41         ListNode* temp;
42         while(front!=NULL){
43             temp=rear;
44             rear=front;
45             front=front->next;
46             rear->next=temp;
47         }
48         return rear;
49     }
50 };

 

标签:力扣,head,ListNode,next,链表,234,return,指针
来源: https://www.cnblogs.com/Wow-A/p/15613777.html