⭐算法入门⭐《栈》简单02 —— LeetCode 234. 回文链表

饭不食,水不饮,题必须刷

C语言免费动漫教程,和我一起打卡!
光天化日学C语言

LeetCode 太难?先看简单题!
C语言入门100例

数据结构难?不存在的!
画解数据结构

LeetCode 太简单?算法学起来!
夜深人静写算法

文章目录

  • 一、题目
    • 1、题目描述
    • 2、基础框架
    • 3、原题链接
  • 二、解题报告
    • 1、思路分析
    • 2、时间复杂度
    • 3、代码详解
  • 三、本题小知识

一、题目

1、题目描述

  给你一个链表,判断是否为回文链表。
  样例输入: 1 -> 2 -> 2 -> 1
  样例输出: true

2、基础框架

  • C语言 版本给出的基础框架代码如下:
bool isPalindrome(struct ListNode* head){
}

3、原题链接

( 1 ) (1) (1) LeetCode 234. 回文链表
( 2 ) (2) (2) 剑指 Offer II 027. 回文链表
( 3 ) (3) (3) 面试题 02.06. 回文链表

二、解题报告

1、思路分析

  • 回文,无非是从一个中心点向两边进行遍历,然后一旦判断不相等就可以直接返回 false。
  • 而作为链表,不像数组那样可以随机访问任意一个位置的元素。
  • 所以,我们可以把链表存到数组中,然后进行判定,当然,我们也可以用一个栈,利用栈后进先出的性质进行判定。
  • 有关 的实现,可以参见以下文章:《画解数据结构》栈。

2、时间复杂度

  • 由于每个括号最多入栈一次,出栈一次。
  • 所以时间复杂度: O ( n ) O(n) O(n)

3、代码详解

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
/************************************* 栈的顺序表实现 *************************************/
#define DataType int
#define maxn 100010

struct Stack {
    DataType data[maxn];
    int top;
}gStk;

void StackClear(struct Stack* stk) {
    stk->top = 0;
}
void StackPushStack(struct Stack *stk, DataType dt) {
    stk->data[ stk->top++ ] = dt;
}
void StackPopStack(struct Stack* stk) {
    --stk->top;
}

DataType StackGetTop(struct Stack* stk) {
    return stk->data[ stk->top - 1 ];
}
int StackGetSize(struct Stack* stk) {
    return stk->top;
}
bool StackIsEmpty(struct Stack* stk) {
    return !StackGetSize(stk);
}


/************************************* 栈的顺序表实现 *************************************/

int ListGetSize(struct ListNode* head) {      // 获取链表的长度
    int len = 0;
    if(!head) {
        return 0;
    }
    while(head) {
        head = head->next;
        ++len;
    }
    return len;
}

bool isPalindrome(struct ListNode* head){
    int len = ListGetSize(head);             // (1)
    if(len == 0) { 
        return true;                         // (2)
    }
    int cnt = 0;
    StackClear(&gStk); 
    while( cnt < len/2 ) {
        StackPushStack(&gStk, head->val);   // (3)
        head = head->next;
        ++cnt;
    }
    if(len & 1) {                          
        head = head->next;                  // (4)
    }
    while(head) {
        if( StackGetTop(&gStk) == head->val) {
            StackPopStack(&gStk);           // (5)
        }else {
            return false;
        }
        head = head->next;
    }

    return true;
}
  • ( 1 ) (1) (1) 遍历计算链表长度;
  • ( 2 ) (2) (2) 空链表,肯定是回文串的啦~;
  • ( 3 ) (3) (3) 将前半部分按顺序入栈;
  • ( 4 ) (4) (4) 如果链表长度为奇数,则跳过中间那个;
  • ( 5 ) (5) (5) 继续往后迭代遍历链表元素,如果 当前元素栈顶元素 相等,则出栈(类似括号匹配),一旦出现不相等的情况,就一定不是回文了,直接返回false,直到遍历完毕后返回true

三、本题小知识

   涉及到和逆序有关的问题,都可以想想怎么用 来解决。


你可能感兴趣的:(《LeetCode算法全集》,leetcode,算法,数据结构,链表,回文)