随手练——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;
}

方法二: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;
}

方法三: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;
}

原文地址:https://www.cnblogs.com/czc1999/p/10346602.html

时间: 2024-10-15 20:00:12

随手练——S(n)=O(1),判断一个链表是否为“回文”的相关文章

请判断一个链表是否为回文链表。

/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ class Solution { public boolean isPalindrome(ListNode head) { if(head==null || head.next == null){ return true; } Lis

判断一个字符串是否为回文-链队(新建,进队,出队),链栈(新建,进栈,出栈)

回文:字符对称排列的字符串,例如ABCBA 思路:根据队:先进先出和栈: 先进后出的原则,进行比较出队和出栈的字符是否相等.如果相等,则为回文. 创建控制台应用程序. 1 #region 字符节点类 2 class CharNode 3 { 4 public char Char //字符 5 { 6 get; 7 set; 8 } 9 public CharNode Next //下一节点 10 { 11 get; 12 set; 13 } 14 public CharNode(char Cha

判断一个整数是否为回文数 Check if a number is palindrome

一种方法是先翻转当前数,然后把它和原数比较(略) 另一种是递归方法,借用一个复制数,对原数递归,使之翻转,然后配合复制数比较 package recursion; public class Check_if_a_number_is_palindrome { public static void main(String[] args) { int num = 121321; System.out.println(check(num)); num = 12321; System.out.printl

判断一个数字是否为回文数

Determine whether an integer is a palindrome. Do this without extra space.(source) 判断一个数字是否为回文数,并且不使用额外的存储空间. "回文"是指正读反读都能读通的句子,那么回文数,就很容易理解,就是指一个数正反读的值是相同的.还有一个要求是不要使用额外的存储空间. Hints: 要将一个数的最高位与最低位比较,取出一个数的最低位容易(x%10),但要得到高位却很难. Solution 1: 首先得知

leecode---09---数字,取余整除---判断一个数字是否是回文

https://leetcode.com/problems/palindrome-number/description/ 题意 判断一个数字是否是回文 分析 32132132100 /100 删去0的部分 %100 留下0的部分 代码 class Solution { public boolean isPalindrome(int x) { if (x < 0) return false; //计算到x的最高位 int div = 1; while (div * 10 <= x) { div

java语言判断一个数字是否为回文数字

判断一个整数是否是回文数.回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数. 示例 1: 输入: 121 输出: true 示例 2: 输入: -121 输出: false 解释: 从左向右读, 为 -121 . 从右向左读, 为 121- .因此它不是一个回文数. 示例 3: 输入: 10 输出: false 解释: 从右向左读, 为 01 .因此它不是一个回文数. 进阶: 你能不将整数转为字符串来解决这个问题吗? 解法一:使用字符串反转,比较反转前后的字符串是否相等 class

回文指的是一个字符串从前面读和从后面读都一 样,编写一个算法判断一个字符串是否为回文。

回文指的是一个字符串从前面读和从后面读都一 样,编写一个算法判断一个字符串是否为回文. 要求: 1)采用链栈实现算法: 2)从键盘输入一个字符串,输出判断结果. #include"stdio.h" #include"stdlib.h" typedef char ElemType; typedef struct stnode { ElemType data; struct stnode *next; }StNode, *LinkStack; int huiwen(ch

判断一个整数是否是回文数C++实现 leetcode系列(九)

判断一个整数是否是回文数.回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数. 示例 1: 输入: 121 输出: true 示例 2: 输入: -121 输出: false 解释: 从左向右读, 为 -121 . 从右向左读, 为 121- .因此它不是一个回文数. 示例 3: 输入: 10 输出: false 解释: 从右向左读, 为 01 .因此它不是一个回文数. 这道验证回文数字的题如果将数字转为字符串,就变成了验证回文字符串的题,没啥难度了,我们就直接来做follow up吧

C实例--判断一个字符串是否是回文数

回文是指顺读和反读内容均相同的字符串,例如"121","ABBA","X"等.本实例将编写函数判断字符串是否是回文. 引入两个指针变量,开始时,两个指针分别指向字符串的首末字符,当两个指针所指字符相等时,两个指针分别向后和向前移动一个字符位置,并继续比较,直到两个指针相遇,说明该字符串是回文,如果比较过程中发现两个指针指向的字符不相等,则判断该字符串不是回文. 下面是代码的实现部分: #include <stdio.h> #inclu