LeetCode234-判断回文链表 O(n)时间O(1)空间 几乎双百解法

题目详情

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

示例 1:

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

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

要求: O(n) 时间复杂度和 O(1) 空间复杂度解决此题

解题

结合回文序列的特点,进行如下想法
三步:

  1. 快慢指针寻中点(考虑奇偶分别进行处理)
  2. 前半段reverse
  3. 两段链表进行挨个比较

缺陷(对原数据进行了修改,最终没有改回去) 具体的思路我在代码中写的十分清楚了
此处就是将三步进行综合,这三步其实拆开都可以作为单独的一道简单题。其中难点在于链表的空指针异常。

此处除了综合三步之外,另外一难点在于,如何区分对待奇偶长度的链表,这点很重要。
对待奇数长度,我们应该将中间的点丢弃,而对待偶数长度,直接拆分。

我的代码优势在于思路十分清晰简洁,运行速度快,而缺点亦很明显,修改了数据,同时将奇数中间点删除了,jvm会直接gc它,这很好改,但是我懒得改了。

下面直接上代码,代码中有详细的注释

class Solution {
    
    
    //O(n)的时间,O(1)的空间
    //思路有了,分成3步
    //首先找到中点,前中点,用快慢指针来寻找O(n)
    //然后将中点所在的前半段链表进行翻转O(n)
    //之后进行从中点和中点的下一个进行挨个的比较O(n)
    //总体的时间复杂度是O(3n),空间复杂度是O(1)

    //当然也有另外一个想法,就是用字符串来记录结果
    //但是我不确定是否用字符串可以算作是一个常数空间,这个我搞不懂
    public boolean isPalindrome(ListNode head) {
    
    
        if(head==null || head.next==null)return true;
        //查询到第二段的开头
        ListNode head2 = findMid(head);
        //将前半截进行逆序
        ListNode head1 = reverseList(head);
        //进行对比,看是否相等
        while(head1!=null&&head2!=null){
    
    
            if(head1.val!=head2.val)return false;
            head1 = head1.next;
            head2 = head2.next;
        }
        return head1==head2;
    }

    /*
    *利用快慢指针寻找到第二段的开头
    */
    private ListNode findMid(ListNode head){
    
    
        ListNode fast = head.next, low = head, pre = null;
        //偶数时,fast.next==null,奇数时,fast==null
        //所以需要对这个进行不同的处理
        while(fast!=null && fast.next!=null){
    
    
            pre = low;
            fast = fast.next.next;
            low = low.next;
        }
        //针对奇数or偶数进行处理
        if(fast==null){
    
    
            pre.next = null;
            return low.next;
        }
        else{
    
    
            pre = low.next;
            low.next = null;
            return pre;
        }
    }

    /*
    *反转链表
    */
    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;

    }

猜你喜欢

转载自blog.csdn.net/qq_34687559/article/details/110750003
今日推荐