隨手練——S(n)=O(1),判斷一個鏈表是否為“回文”
阿新 • • 發佈:2019-02-01
eof img hide main for stack 回文 ron nod
方法一:T(n)=O(n),S(n)=O(n)
走完一遍鏈表,每個值入棧,之後再走一遍鏈表,和每次彈出的棧頂進行比較。
核心:
LNode *p = l->next; while (p) { s.push(p->data); p = p->next; } p = l->next; while (p) { if (p->data != s.top()) { cout << "fuck" << endl; break; } s.pop(); p = p->next; } if (!p)cout << "666" << endl;
完整:
#include <iostream> #include <stack> using namespace std; typedef struct LNode { struct LNode *next; int data; }*LinkList; LinkList init() { LinkList l = (LinkList)mallocView Code(sizeof(LNode)); l->next = NULL; return l; } void push_back(LinkList l,int x) { LNode *p = l; LNode *s= (LNode *)malloc(sizeof(LNode)); s->data = x; while (p->next) { p = p->next; } s->next = p->next; p->next = s; } int main() {int n; stack<int>s; LinkList l = init(); cin >> n; for (int i = 0; i < n; i++) { int t; cin >> t; push_back(l, t); } LNode *p = l->next; while (p) { s.push(p->data); p = p->next; } p = l->next; while (p) { if (p->data != s.top()) { cout << "fuck" << endl; break; } s.pop(); p = p->next; } if (!p)cout << "666" << endl; return 0; }
方法二:T(n)=O(n),S(n)=O(n)
用一個鬼畜(二倍速)指針,一個正常指針,當鬼畜指針到最後NULL時,正常指針正好到中間的位置(奇數),或者前半部分最後一個(偶數),然後將後半部分入棧,再一遍進行比較。
核心:
LNode *p = l->next,*pp=l->next; while (pp&&pp->next) { p = p->next; pp = pp->next->next; } p = p->next;//數據為偶數的話,p是停在前半部分最後一個,數據為奇數的話,跳過中間一個沒問題 while (p) { s.push(p->data); p = p->next; } p = l->next; while (!s.empty()) { if (p->data != s.top()) { cout << "fuck" << endl; break; } p = p->next; s.pop(); } if (s.empty())cout << "666" << endl;
完整代碼:
#include <iostream> #include <stack> using namespace std; typedef struct LNode { struct LNode *next; int data; }*LinkList; LinkList init() { LinkList l = (LinkList)malloc(sizeof(LNode)); l->next = NULL; return l; } void push_back(LinkList l,int x) { LNode *p = l; LNode *s= (LNode *)malloc(sizeof(LNode)); s->data = x; while (p->next) { p = p->next; } s->next = p->next; p->next = s; } int main() { int n; stack<int>s; LinkList l = init(); cin >> n; for (int i = 0; i < n; i++) { int t; cin >> t; push_back(l, t); } LNode *p = l->next,*pp=l->next; while (pp&&pp->next) { p = p->next; pp = pp->next->next; } p = p->next;//數據為偶數的話,p是停在前半部分最後一個,數據為奇數的話,跳過中間一個沒問題 while (p) { s.push(p->data); p = p->next; } p = l->next; while (!s.empty()) { if (p->data != s.top()) { cout << "fuck" << endl; break; } p = p->next; s.pop(); } if (s.empty())cout << "666" << endl; return 0; }View Code
方法三:T(n)=O(n),S(n)=O(1)
同樣用一個鬼畜(二倍速)指針,一個正常指針,不過這次,對後半部分 鏈表 進行反轉。
從兩個方向進行 遍歷,到中間結束,這個過程中把原來反轉的後半部分鏈表反轉回去。
鏈表反轉:
void reverse(LinkList l) { LNode *pre = NULL, *p = l->next; while (p) { LNode *t = p->next; p->next = pre; pre = p; p = t; } l->next = pre; }
核心:(這裏反轉是沒有頭結點的,要註意。代碼量稍微長了一點,過段時間看該費點勁了)
LNode *p = l->next,*pp=l->next; while (pp&&pp->next) { p = p->next;pp = pp->next->next; } p = p->next;//和上一解法相同 LNode *pre = NULL; while (p) { LNode *t = p->next; p->next = pre; pre = p; p = t; } p = l->next; LNode *q = pre; pre = NULL; while (q) { if (p->data != q->data) sign = 1;//需要反轉,不能break LNode *t = q->next; q->next = pre; pre = q; q = t; p = p->next; } p->next = pre;
完整代碼:
#include <iostream> #include <stack> using namespace std; typedef struct LNode { struct LNode *next; int data; }*LinkList; void push_back(LinkList l, int x) { LNode *p = l; LNode *s = (LNode *)malloc(sizeof(LNode)); s->data = x; while (p->next) { p = p->next; } s->next = p->next; p->next = s; } LinkList init() { LinkList l = (LinkList)malloc(sizeof(LNode)); l->next = NULL; int n; cin >> n; for (int i = 0; i < n; i++) { int t; cin >> t; push_back(l, t); } return l; } int main() { int n; int sign = 0; LinkList l = init(); LNode *p = l->next,*pp=l->next; while (pp&&pp->next) { p = p->next;pp = pp->next->next; } p = p->next;//和上一解法相同 LNode *pre = NULL; while (p) { LNode *t = p->next; p->next = pre; pre = p; p = t; } p = l->next; LNode *q = pre; pre = NULL; while (q) { if (p->data != q->data) sign = 1;//需要反轉,不能break LNode *t = q->next; q->next = pre; pre = q; q = t; p = p->next; } p->next = pre; if (!sign) cout << "666" << endl; else cout << "fuck" << endl; return 0; }View Code
隨手練——S(n)=O(1),判斷一個鏈表是否為“回文”