【链表】算法题(一) ---- 力扣 / 牛客

news2024/11/13 21:33:53

一、移除链表元素

        移除链表中值为val的元素,并返回新的头节点

思路:

题目上这样说,我们就可以创建一个新的链表,将值不为val的节点,尾插到新的链表当中,最后返回新链表的头节点。

typedef struct ListNode ListNode;
struct ListNode* removeElements(struct ListNode* head, int val) {
    if(head==NULL)
    {
        return NULL;
    }
    ListNode* newhead = (ListNode*)malloc(sizeof(ListNode));
    ListNode* ptail = head;
    ListNode* pcur = newhead;
    while (ptail) {
        if (ptail->val != val) {
            pcur->next = ptail;
            pcur = pcur->next;
        }
        ptail = ptail->next;
    }
    pcur->next=NULL;
    ListNode* ret = newhead->next;
    free(newhead);
    newhead = NULL;
    return ret;
}

        当然,这个题还有其他思路。

二、反转链表

        将链表反转,并返回反转后的链表的头节点

思路:

        创建三个指针变量,l1,l2,l3(指针初始指向如下图),遍历链表,先让l3=l2->next;再将l2的next指针指向l2;再l1指向l2,l2指向l3(l2下一个节点);直到遍历结束,结束条件为(l2等于NULL)此时l1指向的就是反转后的链表的头节点。

根据题目给的示例来分析

遍历数组,循环进行一次

l2不等于NULL循环继续

l2不等于NULL循环继续

l2不等于NULL循环继续

l2仍然不等于NULL,循环继续

到这里,l2已经遍历到了NULL,循环结束,此时l1指向的就是反转后链表的头节点,直接返回即可。

typedef struct ListNode ListNode;
struct ListNode* reverseList(struct ListNode* head) {
    ListNode* l1,*l2,*l3;
    l1=NULL;
    l2=head;
    while(l2)
    {
        l3=l2->next;
        l2->next=l1;
        l1=l2;
        l2=l3;
        
    }
    return l1;
}

三、链表的中间节点

        看到这个题,本人一开始的想法是:遍历一遍链表,记录链表的节点个数,然后再遍历一次链表,寻找链表的中间节点;这样实现非常麻烦,现在使用一种新的方法来解决这个问题

思路:快慢指针

        定义两个快慢指针,fast和slow刚开始都指向链表的头节点,fast每次向前走两个节点,而slow指针每次向前走一个节点;最后当fast指针或者fast的next指针为NULL遍历结束;此时slow指向的就是链表的中间节点。

根据题所给的示例分析:
        链表个数为奇数

fast=fsat->next->next;

slow=slow->next;

           

遍历到这里,fast的next指针为空,循环结束;此时slow指向的就是链表的中间节点。

        链表的节点数为偶数

fast=fsat->next->next;

slow=slow->next;

循环到这里,fast为空,循环结束,此时slow指向的节点就是链表的中间节点。

typedef struct ListNode ListNode;
struct ListNode* middleNode(struct ListNode* head) {
    if(head==NULL)
    {
        return NULL;
    }
    ListNode* fast=head;
    ListNode* slow=head;
    while(fast&&fast->next)
    {
        fast=fast->next->next;
        slow=slow->next;
    }
    return slow;
}

四、合并两个有序链表

        合并两个有序链表,这里创建一个新的链表,将两个链表中较小小的数据依次尾插到新链表中,最后返回新链表的头节点即可。

        注意:这里需要注意,初始的两个链表可能为空,这里需要进判断,如果list1为空,就返回list1;如果list2为空,就返回list1。

根据题目示例分析

        比较l1和l2指向的节点的值大小,l1->val=l2->val(l1的不小于l2的),将l2指向节点尾插到新链表

        此时,l1->val < l2->val,将l1指向的节点尾插到新链表

        此时,l1->val < l2->val,将l1指向的节点尾插到新链表

比较l1和l2指向的节点的值大小,l2->val < l1->val,将l2指向节点尾插到新链表

        比较l1和l2指向的节点的值大小,l1->val=l2->val(l1的不小于l2的),将l2指向节点尾插到新链表

        l2为空,循环结束,这里l1的节点还没全部插到新链表中,这里直接 ptail->next=l1;即可。

注:这里使用动态内存来给newhead开辟空间,记得将其释放掉,养成好习惯。

typedef struct ListNode ListNode;
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) {
    if(list1==NULL)
    {
        return list2;
    }
    if(list2==NULL)
    {
        return list1;
    }
    ListNode* l1=list1;
    ListNode* l2=list2;
    ListNode* newhead=(ListNode*)malloc(sizeof(ListNode));
    ListNode* ptail=newhead;
    while(l1 && l2)
    {
        if(l1->val<l2->val)
        {
            ptail->next=l1;
            l1=l1->next;
        }
        else
        {
            ptail->next=l2;
            l2=l2->next;
        } 
        ptail=ptail->next;
    }
    if(l1)
    {
        ptail->next=l1;
    }
    if(l2)
    {
        ptail->next=l2;
    }
    ListNode* ret=newhead->next;
    free(newhead);
    newhead=NULL;
    return ret;
}

五、链表分割

将链表小于x的节点排在其余节点之前,不能改变原来顺序,最后返回排序好的链表的头指针。

思路:

        创建两个链表,一个链表l1,存放值小于val的节点;另一个链表l2,存放值大于等于val的节点。最后将两个链表连接起来,返回l1链表的头节点即可。

这里需要注意:再l2链表的结尾,要将尾节点的next指针置为NULL;

#include <cstddef>
class Partition {
public:
    ListNode* partition(ListNode* pHead, int x) {
        // write code here
        ListNode* list1,*l1;
        l1=list1=(ListNode*)malloc(sizeof(ListNode));
        ListNode* list2, *l2;
        l2=list2=(ListNode*)malloc(sizeof(ListNode));
        ListNode* ptail=pHead;
        while(ptail)
        {
            if(ptail->val<x){
                //尾插到l1里
                l1->next=ptail;
                l1=l1->next;
            }
            else{
                l2->next=ptail;
                l2=l2->next;
            }
            ptail=ptail->next;
        }
        l2->next=NULL;
        l1->next=list2->next;
        ListNode* ret=list1->next;
        free(list1);
        free(list2);
        list1=list2=NULL;
        return ret;
    }
};

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

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

相关文章

java《字符串进阶篇》--习题逐语句分析及认识链式编程

一、前言 字符串相关的习题分享&#xff0c;随着学习的深入&#xff0c;应该要多做一些习题来巩固知识点&#xff0c;而不是一味的去学习新的东西。这几天尽可能地去给大家分享一些常用的方法及习题的讲解&#xff0c;希望大家认真观看&#xff0c;每一道题都有对应的分析。基…

GAMMA数据处理(八)

新学习了一个命令&#xff1a; SLC_cat_ScanSAR - Concatenate sequential ScanSAR burst SLC images (Sentinel-1, TSX, RCM...)&#xff0c;做数据拼接的。之前一直没有涉及到拼接问题&#xff0c;就一直没管。如果研究区包含两景SLC&#xff0c;可以拼接成一景。但是不知道…

计算机丢失CH375DLL怎么办,CH375DLL.DLL;计算机找不到CH375DLL怎么办,CH375DLL.DLL

翻遍CSDN&#xff0c;发现的文章不是只有描述不给资源&#xff0c;要不就是资源收费。 真是狗屎啊&#xff1b; 在千辛万苦找到资源后&#xff0c;我决定写一篇&#xff1b; 首先是资源文件下载 我上传的&#xff1a;&#xff08;肯定是0积分&#xff0c;如果收费了告诉我&…

Nuxt.js 错误侦探:useError 组合函数

title: Nuxt.js 错误侦探&#xff1a;useError 组合函数 date: 2024/7/14 updated: 2024/7/14 author: cmdragon excerpt: 摘要&#xff1a;文章介绍Nuxt.js中的useError组合函数&#xff0c;用于统一处理客户端和服务器端的错误&#xff0c;提供statusCode、statusMessage和…

IOT 可编程控制系统

IOT&#xff08;物联网&#xff09;可编程控制系统&#xff0c;如GF-MAXCC等&#xff0c;是一种集成了多种先进技术和功能的智能化控制设备&#xff0c;它能够在物联网系统中发挥关键作用&#xff0c;实现对多种设备的集中管理和控制。具体来说&#xff0c;IOT可编程控制系统的…

7天学会CANOpen

本系列文章&#xff0c;主要介绍CANOpen的学习知识&#xff0c;能够全面掌握CANOpen原理。文章会不定期的更新。 学习基础&#xff1a;CAN通信。 1. CANOpen通信协议1 2. CANOpen对象字的理解 3. CANOpen之CAN-ID、NODE-ID、COB-ID 4. CanOpen报文类型 5. CANO报文---SDO…

python 怎样生成窗体

通过import tkinter导入Tkinter模块&#xff0c;没有这句下面的都不成立了。 wintkinter.Tk()&#xff0c;这句是创建windows的窗口对象&#xff0c;注意后面的Tk&#xff0c;大小写。 win.title("窗口")&#xff0c;这段是设置窗口上的标题。 另外窗口的大小你可以通…

Paddle 打包部署

PaddleOCR 打包部署exe 心酸历程 PaddleOCR部署exe模式PaddleOCR安装到本地(稍后有时间再写)PaddleOCR打包过程异常问题记录&#xff01;&#xff01;&#xff01;&#xff01;No such file or directory: D:\\py_project\\paddleOCR\\dist\\paddleOCR\\_internal\\paddleocr\\…

JVM:垃圾回收器

文章目录 一、介绍二、年轻代-Serial垃圾回收器三、老年代-SerialOld垃圾回收器四、年轻代-ParNew垃圾回收器五、老年代-CMS&#xff08;Concurrent Mark Sweep&#xff09;垃圾回收器六、年轻代-Parllel Scavenge垃圾回收器七、Parallel Old垃圾回收器八、G1垃圾回收器 一、介…

《Python数据科学之五:模型评估与调优深入解析》

《Python数据科学之五&#xff1a;模型评估与调优深入解析》 在数据科学项目中&#xff0c;精确的模型评估和细致的调优过程是确保模型质量、提高预测准确性的关键步骤。本文将详细探讨如何利用 Python 及其强大的库进行模型评估和调优&#xff0c;确保您的模型能够达到最佳性能…

防火墙之NAT,智能选路篇

什么是NAT? 网络地址转换 1.静态NAT&#xff08;static NAT&#xff09;&#xff08;静态一对一映射&#xff09;&#xff1a;设置起来最为简单&#xff0c;内部网络中的每个主机都被永久映射成外部网络中的某个合法的地址。多用于服务器场景。 2.动态NAT&#xff08;pool…

mavsdk_server安卓平台编译

1.下载好mavsdk并进入mavsdk目录 2.生成docker安卓平台文件 docker run --rm dockcross/android-arm64 >./dockcross-android-arm64 3.生成makefile ./dockcross-android-arm64 cmake -DCMAKE_BUILD_TYPERelease -DBUILD_MAVSDK_SERVERON -DBUILD_SHARED_LIBSOFF -Bbuild/…

Study--Oracle-07-ASM自动存储管理(二)

一、ASM安装准备条件 1、ASM支持存储类型 本地祼设备(本地的磁盘和分区) 网络附加存储(NAS) 存储区域网络(SAN) 2、ASM使用本地裸设备,要点: 已经被挂载到操作系统上或者已经做了分区 映射裸设备为文件名 设置正确的权限(针对grid用户和asmadmin组,权限为660) 二、OR…

如何用AI做副业?

无论是打工&#xff0c;还是创业&#xff0c;赚钱才是硬道理&#xff0c;拥有可持续的「睡后收入」才是我们孜孜不倦追求的目标。 一、职业四象限 1、E象限&#xff08;雇员象限&#xff09;、帮别人挣钱 E象限是雇员象限。别人给我们发工资&#xff0c;我们帮别人挣钱。这是风…

建立数据通路(三)

PC寄存器 背景 有了时钟信号&#xff0c;可以提供定时输入。有了D型触发器&#xff0c;可以在时钟信号控制的时间点写入数据把这两个功能组合起来&#xff0c;就可以实现一个自动计数器 程序计数器 加法器的两个输入&#xff0c;一个始终设置成1&#xff0c;另外一个来自于一…

关于Qt Creator 使用Qt Quick的Design模式设置

关于使用Qt Quick的Design模式设置&#xff1a; 如描述所言&#xff1a; 如果使用Design模式打开qml文件失败显示如下&#xff1a; 首先确认自己是否安装了Qt Design Studio 如果安装了仍然不显示&#xff0c;则需要勾选下面三个地方才能用Design模式打开.ui.qml文件&#…

Hologres+Flink企业级实时数仓核心能力介绍

讲师&#xff1a;骆撷冬 Hologres PD 随着业务发展&#xff0c;业务对于时效性的要求在逐渐提升。各种场景都需要实时&#xff0c;例如春晚实时直播大屏、双11 GMV实时大屏、实时个性化推荐等等多种场景&#xff0c;都对数据的时效性有着非常高的要求。随着实时需求的发展&…

【技术追踪】使用去噪扩散型进行 3D 血管图生成(MICCAI-2024)

graphs 图也可以用 diffusion 耶~ 本文提出了第一个去噪扩散模型在 3D 血管图生成中的工作&#xff0c;其是新颖的两阶段生成方法&#xff0c;依次对节点坐标和边进行去噪&#xff0c;在生成多样化、新颖且解剖学上合理的血管图方面性能表现出色。 论文&#xff1a;3D Vessel G…

pg-存储过程

1.概念和优势 2.代码块结构 do end之间俩个$$ declare用来声明定义变量&#xff0c;begin用来运行赋值 notice输出 3.变量使用

java语法(分支,方法,递归);Debug使用

java语法 x 操作符 ->分支&#xff0c;循环&#xff0c;方法 分支 条件的三种if if if…else… public class IfDemo01 { public static void main(String[] args) { int a 3; final int DAY 3; if(a<DAY){ }else if (a<…