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

算法系列-力扣876-求链表的中间节点

# 求链表中间节点,如果有两个中间节点取后面那个

链表定义

```

// @lc code=start

/**

 * Definition for singly-linked list.

 * public class ListNode {

 *     int val;

 *     ListNode next;

 *     ListNode() {}

 *     ListNode(int val) { this.val = val; }

 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }

 * }

 */

```

方法一:计数取一半

解题方法:

先计算链表一共有多少个节点n

n/2,得到中间节点的下标(从0开始)

1 -> 2 -> 3 -> 4 -> 5

坐标节点就是链表的中间节点

时间复杂度:O(n)

空间复杂度:O(1)

```

    public ListNode middleNode(ListNode head) {

        /**

         * 先计算链表一共有多少个节点n

         * n/2,得到中间节点的下标(从0开始)

         *  1 -> 2 -> 3 -> 4 -> 5

         *  坐标节点就是链表的中间节点

         * */

        int n=0;

        ListNode p=head;

        while (p!=null){

            n++;

            p=p.next;

        }

        int mid=n/2;

        ListNode midNode=head;

        for (int i = 0; i < mid; i++) {

            midNode=midNode.next;

        }

        return midNode;

    }

```

方法二:双指针

解题方法:

定义快慢两个指针,快指针每次移动2步,慢指针每次移动1步

注意:指针需要从头节点前开始移动,因此需要定义一个哑结点,快指针和慢指针都从哑节点开始

当快指针移动了2k步后,慢指针移动了k步

假设2k=n,k=n/2

当n为偶数时,慢指针的后续节点就是中间节点

当n为奇数时,慢指针就是中间节点

是否是偶数节点看快指针每次是否都能移动两步

时间复杂度:O(n)

空间复杂度:O(1)

```

    public ListNode middleNode(ListNode head) {

        /**

         * 定义快慢两个指针,快指针每次移动2步,慢指针每次移动1步

         * 注意:指针需要从头节点前开始移动,因此需要定义一个哑结点,快指针和慢指针都从哑节点开始

         * 当快指针移动了2k步后,慢指针移动了k步

         * 假设2k=n,k=n/2

         * 当n为偶数时,慢指针的后续节点就是中间节点

         * 当n为奇数时,慢指针就是中间节点

         * 是否是偶数节点看快指针每次是否都能移动两步

         * -1 -> 1 -> 2 -> 3 -> 4 -> 5 -> null

         * -1 -> 1 -> 2 -> 3 -> 4 -> null

         * */

        if(head == null){

            return null;

        }

        ListNode dummy = new ListNode(-1);

        dummy.next=head;

        ListNode slow=dummy;

        ListNode fast=dummy;

        ListNode midNode=null;

        Boolean isEvent=true;

        while (fast.next!=null){

            slow=slow.next;

            if(fast.next.next!=null) {

                fast = fast.next.next;

            } else{

                fast=fast.next;

                isEvent=false;

            }

        }

        midNode = isEvent ? slow.next : slow;

        return  midNode;

    }

```

方法三:双指针优化

解题方法:

定义快慢两个指针,快指针每次移动2步,慢指针每次移动1步

快指针和慢指针都从头节点开始移动

当快指针移动到链尾时,慢指针移动了k步,n>1

当n为偶数时,n-1必然是奇数

即快指针移动了2(k-1)+1步

此时快慢指针距离原点距离

快2(k-1)+1+1  简化  2k

慢k+1

即慢指针正好处于链表中间位置。

当n为奇数时,n-1必然是偶数

,快指针移动了2k步

此时快慢指针距离原点距离

2k+1

k+1

即慢指针正好处于链表中间位置

时间复杂度:O(n)

空间复杂度:O(1)

方法二的本质是下面的公式:

偶数

快2k

慢k

中间k+1

奇数

快2k-1

慢k

中间k

即快慢指针的初始位置+1就把公式统一了。

```

    public ListNode middleNode(ListNode head) {

        if(head == null){

            return null;

        }

        ListNode slow=head;

        ListNode fast=head;

        

        while (fast!=null && fast.next!=null){

            slow=slow.next;

            fast = fast.next.next;

        }

      

        return slow;

    }

```

http://www.lryc.cn/news/148523.html

相关文章:

  • SpringBoot集成Redis、Redisson保姆教程【附源码】
  • c++多线程中常用的使用方法
  • 【dart】dart基础学习使用(一):变量、操作符、注释和库操作
  • element-plus 设置 el-date-picker 弹出框位置
  • C++day7(auto关键字、lambda表达式、C++中的数据类型转换、C++标准模板库(STL)、list、文件操作)
  • 纽扣电池/锂电池UN38.3安全检测报告
  • K8S:K8S自动化运维容器Docker集群
  • Java的guava 限流写法
  • [uniapp] scroll-view 简单实现 u-tabbar效果
  • vue常见问题汇总
  • GPT-3在化学中进行低数据发现是否足够?
  • gitlab升级
  • Matlab图像处理-灰度插值法
  • axios 或 fetch 如何实现对发出的请求的终止?
  • ChatGPT Prompting开发实战(四)
  • Windows和Linux环境中安装Zookeeper具体操作
  • 41、Flink之Hive 方言介绍及详细示例
  • docker环境安装软件、更换镜像源以及E: Unable to locate package xxx解决
  • 夸克扫描王App用上了AI大模型 让扫描更清楚、提取文字更方便
  • 代价高昂的 IT 错误:识别并避免供应商锁定
  • HBase集群环境搭建与测试
  • 【iOS】Masonry的基本使用
  • 浅析SAS协议:链路层
  • ES6之浅尝辄止1:class的用法
  • django-发送邮件
  • IP私域系统搭建课,视频号打通你的个人ip私域
  • 咸虾米之一些快捷方式的操作,一行方块的左右滑动,方块在一区域内的任意移动
  • Linux 高级指令
  • 江苏移动基于OceanBase稳步创新推进核心数据库分布式升级
  • 6. 删除顺序表中的重复元素