数据结构之单链表oJ练习

news2025/1/13 15:52:53

目录

1.移除单链表中与给数相同的元素

2.反转链表

3.找中间节点

4.找倒数第k个

5.合并两个有序链表

6.链表分割

7.链表的回文结构

8.找公共节点


1.移除单链表中与给数相同的元素

 解题思路:

初始化一个新链表,从头结点开始遍历,若相同,保存下一节点位置,再free 掉该节点,若不同将节点赋值给新链表。

代码段:

struct ListNode* removeElements(struct ListNode* head, int val) {
    if(head == NULL)
        return NULL;
    
    struct ListNode* cur = head;
    struct ListNode* prev = NULL;
    
    while(cur)
    {
        //如果当前节点是需要删除的节点
        if(cur->val == val)
        {
            //首先保存下一个节点
            struct ListNode* next = cur->next;
            //如果删除的为头节点,更新头节点
            //否则让当前节点的前趋节点链接next节点
            if(prev == NULL)
            {
                head = cur->next;
            }
            else
            {
                prev->next = cur->next;  
            }
            //释放当前节点,让cur指向next
            free(cur);
            cur = next;
        }
        else
        {
            //如果cur不是需要删除的节点,则更新prev,cur
            prev = cur;
            cur = cur->next;
        }
    }
    
    return head;
}

2.反转链表

 解题思路:

1.链表逆置,将两个相邻的节点交换位置,交换n-1次,完成链表逆置。

代码段:

struct ListNode* reverseList(struct ListNode* head) {
    if(head == NULL || head->next == NULL)
        return head;
    
    struct ListNode* n1, *n2, *n3;
    n1 = head;
    n2 = n1->next;
    n3 = n2->next;
    n1->next = NULL;
    //中间节点不为空,继续修改指向
    while(n2)
    {
        //中间节点指向反转
        n2->next = n1;
        //更新三个连续的节点
        n1 = n2;
        n2 = n3;
        if(n3)
            n3 = n3->next;
    }
    //返回新的头
    return n1;
}

2.头插法,从第一个节点开始遍历,作为新链表的尾节点,然后每遍历一个,头插该节点在新链表中。

// 取节点头插的思想完成逆置
struct ListNode* reverseList(struct ListNode* head) {
    struct ListNode* newhead = NULL;
    struct ListNode* cur = head;
    while(cur)
    {
        struct ListNode* next = cur->next;
        //头插新节点,更新头
        cur->next = newhead;
        newhead = cur;
        cur = next;
    }
    
    return newhead;
}

3.找中间节点

解题思路:

快慢指针:给一个快指针与慢指针都是从链表的头节点开始遍历,快指针每次遍历两个节点,慢指针每次遍历一个节点,当快指针遍历结束时,慢指针刚好处于节点,返回慢指针。

这里需要考虑一下节点总数对于奇偶情况,若为奇数节点快指针刚好为NULL时,慢指针为中间。若为偶指针,则快指针的next为空时,慢指针为中间指针。

所以循环条件为两个都不为零时,即其中一个为零就是中间指针。

truct ListNode* middleNode(struct ListNode* head){
    struct ListNode* faster=head;
    struct ListNode* fast=head;
    while(faster &&faster->next)
    { 
      fast=fast->next;
      faster=faster->next->next;
     
    }
    return fast;
}

4.找倒数第k个

解题思路:

与找中间节点的思路相同,当快指针指向第k个节点时,慢指针指向第一个节点,开始遍历,当快指针为NULL时,慢指针为该链表中倒数第k个节点。

 

struct ListNode* FindKthToTail(struct ListNode* pListHead, int k ) {
    // write code here
    struct ListNode* fast=pListHead;
    struct ListNode* slow =pListHead;
    while(k--)
    {
         if(fast==NULL)
        {
            return NULL;
        }
        fast=fast->next;
       }
    while(fast)
    {
        fast=fast->next;
        slow=slow->next;
    }
    return slow;
}

5.合并两个有序链表

 

 解题思路:

尾插法:因为是有序链表,我们直接从前开始比较:给定两个指针分别指向链表一与链表二,这里返回的时第三个新链表,则让第一个指针指向节点的数与第二个指针指向节点的数作比较,谁小谁先插,将较小的那个数的节点尾插在链表三之后,之后第一个指针与第二个指针同时继续往后遍历,等到其中一个先遍历完的时候,将另一个指针指向的节点直接尾插到链表三中。若某一链表为空,则返回另外一个。

struct ListNode* mergeTwoLists(struct ListNode*list1, struct ListNode* list2){
struct ListNode*p1=list1;
struct ListNode*p2=list2;
        if(p1 == NULL)
            return p2;
        else if(p2 == NULL)
           return p1;
             
        struct ListNode* head = NULL, *tail = NULL;
        //创建空链表
    	head = tail = (struct ListNode*)malloc(sizeof(struct ListNode));
        tail->next = NULL;
        while(p1 && p2)
        {
            // 取小的进行尾插
            if(p1->val < p2->val)
            {
                tail->next = p1;
                tail = tail->next;

                p1 = p1->next;
            }
            else
            {
                tail->next = p2;
                tail = tail->next;

                p2 = p2->next;
            }
        }
        //剩余元素直接拼接
        if(p1)
            tail->next = p1;
        else
            tail->next = p2;

      struct ListNode* list = head->next;
        free(head);
        return list;
}

6.链表分割

 解题思路:

创建新链表时为了避免头节点判空这一繁琐的步骤,我们创建两个带哨兵位的链表,从已知链表头节点开始遍历,将小于x的该节点重新放在一个链表内,其余大于等于x按原顺序放在另一个链表内,之后free掉哨兵位,合并两个链表,尾节点置空,返回新头节点。

 

 if(pHead == NULL)
            return NULL;
        
        struct ListNode* lessHead, *lessTail,*greaterHead, *greaterTail;
        //创建链表表头
        lessHead = lessTail = (struct ListNode*)malloc(sizeof(struct ListNode));
        greaterHead = greaterTail = (struct ListNode*)malloc(sizeof(struct ListNode));
        struct ListNode* cur = pHead;
        while(cur)
        {
            //小于x的尾插到lessTail
            if(cur->val < x)
            {
                lessTail->next = cur;
                lessTail = lessTail->next;
            }
            //大于等于x的尾插到greaterTail
            else
            {
                greaterTail->next = cur;
                greaterTail = greaterTail->next;
            }
            cur = cur->next;
        }
        //链接两个链表
        lessTail->next = greaterHead->next;
        greaterTail->next = NULL;
        //获取表头
        pHead = lessHead->next;
        free(lessHead);
        free(greaterHead);
        
        return pHead;
    }

7.链表的回文结构

 解题思路:

所谓回文结构就是链表是否对称,因此我们首先需要找的中间节点,将中间节点前的存放在一个链表内,将中间节点包括在中间节点逆置后放在另一个链表中,两链表比对,若有其中一个不相等返回false,孙环结束后返回true。

对于链表奇偶情况时,无论奇偶带有中间节点的比较长,而逆置后与前半部分对比,要么刚好,要么提前结束,不影响对称性。

class PalindromeList {
public:
	bool chkPalindrome(ListNode* A) {
		if (A == NULL || A->next == NULL)
			return true;
		ListNode* slow, *fast, *prev, *cur, *tmp;
		slow = fast = A;
		//找到中间节点
		while (fast && fast->next)
		{
			slow = slow->next;
			fast = fast->next->next;
		}
		prev = NULL;
		//后半部分逆置
		cur = slow;
		while (cur)
		{
			tmp = cur->next;
			cur->next = prev;
			prev = cur;
			cur = tmp;
		}
		//逐点比对
		while (A && prev)
		{
			if (A->val != prev->val)
				return false;
			A = A->next;
			prev = prev->next;
		}
		return true;
	}
};

8.找公共节点

 

 解题思路:本题可直接暴力求解,分别计算出A B两链表的长度,它们的长度差作为较长那个链表便利的条件,即两链表同长度开始比较,若相等则是公共节点,注意这里相同的是结点的地址。

 

struct ListNode *getIntersectionNode(struct ListNode *headA, struct ListNode *headB) {
    struct ListNode* pa=headA;
    struct ListNode* pb=headB;
    int m=0,n=0;
    while(pa)
    {
        pa=pa->next;
        m ++;
    }
    while(pb)
    {
        pb=pb->next;
        n++;
    }
    int x=m-n;
    struct ListNode* a=headA;
    struct ListNode* b=headB;
    if(x>0)
    {
        while(x--)
        {
            a=a->next;
        }
        while(a)
        {
            if(a==b)
            {
                return a;
            }
            a=a->next;
            b=b->next;
        }
    }else if(x<0)
    {
        while(x++)
        {
            b=b->next;
        }
        while(b)
        {
            if(a==b)
            {
                return b;
            }
            a=a->next;
            b=b->next;
        }
    }else if(x==0)
    {
        while(a)
        {
            if(a==b)
        {
            return a;
           
        } a=a->next;
         b=b->next;
        }
        
    }
        return NULL;
    }

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

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

相关文章

天猫数据分析:2023年Q1空气净化器TOP10品牌销量排行榜

随着全球工业化程度的提高&#xff0c;全球空气污染程度仍将继续增加&#xff0c;各领域对空气净化器的需求不断增长&#xff0c;这也有望带动国内空气净化器行业的市场规模保持增长。 根据鲸参谋电商数据平台的相关数据显示&#xff0c;2023年Q1在天猫平台上&#xff0c;空气净…

02_Lock锁

首先看一下JUC的重磅武器——锁&#xff08;Lock&#xff09; 相比同步锁&#xff0c;JUC包中的Lock锁的功能更加强大&#xff0c;它提供了各种各样的锁&#xff08;公平锁&#xff0c;非公平锁&#xff0c;共享锁&#xff0c;独占锁……&#xff09;&#xff0c;所以使用起来…

shell终端敲入命令计算机都做了什么?

本文参考&#xff1a; linux命令行的运行原理是什么&#xff1f; - 知乎 (zhihu.com) 8.1 键盘敲入 A 字母时&#xff0c;操作系统期间发生了什么&#xff1f; | 小林coding (xiaolincoding.com) shell命令背后的执行过程_shell 命令执行的产生的进程_kyrieguard的博客-CSDN博客…

三维动画渲染用什么软件好?

三维渲染是通过计算机应用程序把 3D 模型生成图像&#xff08;照片级真实感或非照片级真实感&#xff09;的自动化过程&#xff0c;三维动画渲染是动画制作过程的最后一步&#xff0c;该过程将各种视觉效果应用于最终模型&#xff0c;例如阴影、纹理、灯光反射和运动模糊等&…

史上最全的接口测试,吐血整理从零到接口自动化实战...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 接口测试&#xf…

04_并发容器类

1. 重现线程不安全&#xff1a;List 首先以List作为演示对象&#xff0c;创建多个线程对List接口的常用实现类ArrayList进行add操作。 public class NotSafeDemo {public static void main(String[] args) {List<String> list new ArrayList<>();for (int i 0; i…

keil移植linux(makefile)

文章目录 运行环境&#xff1a;1.1 freeRTOS_LED工程移植1)修改cubeMX配置2)setting设置3)launch设置4)修改makefile5)修改代码6)实验效果 运行环境&#xff1a; ubuntu18.04.melodic 宏基暗影骑士笔记本 stm32f427IIH6 stlink 9-24v可调电源 robomaster A 板 1.1 freeRTOS_L…

Kubernetes集群的类似top的查看指标的工具ktop

Kubernetes集群的类似top的工具。 遵循Unix/Linux顶级工具的传统&#xff0c;ktop是一个显示有关Kubernetes集群中运行的节点、pod和其他工作负载资源的有用度量信息的工具。 项目地址&#xff1a;https://github.com/vladimirvivien/ktop使用效果图&#xff1a; 特性 集群资…

Linux如何压缩和解压文件

先看压缩 Linux zip 命令用于压缩文件。 zip 是个使用广泛的压缩程序&#xff0c;压缩后的文件后缀名为 .zip 将 /home/html/ 这个目录下所有文件和文件夹打包为当前目录下的 html.zip&#xff1a; zip -r html.zip /home/html 如果在我们在 /home/html 目录下&#xff0c;可…

经济回暖、兴趣电商升级,品牌在竞争白热化的市场中如何突围?| D3大会圆桌回顾

冬去春来&#xff0c;消费市场韧性回弹&#xff0c;消费趋势正处于“转折”和“跃升”的阶段。新的机遇和挑战也将伴随着新的思维、方法和模式&#xff0c;呈现出更多元的变化和创新&#xff1a;渠道虚实融合&#xff0c;内容为王&#xff0c;社会化媒体成为主战场等消费场景不…

13-NumPy

文章目录 一.基础1.Ndarray对象2.数据类型 二.数组1.数组属性&#xff08;1&#xff09;arange&#xff08;2&#xff09;shape&#xff08;3&#xff09;ndim&#xff08;4&#xff09;itemsize 2.创建数组&#xff08;1&#xff09;empty&#xff08;2&#xff09;zero&#…

【接口自动化测试】月薪12k必会技术,从0到1学习接口自动化测试,6个操作安排的明明白白

导读&#xff1a;在所有的开发测试中&#xff0c;接口测试是必不可少的一项。有效且覆盖完整的接口测试&#xff0c;不仅能保障新功能的开发质量&#xff0c;还能让开发在修改功能逻辑的时候有回归的能力&#xff0c;同时也是能优雅地进行重构的前提。编写接口测试要遵守哪些原…

电商直播商家崛起所面临的问题,订单管理系统起关键性作用

随着短视频直播的兴起&#xff0c;电商企业再次迎来大爆发&#xff0c;随着销量的猛增&#xff0c;随之而来的的订单处理成了各大商家的头等大事&#xff0c;面对再次崛起的电商蓝库云认为企业在订单管理会经常遇到以下问题&#xff1a; 电商企业在订单管理中可能面临以下问题…

js版计算连续12个月计算不超3万公里

<!--考虑比亚迪车友不是程序员的多&#xff0c;写了个html版的&#xff0c;复制以下代码在记事本&#xff0c;改后缀名为test.html&#xff0c;然后用浏览器打开--> <!DOCTYPE html> <html><head><meta charset"utf-8" /><title>…

基于SpringBoot3从零配置MybatisPlus

基于SpringBoot3从零配置MybatisPlus记录 文章目录 1.环境2.表数据准备3. 配置pom配置yml 配置MapperScan 3.问题总结问题1: Property sqlSessionFactory or sqlSessionTemplate are required问题2&#xff1a;org.apache.ibatis.binding.BindingException: Invalid bound stat…

Python学习13:说句心里话 A(python123)

描述 分两次从控制台接收用户的两个输入&#xff1a;第一个内容为"人名"&#xff0c;第二个内容为"心里话"。‪‬‪‬‪‬‪‬‪‬‮‬‪‬‫‬‪‬‪‬‪‬‪‬‪‬‮‬‪‬‭‬‪‬‪‬‪‬‪‬‪‬‮‬‫‬‮‬‪‬‪‬‪‬‪‬‪‬‮‬‭‬‫‬‪‬‪…

使用D435i深度相机运行ORB-SLAM3

下载安装链接 下载ORB-SLAM3地址&#xff1a; git clone https://github.com/UZ-SLAMLab/ORB_SLAM3.git eigen3多版本安装&#xff1a;https://blog.csdn.net/weixin_41756645/article/details/129570141 ORB-SLAM2中eigen3版本为&#xff1a;3.2.10版本 ORB-SLAM3中eigen3版…

【Jetpack】ViewModel + LiveData + DataBinding 综合使用 ( 核心要点说明 | 组合方式 | 代码示例 )

文章目录 一、ViewModel LiveData DataBinding 核心要点1、ViewModel 使用要点2、LiveData 使用要点3、DataBinding 使用要点 二、ViewModel LiveData DataBinding 代码示例1、ViewModel LiveData 代码2、build.gradle 构建脚本 - 启用 DataBinding3、DataBinding 布局文件…

ChatGPT实战100例 - (10) 提前体验ChatGPT的多模态绘图功能

文章目录 ChatGPT实战100例 - (10) 提前体验ChatGPT的多模态绘图功能一、需求与思路二、基本调教三、开始秀四、 总结 ChatGPT实战100例 - (10) 提前体验ChatGPT的多模态绘图功能 这个绘图其实比较基础&#xff0c;只能说是能显示个图吧 真要出图&#xff0c;隔壁 文心一言 秒杀…

如何提高三维模型OSGB格式转换3DTILES的转换速度和数据质量

如何提高三维模型OSGB格式转换3DTILES的转换速度和数据质量 提高三维模型从OSGB格式转换为3DTILES格式的转换速度和数据质量&#xff0c;可以从以下几个方面进行优化&#xff1a; 1、选用高效的转换工具&#xff1a;选择高效的转换工具是提高转换速度和数据质量的关键。目前市…