美文网首页
拜托,面试别再问我回文链表了!!!

拜托,面试别再问我回文链表了!!!

作者: TomorrowWu | 来源:发表于2018-10-23 20:06 被阅读0次

    题目描述

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

    示例1:

    输入: 1->2
    输出: false
    

    示例2:

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

    进阶:

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

    解题思路

    思路1

    • 遍历链表,用数组存下每个节点的值,然后从数组两头开始向中间遍历,是否相等
    • 时间复杂度O(n),空间复杂度O(n)

    思路2

    • 遍历一遍链表,得到链表长度n,根据长度的奇偶,找到中间节点,将左半边的链表反转,然后从中间节点分两个方向向左右两边遍历,是否是回文;对左半部分链表进行反转,还原为最初的链表
    • 只需要固定的若干个临时变量,不需要额外开辟空间
    • 时间复杂度为O(n),空间复杂度为O(1)

    代码实现

    // ListNode Definition for singly-linked list.
    type ListNode struct {
        Val  int
        Next *ListNode
    }
    
    // 解法1
    // 用数组存前面的一半节点的值
    // 时间复杂度:O(N)
    // 空间复杂度:O(N)
    func isPalindrome(head *ListNode) bool {
        // 空链表,算回文
        if head == nil {
            return true
        }
    
        var data []int
        for cur := head; cur != nil; cur = cur.Next {
            data = append(data, cur.Val)
        }
    
        for i, j := 0, len(data)-1; i <= j; {
            if data[i] != data[j] {
                return false
            }
            i++
            j--
        }
        return true
    }
    
    // 解法2
    // 找到链表中间节点,将前半部分转置,再从中间向左右遍历对比
    // 时间复杂度:O(N)
    // 空间复杂度:O(1)
    func isPalindrome2(head *ListNode) bool {
        if head == nil || head.Next == nil {
            return true
        }
        isPalindrome := true
    
        //链表长度
        length := 0
        for cur := head; cur != nil; cur = cur.Next {
            length++
        }
    
        //将前半部分反转
        step := length / 2
        var prev *ListNode
        cur := head
        for i := 1; i <= step; i++ {
            cur.Next, prev, cur = prev, cur, cur.Next
        }
        mid := cur
    
        var left, right *ListNode = prev, nil
        if length%2 == 0 {
            //长度为偶数
            right = mid
        } else {
            right = mid.Next
        }
    
        //从中间向左右两边遍历对比
        for left != nil && right != nil {
            if left.Val != right.Val {
                //值不相等,不是回文链表
                isPalindrome = false
                break
            }
            left = left.Next
            right = right.Next
        }
    
        //将前半部分反转的链表进行复原
        cur = prev
        prev = mid
        for cur != nil {
            cur.Next, prev, cur = prev, cur, cur.Next
        }
    
        return isPalindrome
    }
    

    GitHub

    • 源码传送门
    • 项目中会提供各种数据结构及算法的Golang实现, LeetCode解题思路及答案
    题目来源

    leetcode 234. 回文链表

    相关文章

      网友评论

          本文标题:拜托,面试别再问我回文链表了!!!

          本文链接:https://www.haomeiwen.com/subject/qwxzzftx.html