反转从位置 m 到 n 的链表。请使用一趟扫描完成反转。
说明:
1 ≤ m ≤ n ≤ 链表长度。
示例:
输入: 1->2->3->4->5->NULL, m = 2, n = 4
输出: 1->4->3->2->5->NULL
解题思路:
1、构造一个dummy节点 指向头结点,为了可以在头节点指针发生变化的时候,直接用dummy->next定位到头节点,如下:
dummy->1->2->3->4->5->null
2、利用m定位到开始节点的 前一个节点。m=2时,则操作 2那个节点。则前一个 previous 节点值为1
3、规定此时 1节点为previous节点,2节点为cur_operator_node,cur_operator_node->next即3节点是temp节点
4、断开cur_operator_node和temp的连接关系,即2和3的连接, 变更cur_operator_node->next = temp->next,即为2指向4。
断开temp和temp->next的连接关系,即3和4的连接关系,变更为temp->next = previous->next,即3指向2。
断开previous和previous->next的连接关系,即1和2的连接关系,变更为 previous->next=temp,即1指向3。
至此完成了3节点逆置,新的链表如下:
dummy->1->3->2->4->5->null
5、此时1节点仍然是previous节点,2节点仍然是cur_operator_node,cur_operator_node->next即4节点是temp节点
6、按照4的步骤:
断开cur_operator_node和temp的连接关系,即2和4的连接,变更cur_operator_node->next = temp->next,即为2指向5。
断开temp和temp->next的连接关系,即4和5的连接关系,变更为temp->next = previous->next,即4指向3。
断开previous和previous->next的连接关系,即1和3的连接关系,变更为 previous->next=temp,即1指向4。
至此完成了4节点逆置,新的链表如下:
dummy->1->4->3->2->5->null
完成逆转。返回节点头即dummy->next。
即使m=1,1节点为cur_operator_node也成立,因为previous节点存在,是dummy。
代码如下:
struct node {
int value;
node* next;
};
node* reverse_with_range(node* head, int m, int n) { //1 <= m <= n <= lenght
//新增一个空节点指向链表头,防止从链表头倒转
node dummy{ -1,nullptr };
dummy.next = head;
auto previous = &dummy;
for (int i = 1; i < m; ++i) { //定位到开始节点的前一个节点
previous = previous->next;
}
auto cur_operator_node = previous->next;
for (int i = 0; i < n - m ; i++) { //range内倒转
auto temp = cur_operator_node->next;
cur_operator_node->next = temp->next;
temp->next = previous->next;
previous->next = temp;
}
return dummy.next;
}