• 首页

  • 归档

  • 标签

  • 分类

  • 友链
M S B l o g
M S B l o g

ms

获取中...

04
24
java
总结

【力扣】回文链表

发表于 2021-04-24 • java 问题 数据结构 力扣 • 被 815 人看爆

题目:

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

示例 1:

输入: 1->2
输出: false
示例 2:

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

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/palindrome-linked-list-lcci
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

题解:

  1. 将链表的数据复制到数组集合中,再用双指针判断是否为回文

  • 时间复杂度:O(n),其中 n 指的是链表的元素个数。
    第一步: 遍历链表并将值复制到数组中,O(n)。
    第二步:双指针判断是否为回文,执行了 O(n/2) 次的判断,即 O(n)。
    总的时间复杂度:O(2n) = O(n)。
  • 空间复杂度:O(n),其中 n 指的是链表的元素个数,我们使用了一个数组列表存放链表的元素值

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public boolean isPalindrome(ListNode head) {
        List<Integer> vals = new ArrayList<Integer>();

        //将链表中的数据复制到数组集合中
        ListNode temp = head;
        while(temp != null){
            vals.add(temp.val);
            temp = temp.next;
        }

        //使用双指针判断回文
        int front = 0;
        int back = vals.size() - 1;
        while(front < back){
            if(!vals.get(front).equals(vals.get(back))){
                return false;
            }
            front ++;
            back --;
        }
        return true;
    }
}

  1. 找到前半部分链表的尾节点,反转后半部分链表,判断是否回文,恢复链表.

  • 时间复杂度O(n)
  • 空间复杂度O(1)

class Solution {
    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;
    }
}

分享到:
【力扣】链表相交
【力扣】链表求和
  • 文章目录
  • 站点概览
ms

MSms

⚓️HelloWorld⚓️

QQ Email RSS
看爆 Top5
  • MyBatis-Plus分页查询 5,937次看爆
  • @Autowired与@Resource的区别 4,755次看爆
  • feign远程调用及异步调用丢失请求头问题 4,527次看爆
  • spring cloud中OpenFeign整合Sentinel启动报错 4,425次看爆
  • Certbot查看证书过期时间,手动续期以及自动续期 3,303次看爆

Copyright © 2025 ms · 湘ICP备20015239号

Proudly published with Halo · Theme by fyang · 站点地图