要求:

反转从位置 m 到 n 的链表。请使用一趟扫描完成反转。

说明:
1 ≤ m ≤ n ≤ 链表长度。

示例:

输入: 1->2->3->4->5->NULL, m = 2, n = 4
输出: 1->4->3->2->5->NULL

方法迭代链接反转

算法

在看具体算法之前,有必要先弄清楚链接反转的原理以及需要哪些指针。举例而言,有一个三个不同结点组成的链表 A → B → C,需要反转结点中的链接成为 A ← B ← C。

假设我们有两个指针,一个指向结点 A,一个指向结点 B。 分别记为 prev 和 cur。则可以用这两个指针简单地实现 A 和 B 之间的链接反转:

cur.next = prev
这样做唯一的问题是,没有办法继续下去,换而言之,这样做之后就无法再访问到结点 C。因此,我们需要引入第三个指针,用于帮助反转过程的进行。因此,我们不采用上面的反转方法,而是:

third = cur.next
cur.next = prev
prev = cur
cur = third
迭代 地进行上述过程,即可完成问题的要求。下面来看看算法的步骤。

1.如上所述,我们需要两个指针 prev 和 cur。
2.prev 指针初始化为 None,cur 指针初始化为链表的 head。
3.一步步地向前推进 cur 指针,prev 指针跟随其后。
4.如此推进两个指针,直到 cur 指针到达从链表头起的第 mm 个结点。这就是我们反转链表的起始位置。
5.注意我们要引入两个额外指针,分别称为 tail 和 con。tail 指针指向从链表头起的第mm个结点,此结点是反转后链表的尾部,故称为 tail。con 指针指向第 mm 个结点的前一个结点,此结点是新链表的头部。下图可以帮助你更好的理解这两个指针。

6.tail 和 con 指针在算法开始时被初始化,在算法最后被调用,用于完成链表反转。
7.如前文所解释的那样,抵达第 mm 个结点后,在用到上述两个指针前,先迭代地反转链接。不断迭代,直到完成指向第 nn 个结点的链接。此时,prev 指针会指向第 nn 个结点。
8.我们使用 con 指针来连接 prev 指针,这是因为 prev 指针当前指向的结点(第 nn 个结点)会代替第 mm 个结点的位置。 类似地,我们利用 tail 指针来连接 prev 指针之后的结点(第 n+1n+1 个结点)。
为了便于理清每个指针的用法,我们来看一个算法运行的实例。给定一个链表 7 → 9 → 2 → 10 → 1 → 8 → 6,我们需要反转从第 3 个结点到第 6 个结点的子链表

从上图可以看到迭代法的前几步。第一步展示了两个指针的初始化,第三步展示了链表反转过程的初始位置。

上图详细显示了链接反转的过程以及反转两个结点的链接后如何向前移动。如下图所示,本步骤将执行多次。

如上图所示, 两个指针都已经到达最终位置。我们完成了子链表的反转工作。然而,还有一些链接需要调整。下图展示了利用 tail 和 con 指针完成链接调整的过程。

以上链接:https://leetcode-cn.com/problems/reverse-linked-list-ii/solution/fan-zhuan-lian-biao-ii-by-leetcode/

 Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
typedef struct ListNode * PNODE ;
typedef struct ListNode NODE ;
struct ListNode* reverseBetween(struct ListNode* phead, int m, int n){
    PNODE prev=NULL ;
    PNODE curr=phead;
    PNODE temp=NULL ;
    PNODE con =NULL ;
    PNODE tail=NULL ;
   if(phead==NULL)
   {
        return NULL ;
   }
   while(m>1)
   {
    prev=curr;
    curr=curr->next;
    m-- ;
    n-- ;
   }
   con=prev ;
   tail=curr ;
   while(n>0)
   {
    temp=curr->next;
    curr->next=prev;
    prev=curr;
    curr=temp;
    n--;
   }
   //调整算法连接
   if(con!=NULL)
   {
    con->next=prev ;
   }
   else
   {
    phead=prev ;
   }
   tail->next=curr ;
   return phead ;
}

C语言实现反转链表 II(指定2个节点反转)的更多相关文章

  1. 【1】【leetcode-92】 反转链表 II

    (没过,以为简单,结构链表指针搞得很复杂出错.是有捷径的,很典型题目要记住) 反转链表 II(medium) 反转从位置 m 到 n 的链表.请使用一趟扫描完成反转. 说明:1 ≤ m ≤ n ≤ 链 ...

  2. LeetCode 92. 反转链表 II(Reverse Linked List II)

    92. 反转链表 II 92. Reverse Linked List II 题目描述 反转从位置 m 到 n 的链表.请使用一趟扫描完成反转. 说明: 1 ≤ m ≤ n ≤ 链表长度. LeetC ...

  3. Java实现 LeetCode 92 反转链表 II

    92. 反转链表 II 反转从位置 m 到 n 的链表.请使用一趟扫描完成反转. 说明: 1 ≤ m ≤ n ≤ 链表长度. 示例: 输入: 1->2->3->4->5-> ...

  4. 力扣 - 92. 反转链表II

    目录 题目 思路1(迭代) 代码 复杂度分析 思路2(递归) 代码 复杂度分析 题目 92. 反转链表 II 思路1(迭代) 将反转链表分成3个部分:前一段未反转的部分.待反转链表部分.后一段未反转部 ...

  5. 【python】Leetcode每日一题-反转链表 II

    [python]Leetcode每日一题-反转链表 II [题目描述] 给你单链表的头节点 head 和两个整数 left 和 right ,其中 left <= right .请你反转从位置 ...

  6. 92.反转链表II

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

  7. leetcode 206. 反转链表 及 92. 反转链表 II

    206. 反转链表 问题描述 反转一个单链表. 示例: 输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1-> ...

  8. 【Leetcode链表】反转链表 II(92)

    题目 反转从位置 m 到 n 的链表.请使用一趟扫描完成反转. 说明: 1 ≤ m ≤ n ≤ 链表长度. 示例: 输入: 1->2->3->4->5->NULL, m ...

  9. [LeetCode题解]92. 反转链表 II | 一次遍历 + 反转

    解题思路 将链表分为三部分:[0, m).[m, n].(n, L],其中 L 为链表长度. 第一步:使用虚拟头节点 dummy,用于将 head 也能参与操作: 第二步:找到第 m-1 节点(fir ...

随机推荐

  1. django项目中使用KindEditor富文本编辑器

    先从官网下载插件,放在static文件下 前端引入 <script type="text/javascript" src="/static/back/kindedi ...

  2. VFP CursorAdapter 起步三(作者:Doug Hennig 译者:fbilo)

    可重用数据类 VFP 的程序员们想要一个可重用的数据类已经很久了.尽管在过去的版本中也有许多解决这个问题的办法,不过总是有点美中不足.现在在 VFP 8里,我们有了真正的可重用数据类.这个月,Doug ...

  3. python 读取域名信息

    #!/usr/bin/env python # _*_coding:utf-8_*_ import OpenSSL from OpenSSL import crypto from dateutil i ...

  4. jmeter与jdk的安装

    1.第一步:下载jdk的安装包 下载链接: http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151 ...

  5. 【HDU - 1176 】免费馅饼 (逆dp)

    免费馅饼  Descriptions: 都说天上不会掉馅饼,但有一天gameboy正走在回家的小径上,忽然天上掉下大把大把的馅饼.说来gameboy的人品实在是太好了,这馅饼别处都不掉,就掉落在他身旁 ...

  6. MySql学习-4.查询1

    1.基本查询语法: select * from 表名: **注意** 1.select 后写列名,*代表是所有列:        2.列名可以用as起别名,其出现在结果集中: 3.查询多个列,之间用逗 ...

  7. mssql sqlserver 如何将一个日期数据转换为"年份-月份"的格式呢?

    摘要: 下文讲述在sqlserver数据库中,将日期数据转换为指定格式的方法分享,如下所示: 实验环境:sqlserver 2008 R2 实现思路: 实现方法1: 使用year函数和month函数获 ...

  8. 详细讲解Codeforces Round #624 (Div. 3) F. Moving Points

    题意:给定n个点的初始坐标x和速度v(保证n个点的初始坐标互不相同), d(i,j)是第i个和第j个点之间任意某个时刻的最小距离,求出n个点中任意一对点的d(i,j)的总和. 题解:可以理解,两个点中 ...

  9. go 序列化

    序列化 package main import ( "encoding/json" "fmt" ) //结构体 type Monster struct { Na ...

  10. modbus 协议说明及常用格式

    --- 说明: modbus协议一般适用于一个主设备访问多个从设备的硬件开发环境,类似于zigbee网络中的一个路由器多个协调器的一对多模型. modbus常用的寄存器类型为 3X 保持寄存器和 4X ...