三種方法判斷連結串列是否為迴文結構
阿新 • • 發佈:2018-12-30
判斷連結串列是否是迴文結構:如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個額外空間
用快慢指標遍歷連結串列,快指標一次走兩步,慢指標一次走一步,慢指標遍歷時將遍歷過的結點壓入棧中,快指標走完的時候,慢指標到達連結串列中間,棧頂到棧底是連結串列前半部分的逆序。
如果是奇數個元素,慢指標當前指向值(也就是中間位置)不壓入棧中,偶數個元素時,慢指標當前指向值也要壓入棧中。
慢指標繼續遍歷,同時棧元素彈出,若慢指標到達連結串列尾部,棧元素和慢指標遍歷位置元素都相等,則連結串列是迴文結構。
整個過程相當於把連結串列左邊折過來和連結串列右邊進行比較。
注意連結串列元素為奇數個和偶數個之間處理上的不同。
/* 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;
}
};