算法(TS):回文链表

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

示例 1:

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

示例 2:

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


提示:

  • 链表中节点数目在范围1, 105 内
  • 0 <= Node.val <= 9

进阶: 你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?

解答一

将链表中节点保存到一个Map中,key 为节点的次序,value 为节点。对比 Map 中第 n 个节点与第 total - n -1 个节点的值是否相等。

ts 复制代码
/**
 * 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 {
    if (!head) return false
    const nodeMap = new Map<number,ListNode>()
    let count = 0
    while(head) {
        nodeMap.set(count,head)
        head = head.next
        count++
    }

    const total = count
    count = 0
    const middle = Math.floor(total/2)
    while(count < middle) {
        if (nodeMap.get(count).val !== nodeMap.get(total-count-1).val) {
            return false
        }
        count++
    }

    return true
};

**

**

时间复杂度O(n + n/2),空间复杂度O(n)

解答二

  1. 定义两个指针,fast 和 low,fast 的移动速度是 low 的两倍,当fast移动到链表末尾时,low就移动到了链表中间
  2. 反转 low 到链表末尾这部分节点
  3. 将 fast 重置到链表头,同步移动fast和low,比较他们指向的节点值是否相等,不相同则不是回文链表
ts 复制代码
/**
 * 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 {
    if (!head) return false
    let fast = head
    let low = head
    while(fast && fast.next) {
        fast = fast.next.next
        low = low.next
    }
    // 如果 fast 不为 null,则说明传入的链表节点数为奇数
    if (fast) {
        low = low.next
    }

    low = reserve(low)
    fast = head
    while(low) {
        if (fast.val !== low.val) {
            return false
        }
        low = low.next
        fast = fast.next
    }

    return true
};

function reserve(head: ListNode):ListNode {
    let prev = null
    let current = null
    while(head) {
        prev = current
        current = head
        head = head.next
        current.next = prev
    }

    return current
}

时间复杂度O(n),空间复杂度O(1)

相关推荐
倒头就睡的小比特3 天前
算法竞赛C++常用的STL
c++·算法
小羊没烦恼!3 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
猎头南楼3 天前
知识社区推荐系统实践:新用户冷启动与长短期兴趣建模的挑战 资深推荐算法工程师
人工智能·深度学习·算法·机器学习
旖旎夜光3 天前
力控面试题 01.01: 判定字符是否唯一(位运算) —— 题解
c++·学习·算法·leetcode·力控
wzdark3 天前
大规模并行计算中的负载均衡算法研究4
算法
Because_of_Her13 天前
并查集-听课笔记
笔记·算法·并查集
码流子3 天前
高速公路安全监测实践:碰撞监测预警+物联网底座,从感知到处置的闭环
大数据·人工智能·物联网·算法·架构
another heaven3 天前
【算法/C++ MD5算法能否逆解码?原理、C++实现与同类哈希算法对比】
c++·算法·哈希算法
wzdark3 天前
从算法设计模式看编程思维的抽象能力4
算法
2601_962218613 天前
万象生鲜系统称重自动多退少补算法解决生鲜非标品痛点
大数据·数据库·人工智能·python·算法