zoukankan      html  css  js  c++  java
  • 回文链表--链表

    题目

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

    示例 1:

    输入: 1->2
    输出: false

    示例 2:

    输入: 1->2->2->1
    输出: true

    思想

     总体思路:

    1. 使用快慢指针找到链表的中间位置
    2. 反转前半部分链表
    3. 逐一对比前后两部分链表

     上面提到了快慢指针,我们来了解一下如下:

    利用快慢指针,将一个链表看成一个跑道, 假设a的速度是b的两倍, 那么当a跑完全程后, b刚好跑一半, 来找到中间节点的目的.

    slow 和 fast 指针都指向链表的第一个节点,然后slow 每次移动一个指针, fast每次移动两个指针.图如下:

    代码

    代码下面,可以直接运行,代码里面有注释

    public class ListNode {
        public var val: Int?
        public var next: ListNode?
        public init (_ val: Int) {
            self.val = val
            self.next = nil
        }
    }
    
    func isPalindrome(_ head: ListNode?) -> Bool {
        if head == nil || head?.next == nil {
            return true
        }
        var slow = head //慢指针每次移动一个元素,初始值为head
        var fast = head //快指针每次移动两个元素,初始值为head
        var pre = head  //用于前半部分逆转后的指针,指向head
        var prepare: ListNode? = nil
        while fast != nil && fast?.next != nil {//移动快慢指针,然后并将前半部分发转
            pre = slow
            slow = slow?.next
            fast = fast?.next?.next
            pre?.next = prepare
            prepare = pre
        }
        if fast != nil { //奇数时候,中间位置下一个(这样翻转才一样) 1->2->3->2->1,然后分为前半部分反转之后为2->1与原本之后的1->2,就是为了过掉奇数中的中间点3
            slow = slow?.next
        }
        while pre != nil && slow != nil {
            if pre?.val != slow?.val { //不一样的值,直接返回
                return false
            }
            pre = pre?.next //前半部分后移一位
            slow = slow?.next //后半部分后移一位
        }
        return true
    }

    结果

     上面的代码和逻辑以及说明都很清晰,希望对大家有所帮助,还是要动手呀,加油撒

  • 相关阅读:
    「Wallace 笔记」K-D tree 区域查询时间复杂度简易证明
    「LOJ #2980」「THUSCH 2017」大魔法师
    「Wallace 笔记」快速上手回文自动机(PAM)
    「ZJU Summer Training 2020
    「AtCoder AGC002F」Leftmost Ball
    文案高手的18项修炼
    高性能MySQL实战
    300分钟搞懂 Spring Cloud
    腾讯产品启示录
    300分钟吃透分布式缓存
  • 原文地址:https://www.cnblogs.com/guohai-stronger/p/11936506.html
Copyright © 2011-2022 走看看