当前位置: 首页 > article >正文

数据结构与算法之链表: LeetCode 234. 回文链表 (Ts版)

回文链表

  • https://leetcode.cn/problems/palindrome-linked-list/description/

描述

  • 给你一个单链表的头节点 head ,请你判断该链表是否为回文链表
  • 如果是,返回 true ;否则,返回 false

示例 1

输入:head = [1,2,2,1]
输出:true

示例 2

输入:head = [1,2]
输出:false

提示

  • 链表中节点数目在范围[1, 1 0 5 10^5 105] 内
  • 0 <= Node.val <= 9
  • 进阶:你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?

Typescript 版算法实现


1 ) 方案1: 将值复制到数组中后用双指针法

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     val: number
 *     next: ListNode | null
 *     constructor(val?: number, next?: ListNode | null) {
 *         this.val = (val===undefined ? 0 : val)
 *         this.next = (next===undefined ? null : next)
 *     }
 * }
 */

function isPalindrome(head: ListNode | null): boolean {
    const vals = [];
    while (head) {
        vals.push(head.val);
        head = head.next;
    }
    for (let i = 0, j = vals.length - 1; i < j; ++i, --j) {
        if (vals[i] !== vals[j]) {
            return false;
        }
    }
    return true;
};

2 ) 方案2: 递归

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     val: number
 *     next: ListNode | null
 *     constructor(val?: number, next?: ListNode | null) {
 *         this.val = (val===undefined ? 0 : val)
 *         this.next = (next===undefined ? null : next)
 *     }
 * }
 */

let frontPointer;

const recursivelyCheck = (currentNode: ListNode | null): boolean => {
    if (currentNode) {
        if (!recursivelyCheck(currentNode.next)) {
            return false;
        }
        if (currentNode.val !== frontPointer.val) {
            return false;
        }
        frontPointer = frontPointer.next;
    }
    return true;
}
function isPalindrome(head: ListNode | null): boolean {
    frontPointer = head;
    return recursivelyCheck(head);
};

3 ) 方案3: 快慢指针

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     val: number
 *     next: ListNode | null
 *     constructor(val?: number, next?: ListNode | null) {
 *         this.val = (val===undefined ? 0 : val)
 *         this.next = (next===undefined ? null : next)
 *     }
 * }
 */

const reverseList = (head: ListNode | null): ListNode | null => {
    let prev = null;
    let curr = head;
    while (curr) {
        let nextTemp = curr.next;
        curr.next = prev;
        prev = curr;
        curr = nextTemp;
    }
    return prev;
}

const endOfFirstHalf = (head:ListNode | null): ListNode | null => {
    let fast = head;
    let slow = head;
    while (fast.next && fast.next.next) {
        fast = fast.next.next;
        slow = slow.next;
    }
    return slow;
}

var isPalindrome = function(head:ListNode | null):boolean {
    if (!head) return true;

    // 找到前半部分链表的尾节点并反转后半部分链表
    const firstHalfEnd = endOfFirstHalf(head);
    const secondHalfStart = reverseList(firstHalfEnd.next);

    // 判断是否回文
    let p1 = head;
    let p2 = secondHalfStart;
    let result = true;
    while (result && p2) {
        if (p1.val != p2.val) result = false;
        p1 = p1.next;
        p2 = p2.next;
    }        

    // 还原链表并返回结果
    firstHalfEnd.next = reverseList(secondHalfStart);
    return result;
};

http://www.kler.cn/a/502425.html

相关文章:

  • 用python编写一个放烟花的小程序
  • ElasticSearch 同义词匹配
  • 贪心算法笔记
  • WPF中如何在MVVM模式下跨线程更新UI
  • 语音技术与人工智能:智能语音交互的多场景应用探索
  • Django Admin 自定义操作封装
  • sql server 对 nvarchar 类型的列进行 SUM() 运算
  • Spring Boot 动态表操作服务实现
  • OS1.【Linux】大致介绍和环境搭建
  • Redis高危漏洞-GHSA-whxg-wx83-85p5:用户可能会使用特制的 Lua 脚本来触发堆栈缓冲区溢出
  • uc/os-II 原理及应用(八) 系统裁减以及移植到51单片机上
  • 掌握 Ubuntu 终端 mv 与 rename 命令的高效重命名使用方法
  • STM32-笔记42-实时时钟项目
  • uniapp 抖音小程序 getUserProfile:fail must be invoked by user tap gesture
  • CMake学习笔记(1)
  • 开源免费的下载工具AB Download Manager
  • 中等难度——python实现电子宠物和截图工具
  • 概率输出和独热分割掩码的主要区别:
  • 每日学习30分轻松掌握CursorAI:Cursor基础设置与配置
  • 商用服务器密码机的加密技术与优势
  • Win32汇编学习笔记11.游戏辅助的实现
  • fft分析数据求bode图原理
  • 【SQL】进阶知识 -- 删除表的几种方法(包含表内单个字段的删除方法)
  • html5各行各业官网模板源码下载 (4)
  • 初识@ffmpeg/ffmpeg库
  • Docker启动失败 - 解决方案