链表的反转II

题目

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

来源:力扣(LeetCode)
链接:link

解题思路

首先我们先分析题目,这道题类似于链表的反转,只不过设定了反转的范围,所以解题思路一个是我认为难点在于:

  1. 链表的反转
  2. 特殊情况的处理(比如m=1)
  3. 链表的连接

首先我们先来分析第一个问题,这里涉及到单链表的反转,参考一篇文章:link
自己总结如下:

  1. 第一种方法:
    设置一个头节点 start并初始化为NULL,然后从原链表的头部一个一个取节点并插入到新链表的头部,具体代码如下:
ListNode* change(ListNode* head){
ListNode* start = NULL;
ListNode* p=head; //p指针为工作节点
ListNode* temp;//保存下一个节点
while(p!=NULL)
     {
            tmp = p -> next;
            p -> next = newh;//将节点插入到头节点
            newh = p;//然后设置新的头节点为新插入的节点
            p = tmp;//重新设置工作节点p
        }
        return newh;
}
  1. 第二种方法:
    每次都将原第一个结点之后的那个结点放在新的表头后面
    ListNode* ReverseList(ListNode* head) {
        if(head == NULL)
            return head;

        ListNode *res,*first,*temp;
        res = new ListNode(-1);//设置新的头节点
        res->next = head;

        first = res->next;       //first 始终为第一个结点,不断后移,res为新表头
        while(first->next!=NULL) 
            {
            temp = first->next;
            first->next = temp->next;
            //将头节点放在新表头的后面
            temp->next = res->next;
            res->next = temp;          
        }

        return res->next;
    }

对于第二个难点,特殊情况的处理:

  1. 当m==n时,证明没有要反转的链表,直接返回
  2. 当m=1时,会出现的问题是:我们会直接跳过头节点(因为使用了node=node->next),所以我们设置一个哑节点(这个思想是从分割链表中得到的),然后设置哑节点的next指向头节点

对于链表的连接,主要在于:前面的链表和反转链表的连接,反转链表和后面未反转的链表的连接

所以具体整个代码如下:

class Solution {
public:
    ListNode* reverseBetween(ListNode* head, int m, int n) {
        if (m == n) //如果两者相等,直接返回头节点
			return head;
		if (head == NULL)
			return NULL;
		int i = 1;
		ListNode emp(0); //设置哑节点
		emp.next = head;
		ListNode* node = &emp;
		ListNode* Head=NULL;//反转链表的头节点
		ListNode* first,*end;
		ListNode* temp=NULL;
		while (i < m ) {
			node = node->next;
			i++;
		}
		first=end = node->next;  //假设不设置哑节点,则会直接跳过头节点
		i = 0;
		//进行链表的反转,用的是第一种方法
		while (i <= n - m) {
			temp = first->next;
			first->next = Head;
			Head = first;
			first = temp;
			i++;
		}
		end->next = temp; //这里连接的是反转链表和后面未反转链表的连接
		node->next = Head;
		return emp.next;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值