数据结构-链表练习(面试题)

news2024/10/6 11:23:16

1,翻转一个单链表

建立变量cur指向第二个节点,curN指向cur.next,将第二个节点的next改为head,head=cur这样实现,前两个节点顺序的翻转,第二个节点指向了第一个节点,之后cur向后移(cur=curN),curN也向后移,进行循环,直到所以节点的顺序都翻转

问:curN的作用是什么,为什么要这样定义?

答:因为进行反转时,这个节点的next要改为前一个节点的地址,所以这个节点和后一个节点就没有关系了,但是我们还需要找到后一个节点,依次进行翻转,所以设置变量,将后一个节点的地址提前记录下来

public void reverseList(){
    if (head==null){
        return;
    }
    ListNode cur=head.next;
    ListNode curNext=head.next.next;
    head.next=null;
    while (cur!=null){
        cur.next=head;
        head=cur;
        cur=curNext;
        if (curNext!=null){
        curNext=curNext.next;
        }
    }

}

2.给定一个带有头结点 head 的非空单链表,返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点

用快慢指针法:快指针一次走两步,慢指针一次走一步,所以快指针走的是慢指针的两倍路程,所以慢指针指向的是链表的中间值

链表的节点分两种情况,一种为单数,另一种为双数,第一种,fast指向最后一个节点,slow指向中间节点,第二种,fast指向空,slow指向中间的靠右的节点

public ListNode returnMid(){
    if (head==null){
        return null;
    }
    ListNode slow=head;
    ListNode fast=head;
    while (fast!=null&&fast.next!=null){
        fast=fast.next.next;
        slow=slow.next;
    }
    return slow;
}

3, 输入一个链表,输出该链表中倒数第k个结点

用快慢指针法:快指针先走k-1个节点,然后快指针和慢指针一起向后走,直到快指针的下一个为null,则慢指针指向倒数第k个结点

首先要判断输入坐标的合法性,和链表为空的情况

private void KLegal(int k){
    if (k<=0||k>size()){
        throw new IndexException("输入的第k个节点,k输入异常");
    }
}
private void heedIsNull(){
    if (head==null){
        throw new IndexException("head为空,该链表没有节点");
    }
}
public  int kthToLast(int k){
    try {
        KLegal(k);
    }catch (IndexException e){
        e.printStackTrace();
    }
    try {
        heedIsNull();
    }catch (IndexException e){
        e.printStackTrace();
    }
    ListNode slow=head;
    ListNode fast=head;
    while ((k-1)!=0){
        fast=fast.next;
        k--;
    }
    while (fast.next!=null){
        fast=fast.next;
        slow=slow.next;
    }
    return slow.val;
}

4,将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。

建立一个空节点,比较链表1,和链表2,的值将比较大的值的节点放到空节点的后面

然后再将p1与p2的val进行比较重复上述操作,知道一个链表的节点为0,直接将另一个链表剩余的节点直接放到新建的链表后面,最后将建立的空节点删除

public ListNode mergeTowLists(ListNode head1,ListNode head2){
    ListNode node=new ListNode(0);
    ListNode cur=node;
    ListNode b1=head1;
    ListNode p1=head2;
    while (b1!=null&&p1!=null){
        if (b1.val<p1.val){
            cur.next=b1;
            cur=cur.next;
            b1=b1.next;
        }else {
            cur.next=p1;
            cur=cur.next;
            p1=p1.next;
        }
    }
    if (b1==null){
        cur.next=p1;
    }else {
        cur.next=b1;
    }
    return node.next;

}

5,编写代码,以给定值x为基准将链表分割成两部分,所有小于x的结点排在大于或等于x的结点之前

以x为界限,创立两个分区,遍历链表,将小于x的放到第一个分区,大于x的放到第二个分区,采用尾插法放置

public ListNode partition(int k) {
    ListNode b1 = null;
    ListNode b2 = null;
    ListNode p1 = null;
    ListNode p2 = null;
    ListNode cur = head;
    while (cur != null) {
        if (cur.val < k) {
            if (b1 == null) {
                b1 = b2 = cur;
            } else {
                b2.next=cur;
                b2 = cur;
            }
        } else {
            if (p1 == null) {
                p1 = p2 = cur;
            } else {
                p2.next = cur;
                p2 = cur;
            }
        }
        cur = cur.next;
    }
    if (b1==null){
        return p1;
    }
    b2.next = p1;
    if (p1!=null){
        p2.next=null;
    }
    return b1;
}

6,判断回文

1,先用快慢指针,找到中间值,然后将中间值后面的节点翻转,然后,中间值以前的节点从前往后遍历,中间值以后的节点从后往前遍历,并对比节点的val是否相同,如果完全相同,则为回文,如果不相同,则不是

public boolean chkPalindrome(){
    if (head==null){
        return true;
    }
    ListNode slow=head;
    ListNode fast=head;
    while (fast!=null&&fast.next!=null){
        fast=fast.next.next;
        slow=slow.next;
    }
    ListNode cur=slow.next;
    ListNode curNext=cur.next;
    while (cur!=null){
        cur.next=slow;
        slow=cur;
        cur=curNext;
        if (curNext!=null){
            curNext=curNext.next;
        }
    }
    ListNode head1=head;
    while (slow!=head1&&head1.next!=slow){
        if (slow.val!=head1.val){
            return false;
        }
        slow=slow.next;
        head1=head1.next;
    }
    return true;
}

7, 输入两个链表,找出它们的第一个公共结点

先判断两个链表的长度,算出差值k,将长的链表向后走k步,然后,两个链表同时遍历,直到两个链表节点的next相等是,这next指向的节点就是公共节点

public  ListNode getIntersectionNode(ListNode head1,ListNode head2){
    ListNode p1=head1;//long
    ListNode p2=head2;
    int len1=0;
    int len2=0;
    while (p1!=null){
        p1=p1.next;
        len1++;
    }
    while (p2!=null){
        p2=p2.next;
        len2++;
    }
    int len=len1-len2;
     p1=head1;
     p2=head2;
    if (len1<len2){
        p1=head2;
        p2=head1;
        len=len2-len1;
    }
    while (len!=0){
        p1=p1.next;
        len--;
    }
    while (p1!=p2){
        p1=p1.next;
        p2=p2.next;
    }
    return p1;

}

8,成环的判断和成环的节点

成环的判断:快慢指针,快指针一次走两步,慢指针一次走一步,如果成环,快指针与慢指针总会相遇,所以当快指针等于慢指针时,则有环,如果遍历之后没有相遇,则没有环

public boolean isDetectCycle(){
    ListNode slow=head;
    ListNode fast=head;
    while (fast!=null&&fast.next!=null){
        fast=fast.next.next;
        slow=slow.next;
        if (fast==slow){
            return true;
        }
    }
    return false;
}

成环的节点:

有公式可推从头节点到成环节点的路程等于快指针与慢指针相遇的节点到成环节点的距离,所以将slow=head,快指针和慢指针同时走相遇的节点就是成环节点

public ListNode detectCycle(){
    ListNode slow=head;
    ListNode fast=head;
    while (fast!=null&&fast.next!=null){
        fast=fast.next.next;
        slow=slow.next;
        if (fast==slow){
           break;
        }
    }
    if (fast==null||fast.next==null){
        return null;
    }//排除没有环的情况
    slow=head;
    while (slow!=fast){
        slow=slow.next;
        fast=fast.next;
    }
    return slow;

}

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

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

相关文章

linux中 虚拟机 修改时间 centos7

方法1 &#xff1a;虚拟机内 设置 方法2 代码实现 timedatectl set-timezone "Asia/Shanghai"

Detla lake with Java--在spark集群上运行程序

昨天写了第一篇入门&#xff0c;今天看见有人收藏&#xff0c;继续努力学习下去。今天要实现的内容是如何将昨天的HelloDetlaLake 在spark集群上运行&#xff0c;。具体步骤如下 1、安装spark,我使用的是 spark-3.5.1-bin-hadoop3-scala2.13&#xff0c;去官网下载&#xff0c…

Secure CRT 文件传输

Secure CRT 文件传输 Secure CRT支持多种文件传输协议&#xff0c;其中最常用的是Xmodem、Ymodem、Zmodem和Kermit。这些协议允许在本地计算机和远程主机之间安全地传输文件。 Xmodem&#xff1a; Xmodem是一种简单的协议&#xff0c;通常用于在串行连接上进行文件传输。它通过…

【程序错误-显存不足】RuntimeError: CUDA out of memory. Tried to allocate 4.00 GiB

目录 1. 问题2. 解决方法2.1 租服务器(试过有用)2.2 减小batchsize2.3 减少模型大小2.3 检查模型本身没有发现错误&#xff0c;最终确认是验证集评估阶段的张量计算非常占用空间。2.3.1 可以对利用torch.tensor().detach().cpu().numpy()转为numpy&#xff0c;在cpu上进行loss和…

学习Rust的第22天:mini_grep第2部分

书接上文&#xff0c;在本文中&#xff0c;我们学习了如何通过将 Rust 程序的逻辑移至单独的库箱中并采用测试驱动开发 (TDD) 实践来重构 Rust 程序。通过在实现功能之前编写测试&#xff0c;我们确保了代码的可靠性。我们涵盖了基本的 Rust 概念&#xff0c;例如错误处理、环境…

【ARM Cache 系列文章 11.2 -- ARM Cache 组相联映射】

请阅读【ARM Cache 系列文章专栏导读】 文章目录 Cache 组相联映射组相联映射原理多路组相连缓存的优势多路组相连缓存的代价关联度&#xff08;Associativity&#xff09; 上篇文章&#xff1a;【ARM Cache 系列文章 11.1 – ARM Cache 全相连 详细介绍】 Cache 组相联映射 A…

文章解读与仿真程序复现思路——电力自动化设备EI\CSCD\北大核心《计及多重不确定性的虚拟电厂响应区间评估方法》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

mysql-sql-练习题-4-标记

标记 连续登录2-7天用户建表排名找规律 最大连胜次数建表只输出连胜结果输出所有连续结果 连续登录2-7天用户 建表 create table continuous_login(user_id1 integer comment 用户id,date_login date comment 登陆日期 ) comment 用户登录表;insert into continuous_login val…

【Java基础】Spring核心之控制反转(IOC)

1. 如何理解IOC 1.1 什么是IOC 在Spring框架中&#xff0c;IOC&#xff08;Inversion of Control&#xff0c;控制反转&#xff09;是一种设计原则&#xff0c;它是Spring框架的核心概念之一。IOC的基本思想是将程序的控制权从应用程序代码中转移到框架或容器中&#xff0c;从…

c#数据库: 4.修改学生成绩

将4年级的学生成绩全部修改为100分,。修改前的学生信息表如图所示: using System; using System.Collections.Generic; using System.Data.SqlClient; using System.Linq; using System.Text; using System.Threading.Tasks;namespace StudentUpdate {internal class Program{s…

C++:运算符重载-加号(+)

在C中&#xff0c;运算符重载允许重新定义已有运算符的行为&#xff0c;以便让它们适用于自定义类型。这样&#xff0c;你可以通过自定义类型使用内置运算符&#xff0c;使得代码更加直观和易读。 此时我在代码中定义一个新类MyString&#xff1a; class MyString { public:i…

MySQL常见问题解决和自动化安装脚本

常见问题 MySQL密码正确但无法登录的情况 这种情况一般都是因为缓存&#xff0c;使用mysql -u root -p123456直到成功登陆为止&#xff0c;并且进入之后重新修改密码&#xff0c;多次重复修改密码的命令并且再一次清除缓存后退出。 ALTER USER rootlocalhost IDENTIFIED WIT…

Microsoft Threat Modeling Tool 使用(二)

主界面 翻译 详细描述 选择了 “SDL TM Knowledge Base (Core)” 模板并打开了一个新的威胁模型。这个界面主要用于绘制数据流图&#xff08;Data Flow Diagram, DFD&#xff09;&#xff0c;它帮助您可视化系统的组成部分和它们之间的交互。以下是界面中各个部分的功能介绍&a…

CogAgent:开创性的VLM在GUI理解和自动化任务中的突破

尽管LLMs如ChatGPT在撰写电子邮件等任务上能够提供帮助&#xff0c;它们在理解和与GUIs交互方面存在挑战&#xff0c;这限制了它们在提高自动化水平方面的潜力。数字世界中的自主代理是许多现代人梦寐以求的理想助手。这些代理能够根据用户输入的任务描述自动完成如在线预订票务…

Bert基础(二十)--Bert实战:机器阅读理解任务

一、机器阅读理解任务 1.1 概念理解 机器阅读理解&#xff08;Machine Reading Comprehension, MRC&#xff09;就是给定一篇文章&#xff0c;以及基于文章的一个问题&#xff0c;让机器在阅读文章后对问题进行作答。 在机器阅读理解领域&#xff0c;模型的核心能力体现在对…

STM32使用PWM驱动直流电机

系列文章目录 STM32单片机系列专栏 C语言术语和结构总结专栏 文章目录 1. 直流电机和驱动简介 2. 驱动电路原理 3. 代码实现 3.1 PWM.c 3.2 PWM.h 3.3 MOTOR.c 3.4 MOTOR.h 3.5 main.c 3.6 完整工程文件 PWM和OC输出比较详解&#xff1a; STM32定时器的OC比较和PW…

LT6911GX HDMI2.1 至四端口 MIPI/LVDS,带音频 龙迅方案

1. 描述LT6911GX 是一款面向 VR / 显示应用的高性能 HDMI2.1 至 MIPI 或 LVDS 芯片。HDCP RX作为HDCP中继器的上游&#xff0c;可以与其他芯片的HDCP TX配合使用&#xff0c;实现中继器功能。对于 HDMI2.1 输入&#xff0c;LT6911GX 可配置为 3/4 通道。自适应均衡功能使其适合…

使用Github+Picgo+npm实现免费图床

本文参考自 Akilar&#xff0c;原文地址&#xff1a;https://akilar.top/posts/3e956346/ Picgo的配置 Github图床仓库内容不能超过1GB&#xff0c;因为Github原则上是反对仓库图床化的&#xff0c;超过1GB之后会由人工审核仓库内容&#xff0c;如果仓库被发现用来做图床&…

简要说说软分叉和硬分叉。

前言 一、软分叉 二、硬分叉 三、用途 总结 前言 软分叉和硬分叉是区块链技术中的两个重要概念&#xff0c;它们通常与加密货币的网络升级有关。下面我将分别解释这两个概念&#xff0c;并提供一些例子来帮助理解。下面是方便理解软分叉和硬分叉的图 一、软分叉 软分叉是一…

docker学习笔记4:CentOS7安装docker

文章目录 一、安装docker二、配置阿里云加速三、测试镜像安装本篇博客介绍如何在centos7里安装docker,关于CentOS7的安装可以查看本专栏的这篇博客: VmWare CentOS7安装与静态ip配置 centos7里安装docker步骤如下: 一、安装docker 先在终端输入su进入root用户,输入如下命…