前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >脚撕LeetCode(面试02.06)Easy

脚撕LeetCode(面试02.06)Easy

作者头像
JathonKatu
发布2022-01-18 08:19:10
1860
发布2022-01-18 08:19:10
举报
文章被收录于专栏:JathonKatu

题目地址:https://leetcode-cn.com/problems/palindrome-linked-list-lcci/

编写一个函数,检查输入的链表是否是回文的。

代码语言:javascript
复制
示例 1: 
输入:1->2
输出:false
示例 2: 
输入:1->2->2->1
输出:true

进阶:

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

这道题的题意和9题类似,就是判断输入的链表是不是回文,既数组从中间切开两边是对称的。

一、爆破法

首先想到的就是最蠢的办法,先把链表挪动到数组里面,然后头尾遍历数组,出现异常马上返回false,执行完了就返回true。

这里犯了个小错误,忘了list里面放的是Integer,直接if的时候用了== ,导致[-129,-129]这个用例报错了

执行结果如下:

26 / 26 个通过测试用例

状态:通过

执行用时: 4 ms

内存消耗: 42.2 MB

代码语言:javascript
复制
public static boolean isPalindromeMe(ListNode head) {
    if (null == head) return true;
    List<Integer> list = new ArrayList<>();
    ListNode item = head;
    while (null != item) {
        list.add(item.val);
        item = item.next;
    }
    int headIndex = 0, endIndex = list.size() - 1;
    while (headIndex < endIndex) {
        if (!list.get(headIndex).equals(list.get(endIndex))) return false;
        headIndex++;
        endIndex--;
    }
    return true;
}

当然结果是很不理想的,毕竟有进阶做法,我们看看大佬们的做法

在看官方方法之前要学习一下什么叫快慢指针

快慢指针就是定义两根指针,移动的速度一快一慢,以此来制造出自己想要的差值。这个差值可以让我们找到链表上相应的节点。

概念的意思就是,只需要根据我们的需求,去创造一快一慢的两个指针,这就是快慢指针

那么快慢指针快慢的进度没有什么特殊要求,如果你要的是链表的一半那么快针的步长就是慢针的2倍;如果你要链表的倒数第二个,那么快慢针的步长差距就是1;判断链表中有没有环只需要用快针是慢针的2倍看看会不会相遇即可。

二、官方快慢指针法

这道题的快慢针很明显就是快针是慢针的双倍。

他先用快慢针找到中间位置,然后再反转后半个链表,对比完了之后再还原链表。

这里的时间是2ms

而删除掉对比后再反转回来的步骤,时间直接变成1ms,超越了100%

执行结果如下:

26 / 26 个通过测试用例

状态:通过

执行用时: 2 ms

内存消耗: 41 MB

代码语言:javascript
复制
public boolean isPalindrome(ListNode head) {
    if (head == null) {
        return true;
    }

    // 找到前半部分链表的尾节点并反转后半部分链表
    ListNode firstHalfEnd = endOfFirstHalf(head);
    ListNode secondHalfStart = reverseList(firstHalfEnd.next);

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

    // 还原链表并返回结果
    firstHalfEnd.next = reverseList(secondHalfStart);
    return result;
}

private ListNode reverseList(ListNode head) {
    ListNode prev = null;
    ListNode curr = head;
    while (curr != null) {
        ListNode nextTemp = curr.next;
        curr.next = prev;
        prev = curr;
        curr = nextTemp;
    }
    return prev;
}

private ListNode endOfFirstHalf(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;
}

官方答案的思想是好的,用完给人家复原,避免后续使用出现的问题,但是刷leetcode大部分人是不讲武德的,解决完自己的事情就可以了,毕竟这是算法,不是工作。

今天学到了快慢针的用法,不算亏,毕竟以前天天听说快慢针,今天算是见识到了。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-06-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 JathonKatu 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档