LeetCode每日一题 234.回文链表

这篇博客介绍了LeetCode每日一题234——回文链表的解题思路,包括数组+双指针、三步走法和使用栈的方法。重点讨论了各种方法的时间和空间复杂度,并提供了相应的代码实现。
摘要由CSDN通过智能技术生成

10.23 打卡

LeetCode每日一题 234.回文链表
image-20201023160032631

这道题目的做法,其实跟10.20打卡的重排链表很类似,如果你做过那道题目的话,我相信对于这道题目,AC简直手到擒来~

方法一 数组+双指针

**思路:**拿到题目,我一开始想到的就是双指针,直接一个指针从头,一个指针从后,依次遍历往中间靠,这样不是简简单单吗?但是有一个问题就是链表的话,想要让指针知道链表的最后一个元素,这需要从头开始遍历,每一次都需要重复这个步骤,这很明显时间浪费就非常多了!所以我们就又想到了数组,数组想访问任意一个元素都只需要知道下标而已,所以将链表中值复制到数组中,然后再来判断不就轻而易举吗?

下面直接给出代码

class Solution {
    public boolean isPalindrome(ListNode head) {
        if(head == null || head.next == null)
            return true;
        ArrayList<ListNode> list = new ArrayList();
        while(head != null){
            list.add(head);
            head = head.next;
        }
        int l = 0, r = list.size()-1;
        while(l < r){
            if(list.get(l).val != list.get(r).val)
                return false;
            l++;
            r--;
        }
        return true;
    }
}

复杂度分析:

时间复杂度: O(n),n为链表中元素的个数(复制到ArrayList中需要复制n次并且双指针判断时此时最差需要走O(n/2))

空间复杂度:O(n),n为链表中元素的个数,我们用到了一个ArrayList来储存链表中的元素

方法二:三步走(找中点,反转后部分链表,判断回文)

找中点反转链表,在之前的题目们我们就已经找过了,这里不再浪费时间

下面直接贴出代码:

class Solution {
    public boolean isPalindrome(ListNode head) {
        if(head == null || head.next == null)
            return true;
        ListNode minNode = findMid(head);
        ListNode head2 = reverseList(minNode.next);

        //判断是否回文
        ListNode p1 = head;
        ListNode p2 = head2;
       
        while( p2 != null){
            if(p1.val != p2.val)
                return false;
            p1 = p1.next;
            p2 = p2.next;
        }
        return true;
    }

    //翻转后部分的链表
    public ListNode reverseList(ListNode head){
        ListNode tail = null;
        ListNode cur = head;
        
        while(cur != null){
            ListNode temp = cur.next;
            cur.next = tail;
            tail = cur;
            cur = temp;
        }
        return tail;
    }
    
    //找中点
    public ListNode findMid(ListNode head){
        ListNode fast = head;
        ListNode slow = head;
        while(fast.next != null && fast.next.next != null){
            fast = fast.next.next;
            slow = slow.next;
        }
        return slow;
    }
}

复杂度分析:

时间复杂度:O(n),n 指的是链表的大小。

空间复杂度:O(1),只修改原本链表中节点的指向

方法三: 栈(该方法为逛LeetCode题解区觅得)

**思路:**巧妙了利用栈先进后出的性质,何谓回文?不就是正的看和反着看是一样的。所以将链表中的值先存进去栈中,然后再依次弹出和原来的链表进行比较,如果全部相等,则证明是回文链表,这种方法效率比较低,但是也不失为一种办法,简单粗暴(ps:所以我们还可以整个链表反转,然后再和原来的链表进行比较,哈哈哈好家伙=.=!)

下面直接贴出代码:

class Solution {
    
    public boolean isPalindrome(ListNode head) {
        if (head == null) {
            return true;
        }
        if (head.next == null) {
            return true;
        }
        //使用栈
        Stack<Integer> stack = new Stack<>();
        ListNode cur = head;
        while (cur != null) {
            stack.push(cur.val);
            cur = cur.next;
        }
        while (head != null) {
            if (head.val != stack.pop()) {
                return false;
            }
            head = head.next;
        }
        return stack.isEmpty();
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值