leetcode之链表类之链表归并类-----OJ 2/21/23/445 链表相加求和 链表归并

2024-05-09 22:18

本文主要是介绍leetcode之链表类之链表归并类-----OJ 2/21/23/445 链表相加求和 链表归并,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1、OJ21两个链表合并:两个链表合并可以简单的依次比较完成。

OJ21代码:

    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {if (!l1 && !l2) {return nullptr;} else if (!l1 || !l2) {return l1?l1:l2;}ListNode *l3 = nullptr, *tail = l3;        while (l1 && l2) {int curval = (l1->val < l2->val)?l1->val:l2->val;if (l1->val < l2->val) {l1 = l1->next;} else {l2 = l2->next;}if (!l3) {l3 = new ListNode(curval);tail = l3;} else {ListNode *newnode = new ListNode(curval);tail->next = newnode;tail = newnode;}}while (l1) {int curval = l1->val;ListNode *newnode = new ListNode(curval);tail->next = newnode;tail = newnode;l1 = l1->next;}while (l2) {int curval = l2->val;ListNode *newnode = new ListNode(curval);tail->next = newnode;tail = newnode;l2 = l2->next;}return l3;}


2、OJ23多个链表合并

核心思路是:将多个链表加入到小顶堆,然后重载括号运算符重载(用于获取链表value并将较大取出,相当于比较运算符,这里要注意重载的方式),每次取出堆顶,头节点将作为新链表的当前需加入的节点。

注意:1、小顶堆的每个元素是链表,因为每个链表已经有序,且每次堆调整会把头节点更小的链表调整到堆顶,故每次从取出的堆顶链表,取其头节点放入新链表即可,

   2、然后需要把这个链表去掉头节点的部分重新放入堆,以再次调整,找到头节点更小的链表,调整到堆顶。如果该链表已空,则无需加入。

   3、这样直到全部链表都已空,即结束。

OJ23代码:

    struct cmp {bool operator() (ListNode *a, ListNode *b) {return a->val > b->val;}};ListNode* mergeKLists(vector<ListNode*>& lists) {std::priority_queue<ListNode *, vector<ListNode *>, cmp> hp;for (auto l:lists) {if (l) {hp.push(l);}}ListNode *res = nullptr, *tail = res;if (hp.empty()) {return res;}while (!hp.empty()) {ListNode *top = hp.top();hp.pop();if (!res) {res = top;tail = res;} else {tail->next = top;tail = tail->next;}if (top->next) {hp.push(top->next);}}return res;}

3、OJ2 Add Two Numbers 和 OJ445 Add Two Numbers II

首先OJ2,如同两个链表的归并排序,两个链表从头开始value相加,注意进位的处理,直到只要有一个链表为空为止,然后对可能存在的不为空的链表继续累加,注意最后如果还有进位,还要追加一个value为1的节点;

OJ2代码:

class Solution {
public:ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {        if (!l1 && !l2) {return nullptr;} else if (!l1 || !l2) {return (l1)?l1:l2;}ListNode *l3 = nullptr, *tail = nullptr;int add = 0;while (l1 && l2) {int v1 = l1->val, v2 = l2->val;int res = v1 + v2 + add;if (res >= 10) {add = 1;res = res - 10;} else {add = 0;}if (!l3) {l3 = new ListNode(res);tail = l3;} else {ListNode *newnode = new ListNode(res);tail->next = newnode;tail = newnode;}l1 = l1->next;l2 = l2->next;}while (l1) {int v = l1->val;int res = v + add;if (res >= 10) {add = 1;res = res - 10;} else {add = 0;}ListNode *newnode = new ListNode(res);tail->next = newnode;tail = newnode;l1 = l1->next;}while (l2) {int v = l2->val;int res = v + add;if (res >= 10) {add = 1;res = res - 10;} else {add = 0;}ListNode *newnode = new ListNode(res);tail->next = newnode;tail = newnode;l2 = l2->next;}if (add) {ListNode *newnode = new ListNode(1);tail->next = newnode;}return l3;}
};

对于OJ445,区别是需要先做原链表的翻转,然后再做OJ2的流程,也就是说数的顺序是反过来的

OJ445代码:

class Solution {
public:ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {if (!l1 && !l2) {return nullptr;} else if (!l1 || !l2) {return l1?l1:l2;}ListNode *cur = l1, *prev = nullptr, *next = l1->next;while (next) {ListNode *nn = next->next;next->next = cur;cur->next = prev;prev = cur;cur = next;next = nn;}ListNode *rl1 = cur;cur = l2;prev = nullptr;next = l2->next;while (next) {ListNode *nn = next->next;next->next = cur;cur->next = prev;prev = cur;cur = next;next = nn;}ListNode *rl2 = cur;ListNode *rl3 = nullptr, *tail = nullptr;int add = 0;while (rl1 && rl2) {int v = rl1->val + rl2->val + add;if (v >= 10) {add = 1;v = v - 10;} else {add = 0;}if (!rl3) {rl3 = new ListNode(v);tail = rl3;} else {ListNode *newnode = new ListNode(v);tail->next = newnode;tail = newnode;}rl1 = rl1->next;rl2 = rl2->next;}while (rl1) {int v = rl1->val + add;if (v >= 10) {add = 1;v = v - 10;} else {add = 0;}ListNode *newnode = new ListNode(v);tail->next = newnode;tail = newnode;rl1 = rl1->next;}while (rl2) {int v = rl2->val + add;if (v >= 10) {add = 1;v = v - 10;} else {add = 0;}ListNode *newnode = new ListNode(v);tail->next = newnode;tail = newnode;rl2 = rl2->next;}if (add) {tail->next = new ListNode(1);}cur = rl3;prev = nullptr;next = cur->next;while (next) {ListNode *nn = next->next;next->next = cur;cur->next = prev;prev = cur;cur = next;next = nn;}return cur;}
};


这篇关于leetcode之链表类之链表归并类-----OJ 2/21/23/445 链表相加求和 链表归并的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/974658

相关文章

哈希leetcode-1

目录 1前言 2.例题  2.1两数之和 2.2判断是否互为字符重排 2.3存在重复元素1 2.4存在重复元素2 2.5字母异位词分组 1前言 哈希表主要是适合于快速查找某个元素(O(1)) 当我们要频繁的查找某个元素,第一哈希表O(1),第二,二分O(log n) 一般可以分为语言自带的容器哈希和用数组模拟的简易哈希。 最简单的比如数组模拟字符存储,只要开26个c

csu1329(双向链表)

题意:给n个盒子,编号为1到n,四个操作:1、将x盒子移到y的左边;2、将x盒子移到y的右边;3、交换x和y盒子的位置;4、将所有的盒子反过来放。 思路分析:用双向链表解决。每个操作的时间复杂度为O(1),用数组来模拟链表,下面的代码是参考刘老师的标程写的。 代码如下: #include<iostream>#include<algorithm>#include<stdio.h>#

安卓链接正常显示,ios#符被转义%23导致链接访问404

原因分析: url中含有特殊字符 中文未编码 都有可能导致URL转换失败,所以需要对url编码处理  如下: guard let allowUrl = webUrl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else {return} 后面发现当url中有#号时,会被误伤转义为%23,导致链接无法访问

深入手撕链表

链表 分类概念单链表增尾插头插插入 删尾删头删删除 查完整实现带头不带头 双向链表初始化增尾插头插插入 删查完整代码 数组 分类 #mermaid-svg-qKD178fTiiaYeKjl {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-

leetcode-24Swap Nodes in Pairs

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode swapPairs(L

leetcode-23Merge k Sorted Lists

带头结点。 /*** Definition for singly-linked list.* public class ListNode {* int val;* ListNode next;* ListNode(int x) { val = x; }* }*/public class Solution {public ListNode mergeKLists

建立升序链表

题目1181:遍历链表 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:2744 解决:1186 题目描述: 建立一个升序链表并遍历输出。 输入: 输入的每个案例中第一行包括1个整数:n(1<=n<=1000),接下来的一行包括n个整数。 输出: 可能有多组测试数据,对于每组数据, 将n个整数建立升序链表,之后遍历链表并输出。 样例输

C++ | Leetcode C++题解之第393题UTF-8编码验证

题目: 题解: class Solution {public:static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num &

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟)

【每日一题】LeetCode 2181.合并零之间的节点(链表、模拟) 题目描述 给定一个链表,链表中的每个节点代表一个整数。链表中的整数由 0 分隔开,表示不同的区间。链表的开始和结束节点的值都为 0。任务是将每两个相邻的 0 之间的所有节点合并成一个节点,新节点的值为原区间内所有节点值的和。合并后,需要移除所有的 0,并返回修改后的链表头节点。 思路分析 初始化:创建一个虚拟头节点

C语言 | Leetcode C语言题解之第393题UTF-8编码验证

题目: 题解: static const int MASK1 = 1 << 7;static const int MASK2 = (1 << 7) + (1 << 6);bool isValid(int num) {return (num & MASK2) == MASK1;}int getBytes(int num) {if ((num & MASK1) == 0) {return