当前位置: 首页 > news >正文

力扣热题100刷题day61|234.回文链表(两种方法)

一、回文链表

234.回文链表

两种解法

解法1:时间复杂度O(n) 空间复杂度O(n)

遍历链表,计算链表长度,创建同样长度大小的数组,用数组存储链表中所有元素,之后双指针遍历链表,一个从头开始,一个从尾开始,比较元素是否相等;

class Solution {
    public boolean isPalindrome(ListNode head) {
        ListNode curr = head;
        int len = 0;
        if(head.next == null){
            return true;
        }
        while(curr != null){
            len++;
            curr = curr.next;
        }
        //重置curr
        curr = head;
        int[] nums = new int[len];
        for(int i = 0;i < nums.length;i++){
            if(curr != null){
                nums[i] = curr.val;
                curr = curr.next;
            }
            else{
                break;
            }
        }
        for(int i = 0,j = nums.length - 1;i < j;i++,j--){
            if(nums[i] != nums[j]) return false;
        }
        return true;
    }
}

注意⚠️:求完链表长度后,记得重置curr; 

解法2:时间复杂度O(n) 空间复杂度O(1)

快慢指针法(⭐️)

定义两个指针,快指针fast,慢指针slow,初始指向头结点,只要fast != null && fast.next != null,那么慢指针每次移动一个结点,快指针每次移动两个结点;直到fast不满足条件,此时,慢指针指向中点(链表个数为奇数),或者中点偏右的位置(链表个数为偶数);

之后,反转后半部分链表,然后比较前后两部分的数值,相等,则为回文链表,否则不是;

使用快慢指针法找到链表的中点的原理:

快指针的速度是慢指针的 2 倍所以当快指针走完全程时,慢指针刚好走了一半。

慢指针走过的路程为 x,那么快指针就是2x,2x = len,则x = 1/2 len;

class Solution {
    public boolean isPalindrome(ListNode head) {
        //快慢指针
        ListNode slow = new ListNode();
        ListNode fast = new ListNode();
        if(head == null || head.next == null){
            return true;
        }
        slow = head;
        fast = head;
        while(fast != null && fast.next != null){
            slow = slow.next;
            fast = fast.next.next;
        }
        //若链表为奇数个 此时slow指向中间点
        //若链表为偶数个 此时slow指向中间偏右的结点
        //反转后半部分链表
        ListNode pre = null;
        ListNode curr = slow;
        while(curr != null){
            ListNode temp = curr.next;
            curr.next = pre;
            pre = curr;
            curr = temp;
        }
        //此时pre指向反转后链表的头部
        //比较前后两部分链表
        ListNode pA = head;
        ListNode pB = pre;
        while(pB != null){
            if(pA.val != pB.val){
                return false;
            }
            pA = pA.next;
            pB = pB.next;
        }
        return true;
    }
}

注意⚠️:在比较前后两部分链表时,while中的判断条件只能是pB != null;

如果是pA != null,那么当链表个数为偶数时:1 2 3 4;

slow最后指向3,后半部分反转后,整体链表结构为:

前:1 --> 2 -->3 --> null       

后:4 ---> 3 --> null

pA遍历的是前半部分的链表,pB遍历后半部分,当pB指向null时,pA指向3,不为空,进入循环,pB.val就会报错:空指针异常; 

相关文章:

  • 用Grok 3分析案例并提供一些助理或助手的整理工作
  • 宏碁笔记本电脑擎7PRO搭载的 NVIDIA RTX 5080 显卡安装pytorch
  • Talib库安装教程
  • 通过AOP切面,切点,反射填充公共字段
  • 神经网络与深度学习:案例与实践——第三章(3)
  • GRBL运动控制算法(二)圆弧插补
  • Flinksql--订单宽表
  • 【LLM系列】1.大模型简介
  • [实战] linux驱动框架与驱动开发实战
  • 物理数据流图
  • 磁盘分析工具合集:告别C盘焦虑!
  • Mac 上使用 mysql -u root -p 命令,出现“zsh: command not found: mysql“?
  • 深度学习篇---模型训练(1)
  • 为什么卷积神经网络适用于图像和视频?
  • Spring面试题
  • Java 实现冒泡排序:[通俗易懂的排序算法系列之二]
  • 程序化广告行业(61/89):DSP系统活动设置深度剖析
  • 数仓开发团队日常1
  • 无锡无人机驾驶证培训费用
  • lua和C的交互