★题目:反转部分单向链表
给定一个单项链表的头结点head,以及两个整数from和to,
在单项链表上把第from个节点到第to个节点这一部分进行反转。
例如:1->2->3->4->5->null,from=2,to=5 结果为1->4->3->2->5->null
再如:1->2->3->null,from=1,to=3 结果为3->2->1->null
要求:①时间复杂度要求为O(N),空间复杂度要求O(1)
②日过不满足1<=from<=to<=N,则不用调整
分析:判断满足1≤from小于等于to≤n
找到from-1个结点fPer和to+1个结点tPer
翻转fPer和tPer中间的部分,然后正确连接fPer和tPer
若fPer为nullptr,说明翻转部分包括头结点,返回新的头结点,否则返回旧的头结点
1->2->3->4->5(3,4)链表拆解过程为
1->2->3->5 4->5
1->2->3->5 4->3
1->2 3->5 4->3
1->2->4->3->5
void resersePart(Node *&head, int from, int to)
{
int len = 0;
Node *cur = head;
Node *fPre = nullptr;
Node *tPos = nullptr;
//计算链表长度,from的前一个位置fPre,to的后一个位置tPre
while (cur != nullptr)
{
len++;
fPre = len == from - 1 ? cur : fPre;
tPos = len == to + 1 ? cur : tPos;
cur = cur->next;
}
//不满足1≤from≤to≤N
if (from > to || from < 1 || to >len)
{
return;
}
//fPre为空ze证明要翻转的部分包含头结点
cur = fPre == nullptr ? head : fPre->next;
//要翻转部分与右边相连
Node *leftNode = tPos;
Node *rightNode = cur->next;
//翻转
while (cur->next != tPos)
{
rightNode = cur->next;
cur->next = leftNode;
leftNode = cur;
cur = rightNode;
}
cur->next = leftNode;
//翻转部分与左部分相连
if (fPre != nullptr)
{
fPre->next = cur;
}
//若翻转部分包含头结点,从新定义头结点
else
{
head = cur;
}
}