偷偷刷题记录
回文链表
思路
思路1. 处理链表最粗暴的方式就是拷贝到数组中。考试时候也是,只要不会超内存,完全这么办
思路2. 快慢指针。因为我们判断是不是回文链表,回文的特性就是以中为界,两头对称。由于我们不能像使用数组一样采用中心拓展或者两边指针夹逼的方法。我们采用筛选中点与中点并反向链表比较的方式。
相比之下,第一种方式需要遍历一遍链表和一遍数组。
第二种方式,需要遍历一遍链表,翻转半个链表,再同时遍历两个半长度的链表。从耗时上说时间不变,但是不开辟额外空间。
C语言,链表转数组法
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
#define LINE 100000
bool isPalindrome(struct ListNode* head){
int val[LINE];
int count = 0;
while (head != NULL) {
val[count++] = head->val;
head = head->next;
}
if (count == 1) {
return true;
}
int left = 0;
int right = count - 1;
while (left <= right) {
if (val[left++] != val[right--])
return false;
}
return true;
}
C++ 快慢指针加链表翻转比较
class Solution {
public:
bool isPalindrome(ListNode* head) {
//找中点
ListNode *leftMid = getMidNode(head);
// 翻转右边,此时右边已经翻转了
ListNode *rightReverse = getReverseNode(leftMid->next);
// 回文比较
while (rightReverse != nullptr) {
if (head->val != rightReverse->val) {
return false;
}
head = head->next;
rightReverse = rightReverse->next;
}
return true;
}
ListNode *getReverseNode(ListNode *head) {
ListNode* prev = NULL;
ListNode* curr = head;
while (curr) {
ListNode* next = curr->next;
curr->next = prev;
prev = curr;
curr = next;
}
return prev;
}
ListNode *getMidNode(ListNode *head) {
ListNode *fast = head;
ListNode *slow = head;
while (fast->next != nullptr && fast->next->next != nullptr) {
fast = fast->next->next;
slow = slow->next;
}
return slow;
}
};