对于一个链表,请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法,判断其是否为回文结构。给定一个链表的头指针A,请返回一个bool值,代表其是否为回文结构。保证链表长度小于等于900。链表为无头结点、单向、不循环。(由于涉及到结构体,所以写不了完整的测试代码,下面展示的代码为LeetCode中写的代码)
//第一次尝试:
//方法一:最普通的方法,就是双循环,一个一个进行比较,这里就不演示了
//方法二:先逆转后一半元素,再进行比较,首先先找到中间元素(这个前面讲过,快慢指针),然后从中间元素开始,将后面的元素逆置(前面也讲过,三指针法),然后从两头开始比较
//方法三:递归法,一个指针保留原链表的头,利用递归找到尾结点,在一层层递归回去,在递归回去的过程中,从头比较元素
//递归的函数
//设置的保留头结点的指针 struct ListNode* slow = NULL; bool function(struct ListNode* head){ struct ListNode* node = head;
//递归结束条件 if(node == NULL){ return true; } struct ListNode* temp = node; node = node->next;
//如果不相同,就直接返回false if(!function(node)){ return false; }
//元素比较 if(slow->val != temp->val){ return false; }
//更新变量 slow = slow->next; return true; } bool isPalindrome(struct ListNode* head){ if(head == NULL||head->next == NULL){ return true; } //递归法
//保留头结点 slow = head; return function(head); //将后一半元素指向逆转,再判断 struct ListNode* fast = head; struct ListNode* slow = head; struct ListNode* temp = NULL;
//快慢指针找中点 while(fast&&fast->next){ fast = fast->next->next; temp = slow; slow = slow->next; } temp->next = NULL;
//三指针法逆置链表 struct ListNode* p1 = slow; struct ListNode* p2 = p1->next; struct ListNode* p3 = NULL; while(p2){ p3 = p2->next; p2->next = p1; p1 = p2; p2 = p3; } struct ListNode* node = head;
//从两头开始比较 while(node){ if(p1->val != node->val){ return false; } p1 = p1->next; node = node->next; } return true; }
浙公网安备 33010602011771号