反转从位置 m 到 n 的链表

题目是在LeetCode上遇到的,自己在做的时候坑点一大堆,请先认真审题!!!

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

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

示例:

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

关键词:一趟扫描  1 ≤ m ≤ n ≤ 链表长度

一趟扫描 意味着在遍历这个链表节点的过程中保留一些关键节点的指针,

比如假如存在的话,m位置前一个节点和n位置之后的节点

1 <=m<=n<=链表长度: 提醒我们在做这道题时考虑好所有的特殊情况

1=m, m=n, n=链表长度

算法思想:

1. 预处理特殊情况,把单节点链表和m=n的情况直接返回链表头,因为这两种情况下链表和原来一样

2.此时处理2个节点以上(包括两个节点)同时n>m的情况

(1) 将指针p转移到链表的第m个节点,pre保存m前一个节点

(2)接下来是反转操作,reverse_head,reverse_tail,reverse_tail_after分别存储反转链表的头部,尾部节点,尾部节点后一个节点(可能为NULL)

(3)建立头部和反转部分的连接

(4)接下来建立反转部分和尾部的连接

具体代码:

 

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
struct ListNode* reverseBetween(struct ListNode* head, int m, int n) {
  //预处理特殊情况
  if (!head || !head->next || n == m) return head;
    //将p转移到链表的第m个节点,pre保存m前一个节点
    struct ListNode* pre = NULL;
    struct ListNode* p = head;
    int temp_m = m;
    while (temp_m-- > 1) {
	pre = p;
	p = p->next;
    }
    //接下来是反转操作,reverse_head,reverse_tail,reverse_tail_after分别存储反转链表的头部,尾部节点,尾部节点后一个节点(可能为NULL),为了之后的连接
    struct ListNode* reverse_head = NULL;
    struct ListNode* reverse_tail = p;
    struct ListNode* reverse_tail_after = NULL;
    struct ListNode* q = NULL;
    int temp_n = n;
    while (temp_n - m > 0) {
    	q = p->next;
    	reverse_tail_after = q->next;
    	p->next = reverse_head;
	reverse_head = p;
	p = q;
	temp_n--;
    }

    p->next = reverse_head;
    reverse_head = p;
    //接下来建立头部和反转部分的连接
    if (m == 1) {
	//反转链表的head就是链表的head
	head = reverse_head;
    }
    else {
	//用pre将正序头部和反转链表连接
	pre->next = reverse_head;
    }
    //接下来建立反转部分和尾部的连接
    if (reverse_tail_after) {
	reverse_tail->next = reverse_tail_after;
    }
    return head;
}

感觉关键就是考虑好很多特殊情况。

写的比较粗糙,欢迎各位评论并提出意见,大家分享一下自己的idea总是好的~

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值