当前位置: 首页 > news >正文

【初阶数据结构】顺序表和链表算法题(下)

链表

  • 2.链表
    • 2.4合并两个有序链表
    • 2.5链表分割
    • 2.6链表的回⽂结构
    • 2.7相交链表
    • 2.8环形链表I
    • 2.9 环形链表II
    • 2.10随机链表的复制

2.链表

2.4合并两个有序链表

在这里插入图片描述
思路
在这里插入图片描述

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/
typedef struct ListNode ListNode;
ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {//处理链表为空的情况if (list1 == NULL)return list2;if (list2 == NULL)return list1;//方一代码:创建新的空链表ListNode* newhead = NULL, * newtail = NULL;//list1,list2分别指向两个链表的表头//newhead = newtail = (ListNode*)malloc(sizeof(ListNode));while (list1 && list2)//只要有一个条件不满足就跳出循环{if (list1->val < list2->val){//谁小谁尾插if (newhead == NULL){newhead = newtail = list1;}else{newtail->next = list1;newhead = newtail->next;}list1 = list1->next;}else{//l2尾插if (newhead == NULL){newhead = newhead = list2;}else{newtail->next = list2;newtail = newtail->next;}list2 = list2->next;}}//跳出循环只有两种情况,list1为空或list2为空if (list1){newtail->next = list1;}if (list2){newtail->next = list2;}return newhead;
}
//方二代码:创建一个非空链表
typedef struct ListNode ListNode;
struct ListNode* mergeTwoLists(struct ListNode* list1, struct ListNode* list2) {//申请一个动态的空间//此时初始了一个头结点,是个默认的值,最后删掉ListNode* newhead, * newtail;newhead = newtail = (ListNode*)malloc(sizeof(ListNode));while (list1 && list2){//不用判断链表是否为空,直接拿过来尾插if (list1->val < list2->val){newtail->next = list1;list1 = list1->next;}else{newtail->next = list2;list2 = list2->next;}newtail = newtail->next;}if (list1){newtail->next = list1;}else{newtail->next = list2;}ListNode* ret = newhead->next;free(newhead);newhead = NUll;return ret;
}

2.5链表分割

在这里插入图片描述
思路
在这里插入图片描述

单链表算法题----链表分割
牛客是c++写的
/*
struct ListNode {int val;struct ListNode *next;ListNode(int x) : val(x), next(NULL) {}
};*/
class Partition {
public:ListNode* partition(ListNode* pHead, int x) {// write code hereif (pHead == NULL)return NULL;//创建两个非空链表,小链表和大struct ListNode* lessHead, * lessTail, * greaterHead, * greaterTail;//创建链表表头//注意:我动态开辟空间后 lesshead链表和greathead链表头就有一个默认结点啦lessHead = lessTail = (struct ListNode*)malloc(sizeof(struct ListNode));greaterHead = greaterTail = (struct ListNode*)malloc(sizeof(struct ListNode));//遍历原链表,找小于x的和其它节点尾插导大小链表中struct ListNode* cur = pHead;while (cur){//小于x的尾插到lessTailif (cur->val < x){lessTail->next = cur;lessTail = lessTail->next;}//大于等于x的尾插到greaterTailelse{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;}
};

2.6链表的回⽂结构

在这里插入图片描述
思路
在这里插入图片描述

单链表算法题----链表的回⽂结构
/*
struct ListNode {int val;struct ListNode *next;ListNode(int x) : val(x), next(NULL) {}
};*/
class PalindromeList {
public:bool chkPalindrome(ListNode* A) {// write code hereif (A == NULL || A->next == NULL)return true;ListNode* slow, * fast, * prev, * cur, * nxt;slow = fast = A;//1.找到中间节点while (fast && fast->next){slow = slow->next;fast = fast->next->next;}//此时slow为中间结点 //后半部分逆置(反转链表)prev = NULL;cur = slow;while (cur){nxt = cur->next;cur->next = prev;prev = cur;cur = nxt;}//逐点比对while (A && prev)//此时prev为最后一个结点{if (A->val != prev->val)return false;A = A->next;prev = prev->next;}return true;}
};

2.7相交链表

在这里插入图片描述
思路

在这里插入图片描述

单链表算法题----相交链表
/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/typedef struct ListNode ListNode;
struct ListNode* getIntersectionNode(struct ListNode* headA, struct ListNode* headB) {ListNode* p1 = headA;ListNode* p2 = headB;int sizeA, sizeB;sizeA = sizeB = 0;while (p1) {sizeA++;p1 = p1->next;}while (p2) {sizeB++;p2 = p2->next;}//求绝对值int gap = abs(sizeA - sizeB);//让长链表先走gap步ListNode* longlist = headA;ListNode* shortlist = headB;if (sizeA < sizeB){longlist = headB;shortlist = headA;}while (gap--){longlist = longlist->next;}//此时,longlist和shortlist在同一起跑线//两种情况  相交,不相交while (longlist && shortlist){if (longlist == shortlist){//链表相交return shortlist;}//继续往后走longlist = longlist->next;shortlist = shortlist->next;}//都走到为空了,链表不相交return NULL;
}

在这里插入图片描述

2.8环形链表I

在这里插入图片描述
思路证明见下篇
在这里插入图片描述
在这里插入图片描述

单链表算法题----环形链表I
//判断是否带环
//判断是否相遇,环形链表2下个题是找相遇点
/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/
//走两步
typedef struct ListNode ListNode;
bool hasCycle(struct ListNode* head) {//快慢指针ListNode* slow, * fast;slow = fast = head;while (fast && fast->next){slow = slow->next;fast = fast->next->next;if (slow == fast){return true;}}//两个指针始终没有相遇return false;
}
//走三步
typedef struct ListNode ListNode;
bool hasCycle(struct ListNode* head) {//快慢指针ListNode* slow, * fast;slow = fast = head;while (fast && fast->next){slow = slow->next;int n = 3;//fast每次⾛三步while (n--)//进去3次{if (fast->next)fast = fast->next;else//不带环return false;}if (slow == fast){return true;}}//两个指针没有相遇return false;
}

2.9 环形链表II

在这里插入图片描述
结论
让⼀个指针(pcur)从链表起始位置开始遍历链表,同时让⼀个指针(next)从判环时相遇点(meet)的位置开始绕环运⾏,两个指针都是每次均走⼀步,最终肯定会在入口点的位置相遇。

第一步,找环的相遇点
第二步,从头结点和相遇点开始遍历,每次都走一步
第三步,当pcur和meet相遇时,即入口点

单链表算法题----环形链表II
//先运用找相遇点代码
/*** Definition for singly-linked list.* struct ListNode {*     int val;*     struct ListNode *next;* };*/
typedef struct ListNode ListNode;
ListNode* FindNode(ListNode* head)
{ListNode* fast, * slow;slow = fast = head;while (fast && fast->next){slow = slow->next;fast = fast->next->next;if (slow == fast)return slow;//相遇了}return NULL;
}
struct ListNode* detectCycle(struct ListNode* head) {//找环的相遇点ListNode* meet = FindNode(head);//从头结点和相遇点开始遍历,每次都走一步ListNode* pcur = head;while (meet && pcur){//当pcur和meet相遇时,即入口点if (meet == pcur)return meet;meet = meet->next;pcur = pcur->next;}//链表不带环return NULL;
}

2.10随机链表的复制

在这里插入图片描述
在这里插入图片描述
思路

第一步,在原链表基础上继续复制链表
第二步,置random指针,copy->random=pcur->random->next
第三步,复制链表与原链表断开
在这里插入图片描述
`

`附上几张图便于理解

在这里插入图片描述
第三步的时候 下图
在这里插入图片描述

单链表算法题----随机链表的复制
/*** Definition for a Node.* struct Node {*     int val;*     struct Node *next;*     struct Node *random;* };*/typedef struct Node Node;
Node* BuyNode(int x)
{Node* newnode = (Node*)malloc(sizeof(Node));newnode->val = x;newnode->next = newnode->random = NULL;return newnode;
}
//原链表传过来,复制链表
void AddNode(Node* phead)
{Node* pcur = phead;while (pcur){Node* ret = pcur->next;//创建新节点,尾插到pcur Node* newnode = BuyNode(pcur->val);pcur->next = newnode;newnode->next = ret;pcur = ret;}
}
struct Node* copyRandomList(struct Node* head) {if (head == NULL)return NULL;//第一步AddNode(head);//第二步Node* copy, * pcur, * p1, * newhead, * newtail;pcur = head;newhead = newtail = pcur->next;p1 = pcur;while (pcur){copy = pcur->next;if (pcur->random != NULL){//如果为空,copy->random本来就是null,不用再改了copy->random = pcur->random->next;}pcur = copy->next;}//第三步//让pcur再回到头结点,所以有了p1while (p1->next->next){p1 = p1->next->next;newtail->next = p1->next;newtail = newtail->next;}return newhead;
}
``更多链表算法刷题⼊⼝:
⽜客⽹:https://www.nowcoder.com/exam/oj
LeetCode:https://leetcode.cn/problems/copy-list-with-random-pointer/description/

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 图像处理中的对抗性研究:浅谈水印去除技术
  • Golang学习笔记-Golang中的锁
  • Linux上安装Conda以管理Python环境
  • F - Rook on Grid 矩阵 侧面视角 树状数组
  • 《Python 关键概念全解析:可迭代对象、迭代器、生成器与装饰器》
  • 一个简单的springboot项目(有源码)
  • Nginx负载均衡中静态与动态内容分离策略与实践
  • 工厂模式与策略模式的区别?
  • 强化学习,第 5 部分:时间差异学习
  • 2、AI测试辅助-需求分析
  • 【数学建模】国赛论文写作教学——问题重述与分析
  • CST如何仿真Coverage Efficiency和Coverage Threshold
  • 第15届蓝桥杯青少组Scratch初级组省赛真题试卷
  • Figma 替代品 Penpot 安装和使用教程
  • 【Python系列】Jinja2 模板引擎
  • JavaScript 如何正确处理 Unicode 编码问题!
  • 【个人向】《HTTP图解》阅后小结
  • 07.Android之多媒体问题
  • js中forEach回调同异步问题
  • PAT A1092
  • Python中eval与exec的使用及区别
  • seaborn 安装成功 + ImportError: DLL load failed: 找不到指定的模块 问题解决
  • vuex 笔记整理
  • Wamp集成环境 添加PHP的新版本
  • 从零搭建Koa2 Server
  • 如何使用Mybatis第三方插件--PageHelper实现分页操作
  • 掌握面试——弹出框的实现(一道题中包含布局/js设计模式)
  • ​LeetCode解法汇总518. 零钱兑换 II
  • # 执行时间 统计mysql_一文说尽 MySQL 优化原理
  • $.ajax()参数及用法
  • (Git) gitignore基础使用
  • (pojstep1.1.1)poj 1298(直叙式模拟)
  • (Python第六天)文件处理
  • (分布式缓存)Redis持久化
  • (附源码)计算机毕业设计SSM基于健身房管理系统
  • (附源码)小程序 交通违法举报系统 毕业设计 242045
  • (剑指Offer)面试题34:丑数
  • (牛客腾讯思维编程题)编码编码分组打印下标(java 版本+ C版本)
  • (一) springboot详细介绍
  • (最完美)小米手机6X的Usb调试模式在哪里打开的流程
  • .bat文件调用java类的main方法
  • .net流程开发平台的一些难点(1)
  • @ 代码随想录算法训练营第8周(C语言)|Day57(动态规划)
  • [20170728]oracle保留字.txt
  • [24年新算法]NRBO-XGBoost回归+交叉验证基于牛顿拉夫逊优化算法-XGBoost多变量回归预测
  • [30期] 我的学习方法
  • [CF703D]Mishka and Interesting sum/[BZOJ5476]位运算
  • [codevs] 1029 遍历问题
  • [dfs搜索寻找矩阵中最长递减序列]魔法森林的秘密路径
  • [ERROR] Plugin 'InnoDB' init function returned error
  • [GN] 后端接口已经写好 初次布局前端需要的操作(例)
  • [HITCON 2017]SSRFme 1
  • [iphone-cocos2d]关于Loading的若干处理和讨论
  • [json]定义、读写
  • [Jsprit]Jsprit学习笔记-一个简单的示例