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

LeetCode 面试经典 150_链表_反转链表 II(60_92_C++_中等)(头插法)

LeetCode 面试经典 150_链表_反转链表 II(60_92_C++_中等)

    • 题目描述:
    • 输入输出样例:
    • 题解:
      • 解题思路:
        • 思路一(头插法):
      • 代码实现
        • 代码实现(思路一(头插法)):
        • 以思路一为例进行调试

题目描述:

给你单链表的头指针 head 和两个整数 left 和 right ,其中 left <= right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表

输入输出样例:

示例 1:
在这里插入图片描述

输入:head = [1,2,3,4,5], left = 2, right = 4
输出:[1,4,3,2,5]

示例 2:
输入:head = [5], left = 1, right = 1
输出:[5]

提示:
链表中节点数目为 n
1 <= n <= 500
-500 <= Node.val <= 500
1 <= left <= right <= n

题解:

解题思路:

思路一(头插法):

1、创建一个 dummyHead(伪头节点),保存链表头。

  • left 结点之前的结点无需翻转,首先定位到left位置的结点,并保存left前的一个结点信息为 pre,left结点信息为leftNode。
  • 从left位置采用头插法插入pre结点之后。直至插入到right结点。
  • 将right右侧结点连接到leftNode后

例: head = [1,2,3,4,5], left = 2, right = 4
1、定位left位置,leftNode=2,pre =1。dummyHead->1
2、从 2 开始采用头插法插入 1 之后,到right结束 ,dummyHead->1->4->3->2
3、将right右侧结点连接到leftNode后, dummyHead->1->4->3->2->5->nullptr

2、复杂度分析:
① 时间复杂度:O(n),n 代表链表中元素的个数,只遍历了一遍列表。
② 空间复杂度:O(1),使用常数个内存空间(只对源节点的next指向进行更改)。

代码实现

代码实现(思路一(头插法)):
class Solution {
public:ListNode* reverseBetween(ListNode* head, int left, int right) {// 如果链表为空,或反转区间没有变化(left == right),直接返回原链表if (!head || left == right){return head;}// 创建虚拟头节点,简化处理,指向链表的头节点ListNode *dummyHead = new ListNode(0, head);ListNode *curNode = head;  // 当前节点从链表的头开始ListNode *pre = dummyHead; // pre指向虚拟头节点// 1. 定位到反转区间的前一个节点(即位置 left-1)for (int i = 1; i < left; i++) {pre = pre->next;          // pre移到left-1位置curNode = curNode->next;  // curNode移到left位置}// 2. 保存反转区域的起始节点ListNode *leftNode = curNode;ListNode *nextNode = nullptr;  // 用于暂存当前节点的下一个节点// 3. 反转从left到right的部分for (int i = left; i <= right; i++) {nextNode = curNode->next;   // 记录当前节点的下一个节点curNode->next = pre->next;  // 当前节点指向pre->nextpre->next = curNode;        // pre->next指向当前节点curNode = nextNode;         // 当前节点移到下一个节点}// 4. 连接反转后的部分与剩余部分leftNode->next = curNode;  // 将反转区域的尾节点连接到剩余部分// 5. 返回新的链表头,虚拟头节点的next就是新链表的头ListNode *ans = dummyHead->next;// 删除虚拟头节点,避免内存泄漏delete dummyHead;return ans;  // 返回新链表的头节点}
};
以思路一为例进行调试
#include<iostream>
#include<vector>
using namespace std;struct ListNode{int val;ListNode *next;ListNode():val(0),next(nullptr){}ListNode(int x):val(x),next(nullptr){}ListNode(int x,ListNode *next):val(0),next(next){}
};//尾插法创建链表
ListNode *createList(vector<int> nums){ListNode *head=nullptr,*tail=nullptr;for (auto &num : nums){if (head==nullptr){head=tail=new ListNode(num);}else{tail->next=new ListNode(num);tail=tail->next;}}return head;
}
/** 头插法* 首先定位到left位置的结点,并保存left前的一个结点信息为 pre,left结点信息为leftNode。* 从left位置采用头插法插入pre结点之后。直至插入到right结点。* 将right右侧结点连接到leftNode后* 例子:head = [1,2,3,4,5], left = 2, right = 4* 1、定位left位置,leftNode=2,pre =1。dummyHead->1* 2、从 2 开始采用头插法插入 1 之后,到right结束 ,dummyHead->1->4->3->2* 3、将right右侧结点连接到leftNode后, dummyHead->1->4->3->2->5->nullptr* */class Solution {
public:ListNode* reverseBetween(ListNode* head, int left, int right) {// 如果链表为空,或反转区间没有变化(left == right),直接返回原链表if (!head || left == right){return head;}// 创建虚拟头节点,简化处理,指向链表的头节点ListNode *dummyHead = new ListNode(0, head);ListNode *curNode = head;  // 当前节点从链表的头开始ListNode *pre = dummyHead; // pre指向虚拟头节点// 1. 定位到反转区间的前一个节点(即位置 left-1)for (int i = 1; i < left; i++) {pre = pre->next;          // pre移到left-1位置curNode = curNode->next;  // curNode移到left位置}// 2. 保存反转区域的起始节点ListNode *leftNode = curNode;ListNode *nextNode = nullptr;  // 用于暂存当前节点的下一个节点// 3. 反转从left到right的部分for (int i = left; i <= right; i++) {nextNode = curNode->next;   // 记录当前节点的下一个节点curNode->next = pre->next;  // 当前节点指向pre->nextpre->next = curNode;        // pre->next指向当前节点curNode = nextNode;         // 当前节点移到下一个节点}// 4. 连接反转后的部分与剩余部分leftNode->next = curNode;  // 将反转区域的尾节点连接到剩余部分// 5. 返回新的链表头,虚拟头节点的next就是新链表的头ListNode *ans = dummyHead->next;// 删除虚拟头节点,避免内存泄漏delete dummyHead;return ans;  // 返回新链表的头节点}
};int main(int argc, char const *argv[])
{vector<int> nums={1,2,3,4,5};ListNode *head=createList(nums);int left=2;int right=4;//验证二叉树是否创建成功// while (head!=nullptr){//     cout<<head->val<<" ";//     head=head->next;// }Solution s;ListNode *ans = s.reverseBetween(head,left,right);while (ans!=nullptr){cout<<ans->val<<" ";ans=ans->next;}return 0;
}

LeetCode 面试经典 150_链表_反转链表 II(60_92)原题链接
欢迎大家和我沟通交流(✿◠‿◠)

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

相关文章:

  • 第 08 天:编辑器和终端快捷键 (nano, vi/vim)
  • 读取文件夹内的pdf装换成npg给vlm分类人工确认然后填入excel vlmapi速度挺快 qwen3-vl-plus webbrowser.open
  • 主流 AI IDE 之一的 CodeBuddy IDE 介绍
  • 展示型网站制作公司做网站好的网站建设公司哪家好
  • MySQL 大表查询优化、超大分页处理、SQL 慢查询优化、主键选择
  • Unity公共Mono模块:非继承脚本也能更新
  • 使用 Flownex 对发电厂周期进行建模
  • 前端基础:JS基础语法
  • 中山网站建设的企业深圳哪些公司做网站
  • 网站 验收访问的网页正在升级中
  • 29-机器学习与大模型开发数学教程-3-3 张量的运算(Einstein求和约定)
  • 天猫网站建设的优势有哪些室内装修3d动态演示效果图
  • 如何提升网站的搜索排名专业外贸网站建设公司价格
  • 【GESP】C++四级真题 luogu-B4361 [GESP202506 四级] 排序
  • 出版社类网站模板手机商城网站源码
  • 旅游网站建设实施方案湖南建筑工程集团
  • 投资融资理财网站模板如何网站专题策划
  • 淄博网站制作优化安装百度到手机桌面
  • 江苏和住房建设厅网站东莞樟木头网站建设公司
  • 内蒙古工程建设招投标中心网站网站编辑适不适合男生做
  • 网站开发的经费预算跨境电商是干嘛的
  • 高端网站定制设计公司果蔬网站规划建设方案
  • 网站开发怎么接入支付宝app管理系统
  • 如何查看网站权重百度下载安装app
  • 甜点网站要怎么做温州网页设计培训学校
  • 谷歌seo网站怎么做产品分类网站虚拟空间购买
  • wordpress全站伪静态电商网站合作
  • 寿光公司做网站wordpress 建网站 vpn
  • 小说阅读网站开发设计做网站的好处和坏处
  • 钓鱼网站制作天门网站