leetcode刷题/链表 92. 反转链表 II(0ms,图解)

92. 反转链表 II

题意:

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

示例 1:

img

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

示例 2:

输入:head = [5], left = 1, right = 1
输出:[5]
解题思路:

沿用三指针的反转,判断left和right的位置来决定类型.需要额外两个节点来暂存left节点z)和left节点的前驱(p_z)

  1. left在左边界且right在右边界,全部反转;
  2. left在左边界但right不在右边界::左边节点需要指向后续链表的节点,头节点移到最后一个节点;
  3. left不在左边界但right在右边界::让z节点指向空,p_z指向反转的最后一个节点;
  4. 均不在边界::前驱节点指向最后一个节点,z指向后续链表节点;
思路图:

leetcode刷题/链表 92. 反转链表 II(0ms,图解)_第1张图片

代码:
/**
 * 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* reverseBetween(ListNode* head, int left, int right) {
    if(head->next == nullptr)
        return head;
	int count = right - left;
	int loop = left - 1;
	ListNode *p = head;
	ListNode *p_z = p;
	while (loop--)
	{
		p_z = p;
		p = p->next;
	}
    if(p == nullptr || p->next == nullptr)
        return head;
	ListNode *z = p;
	ListNode *s = p->next;
	ListNode *tmp = s->next;
	while (s != nullptr && count--)
	{
		s->next = p;
		p = s;
		s = tmp;
		if(s!=nullptr)
			tmp = s->next;
	}
	if (--left != 0 && s != nullptr)
	{
		z->next = s;
		p_z->next = p;
	}
	else if(left == 0 && s != nullptr)
	{
		z->next = s;
		head = p;
	}
	else if (left != 0 && s == nullptr)
	{
		p_z->next = p;
		z->next = nullptr;
	}
	else if (left == 0 && s == nullptr)
	{
		head = p;
		p_z->next = nullptr;
	}
        
    return head;
    }
};
运行结果:

运行结果

总结:

用了大量的空间来换取时间,如果left和right不在边界就不需要遍历链表,只需要修改其中一部分.不过这样会有点绕,容易造成死循环.

你可能感兴趣的:(leetcode刷题/链表篇,leetcode,数据结构,链表,算法,c++)