力扣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