题目没有说明可以更改输入链表,其实有点擦边了。
就谈这个算法,我之前为了定位到中间那个节点,一直是用计数操作。
期间为了精确确定i =0 , i<n/2 这个边界,纠结模拟半天。好费劲啊!这一点太弱了。
bool judge(struct ListNode *p,struct ListNode *q) { while( p && q) { if(p->val != q->val) return false; p = p->next; q = q->next; } return p==NULL && q==NULL; } bool isPalindrome_using_count(struct ListNode* head) { int i,n = 0; struct ListNode * p = head, *last = NULL, *pre= NULL; while(p!=NULL) { n ++; p=p->next; } if(n < 2) return true; p = head; for( i = 0; i < n/2; i++) { pre = p->next; p->next = last; last = p; p = pre; } if(n%2 != 0) return judge(last,pre->next); else return judge(last,p); }
人家用了快慢指针的方法,定位到最后,slow就是指向最中间那个(奇数个) 或者中间偏左那个 (偶数个)。
然后就容易了。可以把后面翻转,然后和head一个一个比较,最后结果是两个指针均为空,或者head多出一个。
另一种方法是,把前面翻转,和后面比较。单数的话,需要在后面新增一个最中间的节点。
代码
bool isPalindrome(struct ListNode* head) { struct ListNode * fast, *slow; fast = slow = head; if(head == NULL || head->next == NULL) return true; while(fast->next && fast->next->next) { slow = slow->next; fast = fast->next->next; } struct ListNode * p1, *p2; p2 = reverse(slow->next); slow->next = NULL; p1 = head; while(p1 && p2) { if(p1->val != p2->val) return false; p1= p1->next; p2= p2->next; } return p1 == NULL || p1->next == NULL; }
浙公网安备 33010602011771号