描述
例:
输入:{1,2,2,1}
返回: true
解题思路
方法一:使用vector数组
遍历链表,将链表中的值转移到vector中,在vector中通过比较头尾的值来判断链表是否为回文结构
c++ list容器
1.创建一个包含10个元素的list容器,初始值为5
list values(10,5)
2.拷贝其他类型的容器,创建list容器
arrayarr{1,2,3,4,5};
list values(arr.begin()+2,arr.end());//拷贝{3,4,5}
3.访问 list 容器中存储元素的方式很有限,即要么使用 front() 和 back() 成员函数,要么使用 list 容器迭代器。
list 容器不支持随机访问,未提供下标操作符 [] 和 at() 成员函数,也没有提供 data() 成员函数。
list mylist{1,2,3,4,5};
auto it=mylist.begin();
while(it!=mylist.end()){
cout<<*it<<" ";
++it;
}
class Solution {
public:
bool isPail(ListNode* head) {
if(head->next==nullptr) return true;
vector<int> nums;
while(head!=nullptr){
nums.push_back(head->val);
head=head->next;
}
for(int i=0;i<nums.size()/2;i++){
if(nums[i]!=nums[nums.size()-1-i])
return false;
}
return true;
}
};
时间复杂度:O(N),两次遍历;
空间复杂度:O(N),列表存储数据需要的size为n。
方法二:反转链表
首先找到链表的中间节点,将中间节点后的节点进行链表的翻转,然后对两部分进行回文判断。
class Solution {
public:
bool isPail(ListNode* head) {
if(!head||!head->next) return true;
ListNode* fast = head;
ListNode* slow = head;
while(fast && fast->next){ //通过快慢指针找到中点
fast = fast->next->next;
slow = slow->next;
}
if(fast){//如果fast不为空,说明链表的长度是奇数个
slow = slow->next;
}
//反转后半部分链表
slow = reverse(slow);
fast = head;
while(slow!=nullptr){
if(fast->val!=slow->val) return false;
fast = fast->next;
slow = slow->next;
}
return true;
}
ListNode* reverse(ListNode* head){
ListNode* prev=NULL, *tmp, *cur = head;
while(cur){
tmp = cur->next;
cur->next = prev;
prev = cur;
cur = tmp;
}
return prev;
}
};