zoukankan      html  css  js  c++  java
  • 随手练——S(n)=O(1),判断一个链表是否为“回文”

    方法一: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)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;
        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;
    }
    View Code

    方法二: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
  • 相关阅读:
    IDEA常用快捷键和设置
    java反射总结
    IO编程总结
    3月份主要学习
    idea中maven将jar包导入本地maven库
    hive常用命令
    CentOS7 安装图形化桌面
    vue+leaflet
    Springboot + Rabbitmq + WebSocet + vue
    VUE 中引入百度地图(vue-Baidu-Map)
  • 原文地址:https://www.cnblogs.com/czc1999/p/10346602.html
Copyright © 2011-2022 走看看