• 回文链表


    题目:

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

    示例:

    输入: 1->2 输出: false 

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

    解题思路:

    如果是数组求回文就很简单。我们可以使用双指针法来比较两端的元素,并向中间移动。一个指针从起点向中间移动,另一个指针从终点向中间移动。

    然而这里是在链表中,因为不论是正向访问还是反向访问都不是 O(1)。而将链表的值复制到数组列表中是 O(n),因此最简单的方法就是将链表的值复制到数组列表中,再使用双指针法判断。

    时间和空间复杂度都是O(n)

    题目问能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题?

    这里主要介绍比较经典的双指针法,时间复杂度为O(n),空间复杂度为O(1)

    思路:

    a. 定义快慢双指针

    b. 关键点:找出mid,快指针前进2步,慢指针前进1步,最后循环结束慢指针为中间值

    c. 以mid为head进行后半段的反转

    d. 前半段与后半段的Val值依次比较,只要有对不上的立刻返回

    实现:

    //go
    func isPalindrome(head *ListNode) bool {
        if head == nil {
            return true
        }
        firstHalfEnd := endOfFirstHalf(head)
        secondHalfStart := reverseList(firstHalfEnd.Next)
    
        p1, p2 := head, secondHalfStart
        var res = true
        for res && p2 != nil {
            if p1.Val != p2.Val {
                return false
            }
            p1 = p1.Next
            p2 = p2.Next
        }
    
        // 反转恢复链表,写不写都可
        // firstHalfEnd.Next = reverseList(secondHalfStart)
        return res
    }
    
    // 找出中间节点
    func endOfFirstHalf(head *ListNode) *ListNode {
        slow, first := head, head
        for first.Next != nil && first.Next.Next != nil {
            slow = slow.Next
            first = first.Next.Next
        }
        return slow
    }
    
    // 反转链表
    func reverseList(head *ListNode) *ListNode {
        var pre, cur *ListNode = nil, head
        for cur != nil {
            tmpNext := cur.Next
            cur.Next = pre
            pre = cur
            cur = tmpNext
        }
        return pre
    }
    

      地址:https://mp.weixin.qq.com/s/AnpDP3mkfFMabU2mMiNg_g

     

     

  • 相关阅读:
    SystemTap
    在qemu上运行BusyBox
    Initramfs 原理和实践
    在qemu环境中用gdb调试Linux内核
    [转载] 你所不知道的TIME_WAIT和CLOSE_WAIT
    Linux VXLAN
    :not伪类选择器一些错误的写法
    c# 微软小冰-虚拟女友聊天
    Django使用表单操作数据库
    Django内置过滤器详解附代码附效果图--附全部内置过滤器帮助文档
  • 原文地址:https://www.cnblogs.com/smallleiit/p/13743293.html
Copyright © 2020-2023  润新知