描述
翻转链表中第m个节点到第n个节点的部分
m,n满足1 ≤ m ≤ n ≤ 链表长度
您在真实的面试中是否遇到过这个题? 是
样例
给出链表1->2->3->4->5->null, m = 2 和n = 4,返回1->4->3->2->5->null
挑战
翻转链表中第m个节点到第n个节点的部分
m,n满足1 ≤ m ≤ n ≤ 链表长度
您在真实的面试中是否遇到过这个题? 是
样例
给出链表1->2->3->4->5->null, m = 2 和n = 4,返回1->4->3->2->5->null
挑战
在原地一次翻转完成
分析
in-place翻转。首先找到所制定的区间(端点),然后翻转区间,最后实施重连。不需要额外的空间。
创建dummy node,记下head;提醒一下,如果是C++,为了避免内存泄漏,创建dummy node时最好不要用ListNode *dummy = new ListNode(0),而是创建结构体:ListNode dummy(0),最后通过dummy.next返回。
通过一次遍历,找到第m个节点mth,第m个节点的前一个节点mth_prev,第n个节点,第n个节点的后一个节点nth_next。
翻转指定区间的链表段(同翻转整个链表的方法)。一种方法是,先nth->next=NULL,然后调用Reverse Linked List的方法,输入为mth。
重新连接链表。这时指定区间的链表已经反向,把mth_prev与nth相连,mth与nth_next相连。
程序
/**
* Definition of singly-linked-list:
* class ListNode {
* public:
* int val;
* ListNode *next;
* ListNode(int val) {
* this->val = val;
* this->next = NULL;
* }
* }
*/
class Solution {
public:
/**
* @param head: ListNode head is the head of the linked list
* @param m: An integer
* @param n: An integer
* @return: The head of the reversed ListNode
*/
void * reverse(ListNode * head) {
ListNode * prev = NULL;
while(head != NULL){
//保证下一个节点不断
ListNode * tmp = head->next;
//当前的指针指向前一个节点。刚开始时前一个节点为空
head->next = prev;
//改头换面,重新来
prev = head;
head = tmp;
}
}
ListNode * reverseBetween(ListNode * head, int m, int n) {
// write your code here
if(!head->next) return head;
ListNode dummp(0);
dummp.next = head;
ListNode *mth_prev = &dummp, *mth, *nth, *nth_next;
for(int i = 1; i < n; i++){
if(i == m - 1) mth_prev = head;//头结点已经给dummp,所以不需要head
head = head->next;
}
//生成一个独立的链表
mth = mth_prev->next;
mth_prev->next = NULL;
nth = head;
nth_next = nth->next;
nth->next = NULL;
//翻转
reverse(mth);
//重新连接
mth_prev->next = nth;
mth->next = nth_next;
return dummp.next;
}
};