判断一个链表是否为回文结构

题目

给定一个单链表,判断该链表是不是回文,如
1->2->1 True
1->2->2->1 True
1->2->3 False

思路1: 使用栈

链表结构

class Node():
    def __init__(self, val):
        self.val = val
        self.next = None


class LinkList():
    def __init__(self):
        self.head = None


    def init(self, datas):
        tail = None
        for v in datas:
            node = Node(v)
            if tail is None:
                self.head = node
            else:
                tail.next = node
            tail = node


    def to_list(self):
        l = []
        p = self.head
        while p:
            l.append(p.val)
            p = p.next

        return l

实现

    def is_palindrome_stack(self):
        s = []
        cur = self.head
        while cur:
            s.append(cur.val)
            cur = cur.next

        cur = self.head
        while cur:
            if cur.val != s.pop():
                return False
            cur = cur.next

        return True

思路2: 只需要一半数据压栈

    def is_palindrome_stack_half(self):
        if self.head is None or self.head.next is None:
            return True

        fast = self.head
        slow = self.head
        while fast and fast.next:
            fast = fast.next.next
            slow = slow.next

        s = []
        cur = slow.next
        while cur:
            s.append(cur.val)
            cur = cur.next

        cur = self.head
        while len(s) > 0:
            if cur.val != s.pop():
                return False
            cur = cur.next

        return True

思路3: 反转后半部分链表

    def is_palindrome_reverse(self):
        if self.head is None or self.head.next is None:
            return True

        fast = self.head
        slow = self.head
        while fast and fast.next:
            fast = fast.next.next
            slow = slow.next

        half = slow.next
        slow.next = None

        prev = None
        cur = half
        while cur:
            next = cur.next
            cur.next = prev
            prev = cur
            cur = next

        p1 = self.head
        p2 = prev

        while p1 and p2:
            if p1.val != p2.val:
                return False

            p1 = p1.next
            p2 = p2.next

        return True

测试

def test_palindrome(l):
    ll = LinkList()
    ll.init(l)

    l1 = ll.to_list()
    print(l1)

    print('is_palindrome_stack:     ', ll.is_palindrome_stack())
    print('is_palindrome_stack_half:', ll.is_palindrome_stack_half())
    print('is_palindrome_reverse   :', ll.is_palindrome_reverse())
    print('--------------------')


if __name__ == '__main__':
    test_palindrome([])
    test_palindrome([1])
    test_palindrome([1, 1])
    test_palindrome([1, 2, 1])
    test_palindrome([1, 2, 1, 2])
    test_palindrome([1, 2, 3, 4])
    test_palindrome([1, 2, 3, 4, 3, 2, 1])
    test_palindrome([1, 2, 3, 4, 4, 3, 2, 1])

结果

➜  7_is_palindrome python is_palindrome.py
[]
is_palindrome_stack:      True
is_palindrome_stack_half: True
is_palindrome_reverse   : True
--------------------
[1]
is_palindrome_stack:      True
is_palindrome_stack_half: True
is_palindrome_reverse   : True
--------------------
[1, 1]
is_palindrome_stack:      True
is_palindrome_stack_half: True
is_palindrome_reverse   : True
--------------------
[1, 2, 1]
is_palindrome_stack:      True
is_palindrome_stack_half: True
is_palindrome_reverse   : True
--------------------
[1, 2, 1, 2]
is_palindrome_stack:      False
is_palindrome_stack_half: False
is_palindrome_reverse   : False
--------------------
[1, 2, 3, 4]
is_palindrome_stack:      False
is_palindrome_stack_half: False
is_palindrome_reverse   : False
--------------------
[1, 2, 3, 4, 3, 2, 1]
is_palindrome_stack:      True
is_palindrome_stack_half: True
is_palindrome_reverse   : True
--------------------
[1, 2, 3, 4, 4, 3, 2, 1]
is_palindrome_stack:      True
is_palindrome_stack_half: True
is_palindrome_reverse   : True
--------------------
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值