经典链表问题:解析链表中的关键挑战

news2024/12/18 14:53:30

这里写目录标题

  • 公共子节点
    • 采用集合或者哈希
    • 采用栈
    • 拼接两个字符串
    • 差和双指针
  • 旋转链表

公共子节点

例如这样一道题:给定两个链表,找出它们的第一个公共节点。
在这里插入图片描述
具体的题目描述我们来看看牛客的一道题:
在这里插入图片描述
这里我们有四种解决办法:

采用集合或者哈希

思路是这样的,我们先把其中一个链表遍历放入Map中,然后遍历第二个第二个链表与Map中的对比,第一个相同的即为公共节点。

public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
        Map<ListNode, Integer>  map = new HashMap<>();
        while (pHead1 != null) {
            map.put(pHead1, pHead1.val);
            pHead1 = pHead1.next;
        }
        while (pHead2 != null) {
            if (map.containsKey(pHead2)) {
                return pHead2;
            }
            pHead2 = pHead2.next;
        }
        return null;
    }

采用栈

这种方法,我们需要两个栈把两个链表分别遍历入栈,然后同时弹出,相同且最晚出栈的那一组即为公共节点。

public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
        Stack<ListNode>  stack1 = new Stack<>();
        Stack<ListNode>  stack2 = new Stack<>();
        while (pHead1 != null) {
            stack1.push(pHead1);
            pHead1 = pHead1.next;
        }
        while (pHead2 != null) {
            stack2.push(pHead2);
            pHead2 = pHead2.next;
        }
        ListNode ret = null;
        while (stack1.size() > 0 && stack2.size() > 0) {
            if (stack1.peek() == stack2.peek()) {
                ret = stack1.pop();
                stack2.pop();
            } else {
                break;
            }

        }
        return ret;
    }

拼接两个字符串

先看下面的两个链表:
A:1-4-6-2-3-5
B:2-3-5
我们试着拼接一个
AB:1-4-6-2-3-5-2-3-5
BA:2-3-5-1-4-6-2-3-5
我们会发现链表只要有公共的节点,那么我们遍历AB与BA就会找到公共节点。

 public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
        if (pHead1 == null || pHead2 == null) {
            return null;
        }
        ListNode p1 =  pHead1;
        ListNode p2 = pHead2;
        while (p1 != p2) {
            p1 = p1.next;
            p2 = p2.next;
            //防止陷入死循环
            if (p1 != p2) {
                if (p1 == null) {
                    p1 = pHead2;
                }
                if (p2 == null) {
                    p2 = pHead1;
                }
            }
        }
        return p1;
    }

差和双指针

遍历两个链表记录两个链表的长度,然后先遍历较长链表(len1-len2)绝对值个节点,然后两个链表同时向前走,节点一样的时候就是公共节点。

public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
        if (pHead1 == null || pHead2 == null) {
            return null;
        }
        ListNode p1 = pHead1;
        ListNode p2 = pHead2;
        int len1 = 0, len2 = 0;
        while (p1 != null) {
            p1 = p1.next;
            len1++;
        }
        while (p2 != null) {
            p2 = p2.next;
            len2++;
        }
        int sub = Math.abs(len1 - len2);
        ListNode current1 = pHead1;
        ListNode current2 = pHead2;
        if (len1 > len2) {
            int a = 0;
            while (a < sub) {
                current1 = current1.next;
                a++;
            }
        }
        if (len2 > len1) {
            int a = 0;
            while (a < sub) {
                current2 = current2.next;
                a++;
            }

        }
        while (current1 != current2) {
            current1 = current1.next;
            current2 = current2.next;
        }
        return current2;
    }

这段代码是一个Java方法,用于查找两个链表中的第一个公共节点。方法名为FindFirstCommonNode,接收两个参数pHead1和pHead2,分别表示两个链表的头节点。
首先,判断两个链表是否为空,如果有一个为空,则返回null。
然后,使用两个指针p1和p2分别遍历两个链表,计算它们的长度len1和len2。
接下来,计算两个链表长度之差的绝对值sub。
再接着,创建两个新的指针current1和current2,分别指向两个链表的头节点。如果链表1的长度大于链表2的长度,将current1向后移动sub个节点;如果链表2的长度大于链表1的长度,将current2向后移动sub个节点。
最后,同时遍历两个链表,直到找到第一个相同的节点,将其返回。

旋转链表

我们有两种思路:

  • 将前k部分与N-k部分分别反转,连接起来就解决了。
  • 用双指针找到倒数K的位置,具体实现如下:
  public ListNode rotateRight(ListNode head, int k) {
     if(head==null || k==0){
         return head;
     }
     ListNode fast = head;
     ListNode slow = head;
     ListNode temp = head;
     int len = 0;
     while (head!=null){
         head = head.next;
         len++;
     }
     if(k%len==0){
         return temp;
     }
     while (k%len>0){
         k--;
         fast = fast.next;
     }
     while (fast.next!=null){
         fast = fast.next;
         slow = slow.next;
     }
     ListNode res = slow.next;
     fast.next = temp;
     slow.next=null;
return res;
    }
  1. 首先,判断链表是否为空或旋转位置数是否为0,如果满足任一条件,则直接返回原链表头节点。
  2. 初始化三个指针:fast、slow和temp,都指向链表头节点。同时,定义一个变量len用于记录链表的长度。
  3. 遍历链表,计算链表的长度。
  4. 判断旋转位置数k是否能被链表长度整除,如果能整除,则不需要旋转,直接返回原链表头节点。
  5. 如果旋转位置数k不能被链表长度整除,需要找到k对链表长度取模后的余数对应的节点位置。通过fast指针先向前移动k%len个位置,然后fast和slow指针同时向前移动,直到fast指针到达链表尾部。此时,slow指针所在的位置就是需要旋转后的新头节点。
  6. 将新头节点的下一个节点作为新链表的尾节点,将原链表的尾节点接到新链表的头部,形成新的链表。
  7. 返回新的链表头节点。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1122002.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Tomcat启动控制台乱码问题

修改Tomcat/conf/logging.properties

[C++] C++入门

☃️个人主页&#xff1a;fighting小泽 &#x1f338;作者简介&#xff1a;目前正在学习C和Linux &#x1f33c;博客专栏&#xff1a;C入门 &#x1f3f5;️欢迎关注&#xff1a;评论&#x1f44a;&#x1f3fb;点赞&#x1f44d;&#x1f3fb;留言&#x1f4aa;&#x1f3fb; …

【Mysql】B+树索引的使用(七)

前言 每个索引都对应一棵 B 树&#xff0c; B 树分为多层&#xff0c;最下边一层是叶子节点&#xff0c;其余的是内节点&#xff08;非叶子节点&#xff09;。所有用户记录都存储在 B 树的叶子节点&#xff0c;所有目录项记录都存储在内节点。 InnoDB 存储引擎会自动为主键&am…

Spring Cloud Alibaba Seata 实现分布式事物

Seata 是一款开源的分布式事务解决方案&#xff0c;致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式&#xff0c;为用户打造一站式的分布式解决方案 Seata 官网&#xff1a;https://seata.io/zh-cn/ Spring Cloud Alibaba 官…

信息检索与数据挖掘 | (五)文档评分、词项权重计算及向量空间模型

目录 &#x1f4da;词项频率及权重计算 &#x1f407;词项频率 &#x1f407;逆文档频率 &#x1f407;tf-idf权重计算 &#x1f4da;向量空间模型 &#x1f407;余弦相似度 &#x1f407;查询向量 &#x1f407;向量相似度计算 &#x1f4da;其他tf-idf权值计算方法 …

【OpenGL】五、光照

OpenGL Lighting 文章目录 OpenGL Lighting一、 冯氏光照模型(Phong Lighting Model)环境光&#xff08;Ambient lighting&#xff09;漫反射光照&#xff08;Diffuse lighting&#xff09;漫反射光照&#xff08;Specular Lighting&#xff09; 二、 材质(Materials)光照贴图(…

JUC并发编程笔记2

省流&#xff1a; 自己笔记&#xff0c;划走~~~~ 缓存更新策略

vue3里面vant组件的标签页使用?

一、绑一个v-model事件 二、让activeName的初始为0也就是默认是显示第一个标签页的下标 三、给标签页下面的东西进行一个判断 想让哪个优先显示就把哪个判断作为初始值存入

【试题040】多个逻辑或例题2

1.题目&#xff1a;设int n0;&#xff0c;执行表达式n ||(n-1) ||(n0)||(n1)||(n2)后n的值是 &#xff1f; 2.代码解析&#xff1a; 逻辑或 || 运算符是一个短路运算符&#xff0c;它从左到右依次计算表达式&#xff0c;如果遇到一个为真&#xff08;非零&#xff09;的值&am…

No171.精选前端面试题,享受每天的挑战和学习

🤍 前端开发工程师(主业)、技术博主(副业)、已过CET6 🍨 阿珊和她的猫_CSDN个人主页 🕠 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 🍚 蓝桥云课签约作者、已在蓝桥云课上架的前后端实战课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入…

第一章概述

一、学习目的与要求 本章对软件测试作了概括性的介绍&#xff0c;目的是使学生对软件测试有个初步的认识。通过本章的学习&#xff0c;应使学生掌握软件测试的基本概念&#xff0c;了解软件测试的发展历程和行业现状&#xff0c;掌握软件测试技术的分类&#xff0c;理解软件测试…

【JAVA-Day49】Java LinkedList集合详解

Java LinkedList集合详解 摘要引言Java LinkedList集合详解一、什么是LinkedList集合1.1 链表数据结构1.2 双向链表1.3 动态大小1.4 插入和删除元素1.5 适用场景 二、LinkedList集合的使用2.1 创建 LinkedList 集合、添加元素、遍历元素2.2 在指定位置插入元素2.3 获取指定位置…

模拟 Junit 框架

需求 定义若干个方法&#xff0c;只要加了MyTest注解&#xff0c;就可以在启动时被触发执行 分析 定义一个自定义注解MyTest&#xff0c;只能注解方法&#xff0c;存活范围是一直都在定义若干个方法&#xff0c;只要有MyTest注解的方法就能在启动时被触发执行&#xff0c;没有这…

开源博客项目Blog .NET Core源码学习(5:mapster使用浅析)

开源博客项目Blog使用mapster框架映射对象&#xff0c;主要是在数据库表对象及前端数据对象之间进行映射&#xff0c;本文学习并记录项目中mapster的使用方式。   App.Hosting项目的program文件中调用builder.Services.AddMapper函数进行对象模型自动映射&#xff0c;而该函数…

numpy矩阵画框框

在n>5(n是奇数)的nn数组中&#xff0c;用*画外方框和内接菱形。 (本笔记适合熟悉numpy的coder翻阅) 【学习的细节是欢悦的历程】 Python 官网&#xff1a;https://www.python.org/ Free&#xff1a;大咖免费“圣经”教程《 python 完全自学教程》&#xff0c;不仅仅是基础那…

二维码智慧门牌管理系统升级解决方案:突破传统,实现质检与抽检的个性化配置

文章目录 前言一、引入“独立质检”二、个性化抽检类别设定三、触发重采要素的功能升级四、升级优势与展望 前言 在数字化时代&#xff0c;智慧门牌管理系统已经成为社会管理的重要工具。为了满足各种复杂需求&#xff0c;系统升级是必然趋势。本次升级主要针对质检和抽检两大…

Python+requests+exce接口自动化测试框架

一、接口自动化测试框架 二、工程目录 三、Excel测试用例设计 四、基础数据base 封装post/get&#xff1a;runmethod.py #!/usr/bin/env python3 # -*-coding:utf-8-*- # __author__: hunterimport requests import jsonclass RunMain:def send_get(self, url, data):res req…

Ragnar Locker勒索软件开发者在法国被逮捕

导语&#xff1a;在一次跨国行动中&#xff0c;执法机构逮捕了与Ragnar Locker勒索软件团伙有关的一名恶意软件开发者&#xff0c;并查封了该团伙的暗网网站。Ragnar Locker勒索软件团伙自2020年以来在全球范围内对168家国际公司进行了攻击。此次行动是法国、捷克、德国、意大利…

搭建网站七牛云CDN加速配置

打开七牛云后台&#xff1b;添加域名&#xff1b; 添加需要加速的域名&#xff0c;比如我添加的是motoshare.cn 源站配置&#xff0c;这里要用IP地址&#xff0c;访问的目录下面要有能访问测试的文件&#xff0c;尽量不要用源站域名&#xff0c;这个只能用加速二级域名&#x…