首页 > 其他分享 >【华为机试ACM基础#02】从单向链表中删除指定值的节点(熟悉链表的输入方式,虽然说本题可能是特例)

【华为机试ACM基础#02】从单向链表中删除指定值的节点(熟悉链表的输入方式,虽然说本题可能是特例)

时间:2023-06-26 19:55:41浏览次数:66  
标签:02 ListNode cur val ACM next 链表 节点

从单向链表中删除指定值的节点

输入一个单向链表和一个节点的值,从单向链表中删除等于该值的节点,删除后如果链表中无节点则返回空指针。

链表的值不能重复。

构造过程,例如输入一行数据为:

6 2 1 2 3 2 5 1 4 5 7 2 2

则第一个参数6表示输入总共6个节点,第二个参数2表示头节点值为2,剩下的2个一组表示第2个节点值后面插入第1个节点值,为以下表示:

1 2 表示为

2->1

链表为2->1

3 2表示为

2->3

链表为2->3->1

5 1表示为

1->5

链表为2->3->1->5

4 5表示为

5->4

链表为2->3->1->5->4

7 2表示为

2->7

链表为2->7->3->1->5->4

最后的链表的顺序为 2 7 3 1 5 4

最后一个参数为2,表示要删掉节点为2的值

删除 结点 2

则结果为 7 3 1 5 4

数据范围:链表长度满足 1≤�≤1000 1≤n≤1000 ,节点中的值满足 0≤���≤10000 0≤val≤10000

测试用例保证输入合法

输入描述

输入一行,有以下4个部分:

​ 1 输入链表结点个数
​ 2 输入头结点的值
​ 3 按照格式插入各个结点
​ 4 输入要删除的结点的值

输出描述

输出一行

输出删除结点后的序列,每个数后都要加空格

思路

如果这题是在LeetCode用核心代码模式做的话,是一道很常规的题目,只需要遍历单向链表,找到与目标值匹配的节点后删除即可

在ACM模式下,输入输出就成了大问题

为了理顺逻辑,最好将删除功能单独写成一个函数

那么,整体逻辑就是:从输入数据中拿到头节点,遍历输入数据,将链表构建好,然后调用删除函数将指定节点删除,最后再把链表的值打印出来

#include<iostream>
using namespace std;

struct ListNode{
};

ListNode* deleteNode(ListNode* head, int val) {//删除链表中值为val的节点
    
}

int main(){
    
}

定义结构体

先定义一个结构体作为链表节点(详见:构造链表)

struct ListNode{
    int val;
    ListNode* next;
    ListNode(int x):val(x), next(nullptr){}
};
删除函数

使用dummy进行删除(注意,这里和设计链表中的删除函数还不太一样,这里需要根据节点值进行删除而不是索引值)

ListNode* deleteNode(ListNode* head, int val) {//删除链表中值为val的节点
    if(head == nullptr) return nullptr;//特判:如果头结点为空,返回空指针
    if(head->val == val) return head->next;//特判:如果头结点的值等于val,直接返回头结点的下一个节点
    
    ListNode* dummy = new ListNode(0);//创建dummy节点,接在头节点之前
    dummy->next = head;
    ListNode* cur = dummy;
    while(cur->next != nullptr){
        if(cur->next->val == val){//处理被删除的节点
            ListNode* tmp = cur->next;
            cur->next = cur->next->next;
            delete tmp;
        }else{
            cur = cur->next;
        }
    }
    return dummy->next;   
}
主函数

在主函数里,我们需要接受一行输入数据,例如:

6 2 1 2 3 2 5 1 4 5 7 2 2

则第一个参数6表示输入总共6个节点,第二个参数2表示头节点值为2,剩下的2个一组表示第2个节点值后面插入第1个节点值

根据题目描述,我们需要两个两个的从输入数据中取值,过程如下:

取1、2,表示2要接在1后面【链表为2->1】

接下来取2、3,表示3要接在2后面【链表为2->3->1】

然后取5、1,表示5要接在1后面【链表为2->3->1->5】

取4、5,表示5要接在4后面【链表为2->3->1->5->4】...

实际上题目除了要我们从单向链表中删除指定值的节点,还需要我们根据输入数据按照规则来先构建链表

int main(){
    //定义几个变量分别接收:链表节点数量(例子中的6)、头节点的值(例子中的2)、待删除节点的值
    int n, head_val, val;
    cin >> n >> head_val;

    ListNode* head = new ListNode(head_val); //创建头结点
    for(int i = 0; i < n-1; i++){  //循环插入剩余的n-1个节点
        int pre_val, cur_val;//取两个值(如例子中的1、2)
        cin >> cur_val >> pre_val; //输入当前节点的值和需要插入的位置的节点的值

        ListNode* pre = head;
        while(pre != NULL && pre->val != pre_val)  //遍历链表,找到需要插入的节点
            pre = pre->next;

        ListNode* cur = new ListNode(cur_val); //创建当前节点
        cur->next = pre->next;  //将当前节点插入至链表中
        pre->next = cur;
    }
}

然后再从输入中获取待删除值,调用删除函数,之后遍历打印链表即可

    cin >> val; //输入需要删除的节点的值
    head = deleteNode(head, val); //删除节点
    while(head != NULL){  //遍历打印链表
        cout << head->val << " ";
        head = head->next;
    }
代码
#include<iostream>
using namespace std;

struct ListNode{
    int val;
    ListNode* next;
    ListNode(int x) : val(x), next(NULL) {}
};

ListNode* deleteNode(ListNode* head, int val) {//删除链表中值为val的节点
    if(head == nullptr) return nullptr;//特判:如果头结点为空,返回空指针
    if(head->val == val) return head->next;//特判:如果头结点的值等于val,直接返回头结点的下一个节点
    
    ListNode* dummy = new ListNode(0);//创建dummy节点,接在头节点之前
    dummy->next = head;
    ListNode* cur = dummy;
    while(cur->next != nullptr){
        if(cur->next->val == val){//处理被删除的节点
            ListNode* tmp = cur->next;
            cur->next = cur->next->next;
            delete tmp;
        }else{
            cur = cur->next;
        }
    }
    return dummy->next;   
}

int main(){
    int n, head_val, val;
    cin >> n >> head_val;

    ListNode* head = new ListNode(head_val); //创建头结点
    for(int i = 0; i < n-1; i++){  //循环插入剩余的n-1个节点
        int cur_val, pre_val;//取两个值(如例子中的1、2)
        cin >> cur_val >> pre_val; //输入当前节点的值和需要插入的位置的节点的值

        ListNode* pre = head;
        while(pre != NULL && pre->val != pre_val)  //遍历链表,找到需要插入的节点
            pre = pre->next;

        ListNode* cur = new ListNode(cur_val); //创建当前节点
        cur->next = pre->next;  //将当前节点插入至链表中
        pre->next = cur;
    }

    cin >> val; //输入需要删除的节点的值
    head = deleteNode(head, val); //删除节点
    while(head != NULL){  //遍历打印链表
        cout << head->val << " ";
        head = head->next;
    }
    return 0;
}

输入输出总结

其实也没啥好总结的这题,本来以为可以用来当做ACM下链表输入的参考的,结果使用的还是cin

但是观察这题可以发现:ACM下,题目要求的输入有可能不是一次性输入完成的

例如本题,题目举的例子是6 2 1 2 3 2 5 1 4 5 7 2 2,如果一开始没明白题意的话很容易以为输入数据的形式就是这个,导致后续处理很困难

还有就是复习了一下删除指定节点值的操作,练习了链表的构造

标签:02,ListNode,cur,val,ACM,next,链表,节点
From: https://www.cnblogs.com/DAYceng/p/17506587.html

相关文章

  • 云原生周刊:HashiCorp Vault 1.14 发布 | 2023.6.26
    开源项目推荐HelmfileHelmfile是一个开源工具,使用Helmcharts简化复杂应用程序的部署。它提供了一种声明性的方式来定义Kubernetes资源的期望状态,并管理Helmreleases的安装、升级和删除。KubeVPNKubeVPN是一个基于Kubernetes的开源VPN解决方案,它提供了一种简单的......
  • 【cs50 2022】lab1 && problem set1
    |lab1|#include<cs50.h>#include<stdio.h>intmain(void){//TODO:Promptforstartsizeintstart_size;do{start_size=get_int("Startsize:");}while(start_size<9);//TODO:Promptforend......
  • 生活反思随笔 2023.6 -
    [1]当投身于漫长的事业时,我们需要信心之源泉来维持内心的平静,因此我们能好好地坚持下去。当信心的来源来自于亲友时,我们心怀感激。当独自上路时,我们时常锻炼我们自信之肌肉,并对我们的自信心怀感激。[2]“德智体美劳”这个小时候常听到的五个综合的个人修养评价指标,实际放到成......
  • C/C++航空客运订票系统[2023-06-26]
    C/C++航空客运订票系统[2023-06-26]实验1航空客运订票系统问题描述:航空客运订票的业务活动包括查询航线和客票预订的信息、客票预订和办理退票等,设计一个程序使上述任务借助计算机来完成。基本要求:(一)系统必须存储的数据信息。1.信息:飞机抵达的城市、航班号、飞机号、起降......
  • 2023-06-26:在大小为 n x n 的网格 grid 上,每个单元格都有一盏灯,最初灯都处于 关闭 状
    2023-06-26:在大小为nxn的网格grid上,每个单元格都有一盏灯,最初灯都处于关闭状态给你一个由灯的位置组成的二维数组lamps其中lamps[i]=[rowi,coli]表示打开位于grid[rowi][coli]的灯即便同一盏灯可能在lamps中多次列出,不会影响这盏灯处于打开状态当一盏灯处于......
  • 福昕Foxit PDF远程代码执行漏洞CVE-2023-27363分析与复现
    漏洞概述福建福昕软件开发股份有限公司是一家国际化运营的PDF电子文档解决方案提供厂商,提供文档的生成、转换、显示、编辑、搜索、打印、存储、签章、表单、保护、安全分发管理等涵盖文档生命周期的产品技术与解决方案。其下产品FoxitPDFReader和FoxitPDFEditor的javascript函......
  • Freertos学习02-Task传入参数
    一、前言介绍了freertos具有许多特点,其中的任务调度将有助提高系统的实时性,并将各任务解耦,有助于产品的后续维护与开发,上一节介绍了freertos中关于任务的创建与删除,这一节介绍如何在创建函数的同时并传递参数。二、传递参数再次回顾xTaskCreate()函数的用法以及各输入参数,其中......
  • 集成板级摄像头行业市场调研及趋势分析报告2023-2029
    2023-2029全球集成板级摄像头行业调研及趋势分析报告2022年全球集成板级摄像头市场规模约亿元,2018-2022年年复合增长率CAGR约为%,预计未来将持续保持平稳增长的态势,到2029年市场规模将接近亿元,未来六年CAGR为%。从核心市场看,中国集成板级摄像头市场占据全球约%的市场份额,为全......
  • 家用电器用电机行业市场调研及趋势分析报告2023-2029
    2023-2029全球家用电器用电机行业调研及趋势分析报告2022年全球家用电器用电机市场规模约亿元,2018-2022年年复合增长率CAGR约为%,预计未来将持续保持平稳增长的态势,到2029年市场规模将接近亿元,未来六年CAGR为%。从核心市场看,中国家用电器用电机市场占据全球约%的市场份额,为全......
  • Hugging Face 入选 Time《时代周刊》2023 全球前 100 最具影响力的公司
    ......