写在前面:
今天受实验室同学的启发,决定以后记录每天自己的leetcode的刷天记录,另外希望自己在做题时时能够深入思考,争取做到每做一题都能够有所收获。
时间:2020年10月13日
问题描述:请判断一个链表是否为回文链表。
示例:
输入: 1->2
输出: false
输入: 1->2->2->1
输出: true
进阶:你能否使用O(n)的时间复杂度和O(1)空间复杂度
思路:首先利用快慢指针找到链表的中间结点,然后再将链表从中间节点分割生成两个链表,最后比较两个链表是否相等
//找到链表的中间结点,并从中间结点将链表分割
ListNode *partLinkList(ListNode *head) {
auto head2 = new ListNode(0);
//利用快慢指针查找链表的中间结点
ListNode *slow = head;
ListNode *fast = head;
while (fast->next != nullptr && fast->next->next != nullptr) {
//慢指针每次移动一个结点,快指针每次移动两个结点
slow = slow->next;
fast = fast->next->next;
}
//循环结束时,慢指针指向中间节点
//当链表结点个数为奇数时,fast->next指向空节点
if (fast->next == nullptr) {
//当结点个数为奇数,分割链表,需要为申明一个结点指向第二个链表的头结点
head2->val = slow->val; //新节点值为中间结点的值
//分割链表
head2->next = slow->next;
slow->next = nullptr;
} else {
//链表个数是偶数
//分割链表
head2 = slow->next;
slow->next = nullptr;
}
return head2;
}
//翻转链表
ListNode* reverseLinkList(ListNode *head) {
ListNode* pre= nullptr;
auto cur=head;
while(cur!= nullptr){
auto temp=cur->next;
cur->next=pre;
pre=cur;
cur=temp;
}
return pre;
}
//判断链表是否是回文链表
bool isPalindrome(ListNode *head) {
//特殊情况判断
if (head == nullptr || head->next == nullptr)
return true;
//查找链表的中间结点后,分割链表,返回第二个链表的头结点
auto head2 = partLinkList(head);
//翻转第一个链表
head=reverseLinkList(head);
//判断两个链表是否相等
while (head!= nullptr){
if(head->val!=head2->val)
return false;
head=head->next;
head2=head2->next;
}
return true;
}
收获:
(1)、自己一开始并没有想到利用快慢指针查找链表中间结点的方法,而是想着将链表元素存进数组再做处理。
(2)、在做翻转链表处理时,自己并没有想到将pre结点设为null的方法。
(3)、指针传参,如果想要改变指针的指向,需要将函数的形参设为 ** 类型。