leetcode以及牛客网单链表相关的题、移除链表元素、链表的中间节点、合并两个有序链表、反转链表、链表分割、倒数第k个节点等的介绍

文章目录

  • 前言
  • 一、移除链表元素
  • 二、链表的中间节点
  • 三、合并两个有序链表
  • 四、反转链表
  • 五、链表分割
  • 六、倒数第k个节点
  • 总结


前言

leetcode以及牛客网单链表相关的题、移除链表元素、链表的中间节点、合并两个有序链表、反转链表、链表分割、倒数第k个节点等的介绍


一、移除链表元素

在这里插入图片描述


/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
 typedef struct ListNode ListNode;
struct ListNode* removeElements(struct ListNode* head, int val) {
    
    ListNode* newhead = NULL;
    ListNode* newtail = NULL;
    ListNode* cur = head;
    while(cur)
    {
        if(cur->val != val)
        {
            if(newhead == NULL)
            {
                newhead = newtail = cur;
            }
            else
            {
                newtail->next = cur;
                newtail = newtail->next;
            }
            cur = cur->next;
           
        }
        else
        {
            ListNode* next = cur->next;
            free(cur);
            cur = next;
        }
        
    }
    if(newtail)
            newtail->next = NULL;
    return newhead;
}
  • 遍历链表,若节点的值不等于给定的值,则尾插到新链表后面。
  • 若等于,则跳过。

二、链表的中间节点

在这里插入图片描述


/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
 typedef struct ListNode ListNode;
struct ListNode* middleNode(struct ListNode* head) {
    ListNode* fast = head, *slow = head;

    while(fast != NULL && fast->next != NULL)
    {
        fast = fast->next->next;
        slow = slow->next;
    }

    return slow;

}
  • 快慢指针
  • 快指针一次走两步。
  • 慢指针一次走一步。
  • 当快指针节点为空或者下一个节点为空时,跳出循环。
  • 此时慢指针指向中间节点。

三、合并两个有序链表

在这里插入图片描述


/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
 typedef struct ListNode ListNode;
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) {
    if(list1 == NULL &&list2 == NULL)
    {
        return NULL;
    }
    
    ListNode* newHead , *newTail;
    newHead = newTail = NULL;

    while(list1 != NULL && list2 != NULL)
    {
        if(list1->val > list2->val)
        {
            if(newHead == NULL)
            {
                newHead = newTail = list2;
            }
            else
            {
                newTail->next = list2;
                newTail = newTail->next;
            }
            list2 = list2->next;
        }
        else
        {
            if(newHead == NULL)
            {
                newHead = newTail = list1;
            }
            else
            {
                newTail->next = list1;
                newTail = newTail->next;
            }
            list1 = list1->next;
        }
    }
    if(list1 == NULL)
    {
        if(newHead == NULL)
            newHead = list2;
        else
            newTail->next = list2;
    }
    else
    {
        if(newHead == NULL)
            newHead = list1;
        else
            newTail->next = list1;
    }
    return newHead;
}
  • 遍历两个单链表。
  • 两个链表都不为空,判断节点大小,将小点节点尾插到新的头节点上。
  • 若有一个链表为空,跳出循环,并将另一个链表尾插到新的尾节点上。

四、反转链表

在这里插入图片描述


/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
 typedef struct ListNode ListNode;
struct ListNode* reverseList(struct ListNode* head) {
    if(head == NULL)
        return NULL;
   ListNode* n1, *n2, *n3;

   n1 = NULL;
   n2 = head;
   n3 = head->next;

   while(n2)
   {
        n2->next = n1;

        n1 = n2;
        n2 = n3;
        if(n3)
            n3 = n3->next;
   }
    
    return n1;
}
    1. 将每个节点的next指向前一个节点。
    1. 创建一个新的头节点,遍历链表进行头插。

五、链表分割

在这里插入图片描述


/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};*/
class Partition {
public:
    ListNode* partition(ListNode* pHead, int x) {
        struct ListNode* gGuard, *gTail, *lGuard, *lTail;

        gGuard = gTail = (struct ListNode*)malloc(sizeof(struct ListNode));
        lGuard = lTail = (struct ListNode*)malloc(sizeof(struct ListNode));
        gGuard->next = lGuard->next = NULL;

        struct ListNode* cur = pHead;

        while(cur)
        {
            if(cur->val < x)
            {
                lTail->next = cur;
                lTail = lTail->next;
            }
            else 
            {
                gTail->next = cur;
                gTail = gTail->next;
            }
            cur = cur->next;
        }
        
        lTail->next = gGuard->next;
        gTail->next = NULL;
        pHead = lGuard->next;

        free(gGuard);
        free(lGuard);

        
        
        return pHead;
        

    }
};
  • 创建两个带有哨兵位的单向链表。
  • 若小于给定值尾插到小的链表中。
  • 若大于等于给定值尾插到大的链表中。
  • 再将小链表的尾节点的next指向大链表的第一个有效节点。
  • 最后再将大链表的尾节点的next指向NULL。

六、倒数第k个节点

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

#include <stdio.h>
#include <stdlib.h>

typedef struct ListNode
{
	int val;
	struct ListNode* next;
}ListNode;


ListNode* FindKthToTail(ListNode* pListHead, int k)
{
	if (pListHead == NULL)
	{
		return NULL;
	}
	ListNode* fast, * slow;
	fast = slow = pListHead;

	int i = 0;
	for (i = 1; i < k; i++)
	{

		fast = fast->next;
		if (fast == NULL)
		{
			return NULL;
		}
	}

	while (fast->next != NULL)
	{
		fast = fast->next;
		slow = slow->next;
	}
	return slow;
}

int main()
{

	ListNode* phead = (ListNode*)malloc(sizeof(ListNode));
	ListNode* n2 = (ListNode*)malloc(sizeof(ListNode));
	ListNode* n3 = (ListNode*)malloc(sizeof(ListNode));
	ListNode* n4 = (ListNode*)malloc(sizeof(ListNode));
	ListNode* n5 = (ListNode*)malloc(sizeof(ListNode));


	phead->val = 1;
	n2->val = 2;
	n3->val = 3;
	n4->val = 4;
	n5->val = 5;

	phead->next = n2;
	n2->next = n3;
	n3->next = n4;
	n4->next = n5;
	n5->next = NULL;

	ListNode* plist = phead;

	ListNode* ret = FindKthToTail(plist,5);

	while (ret)
	{
		printf("%d->", ret->val);
		ret = ret->next;
	}
	printf("NULL\n");

	return 0;
}
  • 倒数第k个和倒数第一个之间的距离是k-1.
  • 所以使用快慢指针,将快的指针先走k-1步,此时快慢指针差距是k-1.
  • 所以当快指针走到链表结尾时,慢指针走到倒数第k个节点。

总结

leetcode以及牛客网单链表相关的题、移除链表元素、链表的中间节点、合并两个有序链表、反转链表、链表分割、倒数第k个节点等的介绍

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【详细讲解】二叉树的层序遍历

广度优先搜索 总结一下&#xff0c;思路就是&#xff1a; 加入元素&#xff0c;记录size&#xff0c;size就是当前这一层的元素个数。不断弹出元素&#xff0c;size - 1&#xff0c; 同时加入弹出元素的左右孩子&#xff0c;直到size0&#xff0c;说明当前层已经完全遍历完&am…

闲话 .NET(4):为什么要跨平台?

前言 .NET Core 有一个关键词就是跨平台&#xff0c;为什么要跨平台呢&#xff1f;Windows 操作系统不香吗&#xff1f;今天我们来聊聊这个 原因一&#xff1a;安全考虑 Windows OS 是闭源的&#xff0c;而 Linux 是开源的&#xff0c;因此有些公司的技术负责人就认为 Linux…

Unity性能优化工具介绍

文章目录 一.Stats组件1.Audio音频的数据组件:2.图形数据 二.Profiler 性能分析器 一.Stats组件 Unity自带Statistics(统计数据),Game视窗中点击Stats打开 1.Audio音频的数据组件: 1):Level 声音强度 单位是分贝(dB) 表示音频听声音的大小,是闪烁波动的. 2):SDPload 数据信…

利用神经网络学习语言(一)——自然语言处理的基本要素

相关说明 这篇文章的大部分内容参考自我的新书《解构大语言模型&#xff1a;从线性回归到通用人工智能》&#xff0c;欢迎有兴趣的读者多多支持。 本文涉及到的代码链接如下&#xff1a;regression2chatgpt/ch10_rnn/tokenizer.ipynb 本系列文章将深入探讨一种应用广泛的神经…

Vitis HLS 学习笔记--基本指针和算术指针

目录 1. 简介 2. 基本指针 3. 算术指针 4. 疑点解答 4.1 疑点1 4.2 疑点2 5. 总结 1. 简介 在 C/C 语言中&#xff0c;指针被广泛用来表示内存中的地址信息&#xff0c;它们是理解和使用这些语言的核心概念之一。然而&#xff0c;在 Vitis HLS 中&#xff0c;指针的使用…

ChatGPT、Llama等大模型回答脑筋急转弯

分别使用ChatGPT3.5、 4.0 和Llama 2 70B 和3 70B这四个应用最广的大模型来回答这个流传最广的脑筋急转弯。 树上10知鸟&#xff0c;打死2只&#xff0c;还有几只&#xff1f; 看看它们的表现吧&#xff1a; 题目树上10知鸟&#xff0c;打死2只&#xff0c;还有几只&#xf…

保护共享资源的方法(互斥锁)

我最近开了几个专栏&#xff0c;诚信互三&#xff01; > |||《算法专栏》&#xff1a;&#xff1a;刷题教程来自网站《代码随想录》。||| > |||《C专栏》&#xff1a;&#xff1a;记录我学习C的经历&#xff0c;看完你一定会有收获。||| > |||《Linux专栏》&#xff1…

【BSP开发经验】简易文件系统digicapfs实现方式

文章目录 背景Linux vfs框架介绍数据结构系统调用openwriteread 总体框架 Linux 磁盘高速缓存机制标准文件访问同步文件访问异步文件访问buffer_head 如何实现一个简单的文件系统blkdevfs注册文件系统产生一个文件让文件变得可读可写 背景 在新的分区升级启动方案中需要分别实…

快手二面准备【面试准备】

快手二面准备【面试准备】 前言版权快手二面准备秋招一面中的问题实习一面中的问题计算机网络和操作系统论坛项目登录注册ThreadLocal代替session存储用户秒杀项目登录注册->阿里验证码->rpcsession为什么改为token实现&#xff0c;redis存储用户信息由binlog的用法->…

【Unity】免费的高亮插件——QuickOutline

除了常见的HighLightSystem来实现的高亮功能&#xff0c;其实还有很多的方法实现物体的高亮。 在 Unity资源商店 搜索OutLine&#xff0c;就会有很多免费好用的高亮插件。 下面介绍一下 QuickOutline这个插件&#xff0c;在 Unity资源商店 搜索到后&#xff0c;点击进去就可以…

网络模型-Qinq配置与应用

Qinq配置与应用 通过配置Qinq来实现利用公网提供的VLAN100使企业1互通&#xff0c;利用公网提供的VLAN200使企业2互通不同企业之间互相隔离。并通过在连接其它厂商设备的接口上配置修改0in0外层VLAN Tag的TPID值&#xff0c;来实现与其它厂商设备的互通。 一、创建VLAN #在Swi…

薪资不公、晋升无望?动笔写一份申诉材料吧!

薪资不公、晋升无望&#xff1f;动笔写一份申诉材料吧&#xff01; 引言&#xff1a;每个努力工作的人都值得公平对待 在职场上&#xff0c;我们付出了汗水和智慧&#xff0c;期待着相应的回报——合理的工资和公正的晋升机会。然而&#xff0c;现实并不总是如此美好。当你感觉…

Thingsboard规则链:Entity Type Filter节点详解

在物联网&#xff08;IoT&#xff09;的世界里&#xff0c;数据的多样性与复杂性要求处理架构具备高度的灵活性和针对性。ThingsBoard作为一款强大的物联网平台&#xff0c;通过其规则链&#xff08;Rule Chains&#xff09;机制&#xff0c;让数据的自动化处理变得既强大又灵活…

谓词逻辑(一)

一、句子的谓词符号化 谓词逻辑&#xff0c;也叫一阶逻辑&#xff0c;它对每个最简单的命题尽一步进行分解。 1个体词&#xff1a;可以独立存在的客体。 2谓词&#xff1a;描述一个个体词的属性或多个个体词之间的关系&#xff08;可用一元函数和多元函数来理解&#xff09;…

18.SpringCloud Gateway

简介 SpringCloud Gateway是spingcloud家族的产品&#xff0c;使用netty实现的高性能服务网关&#xff0c;用于替换netflix公司的zuul网关实现。 参考地址&#xff1a; https://spring.io/projects/spring-cloud 术语 工作原理 Route Predicate Factories GatewayFilte…

降本增效!看TeeChart如何帮助实现海量「监测数据」可视化

“环境监测数据异常庞大&#xff0c;想要实现数据监测分析&#xff0c;除了要求控件具有良好的兼容性和稳定性&#xff0c;还对多样化、定制化的图表开发也有很高的要求” ——————— 项目负责工程师 王工 TeeChart Pro 最新版下载&#xff08;qun&#xff1a;740060302&…

C++初阶学习第十弹——探索STL奥秘(五)——深入讲解vector的迭代器失效问题

vector&#xff08;上&#xff09;&#xff1a;C初阶学习第八弹——探索STL奥秘&#xff08;三&#xff09;——深入刨析vector的使用-CSDN博客 vector&#xff08;中&#xff09;&#xff1a;C初阶学习第九弹——探索STL奥秘&#xff08;四&#xff09;——vector的深层挖掘和…

JVM学习-堆空间(一)

堆空间 每个进程&#xff08;JVM实例&#xff09;拥有唯一的方法区和堆空间&#xff0c;拥有唯一的Runtime实例(基于饿汉式方式)&#xff0c;线程共享进程的方法区和堆空间&#xff0c;每个线程拥有独立的程序计数器、本地方法栈和虚拟机栈。 一个JVM实例只存在一个堆内存&am…

windows docker desktop 更换镜像存储目录

windows docker desktop 更换镜像存储目录 方法&#xff1a;如图&#xff0c;Browse浏览一个新的目录并选中&#xff0c;确定后&#xff0c;程序会开始stop&#xff0c;在stop完成前&#xff0c;会持续迁移原有镜像到新的位置&#xff0c;你会发现目标位置的磁盘占用空间越来越…

内网穿透--Ngrok-入门-上线

免责声明:本文仅做技术交流与学习... 目录 Ngrok: 技术实现: 前提: 命令: 详细流程及图解: 平台Ngrok: Sunny-Ngrok内网转发内网穿透 - 国内内网映射服务器 支持的协议&#xff1a;tcp、http、https 支持的类型&#xff1a;正向代理、反向代理 --隧道开通免费的 --协议…