判断链表是否是回文结构:如1->2->3->2->1则是回文结构
目录
方法1:时间复杂度O(n),空间复杂度O(N),使用N个额外空间 最简单
方法2:时间复杂度O(n),空间复杂度O(N),使用N/2个额外空间
方法1:时间复杂度O(n),空间复杂度O(N),使用N个额外空间 最简单
将链表元素压入栈,遍历链表的同时弹出栈元素,判断遍历结点和弹出结点的值是否相等,如都相等,则是回文结构。
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};*/
class Palindrome {
public:
bool isPalindrome(ListNode* pHead) {
// write code here
ListNode * p = pHead;
stack<int> s;
if(pHead == NULL ||pHead->next == NULL)
return false;
while(p){
s.push(p->val);
p=p->next;
}
ListNode *t = pHead;
while(!s.empty()){
if(t->val != s.top()){
return false;
}
else{
s.pop();
t=t->next;
}
}
return true;
}
};
方法2:时间复杂度O(n),空间复杂度O(N),使用N/2个额外空间
用快慢指针遍历链表,快指针一次走两步,慢指针一次走一步,慢指针遍历时将遍历过的结点压入栈中,快指针走完的时候,慢指针到达链表中间,栈顶到栈底是链表前半部分的逆序。
如果是奇数个元素,慢指针当前指向值(也就是中间位置)不压入栈中,偶数个元素时,慢指针当前指向值也要压入栈中。
慢指针继续遍历,同时栈元素弹出,若慢指针到达链表尾部,栈元素和慢指针遍历位置元素都相等,则链表是回文结构。
整个过程相当于把链表左边折过来和链表右边进行比较。
注意链表元素为奇数个和偶数个之间处理上的不同。
扫描二维码关注公众号,回复:
4712768 查看本文章
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};*/
class Palindrome {
public:
bool isPalindrome(ListNode* pHead) {
// write code here
ListNode * fast = pHead;
ListNode * slow = pHead;
stack<int> s;
if(pHead == NULL ||pHead->next == NULL)
return false;
while(fast && fast->next){
s.push(slow->val);
slow = slow->next;
fast = fast->next->next;
}
ListNode * p ;
////这里有差别
if (fast== NULL)//链表个数为偶数
p = slow;
else
p = slow->next;
////
while(p && !s.empty()){
if(s.top()==p->val){
s.pop();
p= p->next;
}
else
return false;
}
return true;
}
};
或
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};*/
class Palindrome {
public:
bool isPalindrome(ListNode* pHead) {
// write code here
ListNode * fast = pHead;
ListNode * slow = pHead;
stack<int> s;
if(pHead == NULL ||pHead->next == NULL)
return false;
while(fast && fast->next){
s.push(slow->val);
slow = slow->next;
fast = fast->next->next;
}
ListNode * p = slow;
////这里有差别
if (fast!= NULL)//链表个数为奇数
s.push(slow->val);
///
while(p && !s.empty()){
if(s.top()==p->val){
s.pop();
p= p->next;
}
else
return false;
}
return true;
}
};
方法3:时间复杂度O(n),空间复杂度O(1),最优解
找到链表中间值,链表右半部分做逆序。从链表两段开始进行比较,如果两个指针相遇前,对应元素都相等,则是回文结构。
注意在做逆序的时候 ,设置逆序之后右边链表的最后一个元素的next指向null,并以此作为循环判断条件。
/*
struct ListNode {
int val;
struct ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};*/
class Palindrome {
public:
bool isPalindrome(ListNode* pHead) {
// write code here
ListNode* fast = pHead;
ListNode* slow = pHead;
while(fast&&fast->next){
fast = fast->next->next;
slow = slow->next;
}
ListNode *res = NULL;//逆序时遍历值
ListNode *next;
ListNode* p = pHead;
while(slow){
next = slow->next;
slow->next = res;
res = slow;
slow = next;
}
while(res){
if(p->val == res->val){
p=p->next;
res = res->next;
}
else{
return false;
}
}
return true;
}
};