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

网站建设 服务器编写网站方案设计书表格

网站建设 服务器,编写网站方案设计书表格,阿里巴巴国际站运营,微信h5商城网站目录链表常用的技巧和操作1、常用技巧2、常用操作一、[两数相加](https://leetcode.cn/problems/add-two-numbers/description/)二、[两两交换链表中的节点](https://leetcode.cn/problems/swap-nodes-in-pairs/description/)三、[重排链表](https://leetcode.cn/problems/reor…

在这里插入图片描述

目录

  • 链表常用的技巧和操作
    • 1、常用技巧
    • 2、常用操作
  • 一、[两数相加](https://leetcode.cn/problems/add-two-numbers/description/)
  • 二、[两两交换链表中的节点](https://leetcode.cn/problems/swap-nodes-in-pairs/description/)
  • 三、[重排链表](https://leetcode.cn/problems/reorder-list/description/)
  • 四、[合并 K 个升序链表](https://leetcode.cn/problems/merge-k-sorted-lists/description/)
  • 五、[K 个一组翻转链表](https://leetcode.cn/problems/reverse-nodes-in-k-group/description/)
  • 结尾

链表常用的技巧和操作

1、常用技巧

  1. 画图

  2. 引入虚拟头结点

    • 便于我们处理边界情况
    • 方便我们对链表进行操作
  3. 不要吝啬空间,大胆定义变量
    相信我们在上学期间学习过数据结构的同学都很熟悉,给你两个节点,使用双向链接将其链接起来,但是只给你一个节点的地址,要求你在两个节点之间插入一个新节点,大家可能都被链接的顺序恶心过,但是只要定义一个变量记录另一个节点的地址,那么我们想怎么链接就怎么链接了。

  4. 快慢双指针

2、常用操作

  1. 创建一个新节点
  2. 头插
  3. 尾插

一、两数相加

题目描述
在这里插入图片描述

思路讲解
本道题只需要模拟两数相加的过程即可,首先定义一个虚拟头结点,这样就不需要对链表进行特殊处理,然后定义两个变量分别记录对应位上两数相加的个位和进位,创建一个节点存储个位上的数字,尾插到虚拟头结点所在的链表中,然后同时将两个原始链表向后同时移动,重复上面的操作,直到两个链表都遍历完后返回以虚拟头结点后面一个节点为头结点的链表即完成本题。

需要注意两数相加时还要加上进位,若是某个链表对应位上没有节点,我们认定这个节点上的数字为0。

编写代码

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     ListNode *next;*     ListNode() : val(0), next(nullptr) {}*     ListNode(int x) : val(x), next(nullptr) {}*     ListNode(int x, ListNode *next) : val(x), next(next) {}* };*/
class Solution {
public:ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {int add = 0;ListNode* newhead = new ListNode();ListNode* cur = newhead;while(l1 || l2 || add){int num1 = (l1 != nullptr) ? l1->val : 0;int num2 = (l2 != nullptr) ? l2->val : 0;int sum = num1 + num2 + add;ListNode* newNode = new ListNode(sum % 10);cur->next = newNode;cur = cur->next;add = sum / 10;if(l1 != nullptr)   l1 = l1->next;if(l2 != nullptr)   l2 = l2->next;}return newhead->next;}
};

二、两两交换链表中的节点

题目描述
在这里插入图片描述

思路讲解
本道题我们需要做的就是将链表中每两个节点进行交互即可,我们只需要模拟如何将节点进行交换即可。若链表中只有一个节点时,不需要进行交换,返回即可。

这里我创建一个虚拟头结点用来避免对链表第一次交换进行特殊处理,通过画图我们发现,看似是对两个节点进行交换,实际上却涉及到了四个节点,为了我们方便处理,直接定义四个指针分别指向四个连续的节点,有了这四个指针就可以很方便的将两个节点进行交换了,如下图,我们只需要修改prve、cur和next指向节点中next的指向即可,修改完指向后就需要指针向后移动了,各个指针移动后对应的位置在下图中有明确的标识,有些指针移动后位置比较特殊,需要特殊判断。

在这里插入图片描述

然后就是循环的判断条件了,这里我们将链表分类奇数节点个数和偶数节点个数来看,如图,奇数情况下只要next没有指向节点就结束,偶数情况下cur没有指向节点就结束,综上只要cur或next有一个没有指向节点就结束循环。最后返回以虚拟头结点后面一个节点为头结点的链表即完成本题。
在这里插入图片描述

编写代码

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     ListNode *next;*     ListNode() : val(0), next(nullptr) {}*     ListNode(int x) : val(x), next(nullptr) {}*     ListNode(int x, ListNode *next) : val(x), next(next) {}* };*/
class Solution {
public:ListNode* swapPairs(ListNode* head) {if(head == nullptr || head ->next == nullptr)return head;ListNode* newhead = new ListNode();ListNode* prev = newhead ,*cur = head ;ListNode* next = head->next , *nnext = next->next;while(cur != nullptr && next != nullptr){prev->next = next;next->next = cur;cur->next = nnext;prev = cur;cur = nnext;if(cur)next = cur->next;if(next)nnext = next->next;}return newhead->next;}
};

三、重排链表

题目描述
在这里插入图片描述

思路讲解

本道题是让我们将链表重新排序,并且不能只修改节点的值,而是要进行节点之间的切换,我们看了题目的示例,可以得出重排链表,实际上是重复拿出原链表中的头节点和尾节点,并将尾节点链接到头节点的后面,然后按照拿出来的顺序进行链接,即可完成对链表的重排。

本题还有一个更简单的思路,就是将这个链表从中间分开变为两个链表,使前面链表的节点个数比后面的链接节点个数多一个或是相等,然后将后面这个链表逆转,最后通过两个链表的合并即可完成链表的重排。

编写代码

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     ListNode *next;*     ListNode() : val(0), next(nullptr) {}*     ListNode(int x) : val(x), next(nullptr) {}*     ListNode(int x, ListNode *next) : val(x), next(next) {}* };*/
class Solution {
public:void reorderList(ListNode* head) {if(head->next == nullptr)return;ListNode* slow = head , *fast = head -> next;while(fast && fast->next){slow = slow->next;fast = fast->next->next;}// 从中间截断为两段链表ListNode* newhead1 = new ListNode();ListNode* cur = slow -> next;slow->next = nullptr;ListNode* next = cur->next;// 逆置后半段链表cur->next = nullptr;while(cur){cur->next = newhead1->next;newhead1 -> next = cur;cur = next;if(next)next = next -> next;}ListNode* cur1 = head ,*cur2 = newhead1->next;ListNode* next1 = head->next ,*next2 = cur2->next;ListNode* newhead2 = new ListNode();cur = newhead2;while(cur2){// 依次插入两个链表cur -> next = cur1;cur1 = next1;if(next1)next1 = next1->next;cur = cur -> next;cur -> next = cur2;cur2 = next2;if(next2)next2 = next2->next;cur = cur -> next;}// 第一段链表一定与第二段链表等长或更长if(cur1)cur->next = cur1;head = newhead2;}
};

四、合并 K 个升序链表

题目描述
在这里插入图片描述

思路讲解
本道题是想让我们将k个升序链表,按照节点的大小合并为1个升序链表,这里我们一定能想到的就是暴力解法,每次遍历所以链表的头节点,找到最小的节点并取出,再将这个节点链入到新链表中,重复这样的操作,直到k个链表中没有任何节点位置,最后返回新链表即可完成本道题,这样完成本道题的时间复杂度为O(nk2^22)。

这里可以使用优先级队列进行优化,我们创建一个小堆,将所有链表的头节点放入小堆中,小堆根据节点的大小将最小的节点移动到堆顶,这样我们就可以通过找到堆顶元素就可以找到k个链表中头节点中最小的节点了,将该节点从堆中和它所对应的链表中取出,并将它所对应链表中的新头节点放入到堆中,若没有节点则不需加入,小堆则会按照它的特性将堆中的节点重新调整,然后将取出来的节点链接到新的链表中,重复这样的操作直到堆中没有任何节点为止,最后将新链表返回即可完成合并 K 个升序链表。

编写代码

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     ListNode *next;*     ListNode() : val(0), next(nullptr) {}*     ListNode(int x) : val(x), next(nullptr) {}*     ListNode(int x, ListNode *next) : val(x), next(next) {}* };*/
class Solution {
public:ListNode* mergeKLists(vector<ListNode*>& lists) {int count = lists.size(); // 链表的个数ListNode* newhead = new ListNode();ListNode* last = newhead;// 记录链表中有节点的链表个数int ListCount = 0;while(1){int MinPos = 0;int min = 10001;for(int i = 0 ; i < count; i++){ListNode* cur = lists[i];if(cur){   ListCount++;if(min > cur->val){min = cur->val;MinPos = i;}}}// 当链表所有链表都没有节点时跳出循环if(ListCount == 0)break;last->next = lists[MinPos];// 插入到新的链表中last = last -> next;if(lists[MinPos])lists[MinPos] = lists[MinPos]->next;MinPos = 0 , ListCount = 0;}return newhead->next;}
};

五、K 个一组翻转链表

题目描述
在这里插入图片描述

思路讲解
本道题想让我们将链表中每k个节点进行翻转,若剩下的节点小于k个则保持愿意。

这里可以使用模拟的思路解决本题,我们先遍历整个链表,得到链表中节点的个数为num,有每k个节点需要翻转一次,通过num/k得到有count组子链表需要翻转。循环count次,每次记录该组子链表的前一个节点和后一个节点,将本组k个节点进行逆序,再链接回原链表中,这里可以使用头插法的方式将链表进行逆序,最后返回链表的头结点即可。

编写代码

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     ListNode *next;*     ListNode() : val(0), next(nullptr) {}*     ListNode(int x) : val(x), next(nullptr) {}*     ListNode(int x, ListNode *next) : val(x), next(next) {}* };*/
class Solution {
public:ListNode* reverseKGroup(ListNode* head, int k) {int numNode = 0;  // 节点个数ListNode* cur = head;while(cur){numNode++;cur = cur->next;}int opCount = numNode / k;  // 记录需要翻转的次数ListNode* newhead = new ListNode();   // 创建哨兵位头结点newhead->next = head;ListNode* prev = newhead; // 标记每k个节点的前一个节点,方便链接cur = head;ListNode* connect = cur; // 旋转k个节点后的最后一个节点,方便链接ListNode* next = cur->next; while(opCount--){connect = cur;for(int i = 1 ; i <= k ; i++){cur->next = prev->next;prev->next = cur;cur = next;if(next)next = next->next;}// 记录前一段的尾prev = connect;}prev->next = cur;return newhead->next;}
};

结尾

如果有什么建议和疑问,或是有什么错误,大家可以在评论区中提出。
希望大家以后也能和我一起进步!!🌹🌹
如果这篇文章对你有用的话,希望大家给一个三连支持一下!!🌹🌹

在这里插入图片描述

http://www.dtcms.com/a/509691.html

相关文章:

  • 做房产应看的网站福田做网站
  • 新能源汽车价格趋势麦当劳的网站优化建议
  • 网站建设与管理vs2010安徽科技学院
  • 搭建网站的步骤免费网络电视app
  • 河南中州路桥建设有限公司网站两学一做登录网站
  • 青海建设厅网站黑名单企业简介画册
  • 自己做的网站可以用于百度推广吗宁波网站制作联系方式
  • wordpress 整站音乐嘉兴网站设计
  • 学校网站设计图片wordpress 跳转小程序
  • 动软代码生成器 做网站怎样攻击网站
  • 网站推广基本预算wordpress本地安装插件
  • 7. 解码器层(DecoderLayer):Transformer的“目标序列生成器”
  • 网站报价页做一款app需要什么技术
  • 没有英文网站怎么做外贸只做水果的网站
  • 网站流量怎么变现呢南阳定制网站制作价格低
  • 品牌网站开发策划书曲靖网站微信建设
  • 网站开发的一次性收益做微信公众号第三网站
  • 自己做的网站上传手机做电商怎么赚钱
  • 【GESP】C++五级考试大纲知识点梳理, (5) 算法复杂度估算(多项式、对数)
  • 微商城手机网站制作公司网站设计手机版为什么那么多背景
  • 省建设厅网站安徽怎么做新网站上线通稿
  • 江西建设银行分行网站手机交互网站
  • 昌都网站建设西安找工作哪个网站好
  • 万网 网站 ip低价网站建设教程
  • 营销型网站制作培训多少钱昆明市建设局官方网站
  • 银川建设局网站温州网站制作软件
  • 自己做网站有什么意义新手如何做网站推广
  • 原创网站源码网站内容添加
  • vs2015做网站如何添加控件wordpress设置付费
  • 下载软件网站程序员40岁以后出路