您的位置:首页 > 其它

【LeetCode】92. Reverse Linked List II 解题报告

2017-03-28 09:42 429 查看
转载请注明出处:http://blog.csdn.net/crazy1235/article/details/67632059

Subject

出处:https://leetcode.com/problems/reverse-linked-list-ii/

Reverse a linked list from position m to n. Do it in-place and in one-pass.

For example:

Given 1->2->3->4->5->NULL, m = 2 and n = 4,

return 1->4->3->2->5->NULL.

Note:

Given m, n satisfy the following condition:

1 ≤ m ≤ n ≤ length of list.

Explain

反转链表中第m 到 第n 个结点

解决方案就是通过链表反转的方式,将m-n个结点反转,然后在拼接之前后之后的结点。

重点就是记录第m个结点的前驱结点和第n个结点的后续结点。


链表反转的方法可参考:

http://blog.csdn.net/crazy1235/article/details/66971177

Solution

solution 1

还是通过栈的方式反转,然后拼接

/**
* 使用stack
*
* Runtime : 1ms
*
* beats 2.94% of java submissions
*
* @param head
* @param m
* @param n
* @return
*/
public ListNode reverseBetween(ListNode head, int m, int n) {
if (head == null || head.next == null || m >= n) {
return head;
}

ListNode dummyNode = new ListNode(0);
dummyNode.next = head;
head = dummyNode;

ListNode preNode = head; // pre node

for (int i = 1; i < m; i++) {
preNode = preNode.next;
}

// ----

ListNode tempNode = preNode.next;

Stack<ListNode> stack = new Stack<>();
int i = 0;
while (m + i <= n) {
stack.push(tempNode);
tempNode = tempNode.next;
i++;
}

ListNode postNode = tempNode; // post node

ListNode resultNode = stack.pop();
tempNode = resultNode;

while (!stack.isEmpty()) {
tempNode.next = stack.pop();
tempNode = tempNode.next;
}

//
preNode.next = resultNode;
tempNode.next = postNode;

return dummyNode.next;
}


solution 2

通过迭代方式

/**
* 通过迭代方式反转m-n的结点
*
* Runtime : 0ms
*
* beats 18.23% of java submissions
*
* @param head
* @param m
* @param n
* @return
*/
public ListNode reverseBetween2(ListNode head, int m, int n) {
if (head == null || head.next == null || m >= n) {
return head;
}

ListNode dummyNode = new ListNode(0);
dummyNode.next = head;
head = dummyNode;

ListNode preNode = head; // pre node

for (int i = 1; i < m; i++) {
preNode = preNode.next;
}

// iteration

ListNode nodeA = preNode.next;
ListNode nodeB = preNode.next.next;
ListNode nodeResult = nodeA;

int i = 0;
while (m + i < n) {
nodeA.next = nodeB.next;
nodeB.next = nodeResult;
nodeResult = nodeB;
nodeB = nodeA.next;
i++;
}

//
preNode.next = nodeResult;

return dummyNode.next;
}


此方法中不需要拼接第n个结点后面的结点,因为while循环之后,n后面的结点依旧是拼接完好的。

此方法还可以优化,省去nodeResult变量,将其替换为preNode.

/**
* 方法二的优化方式
*
* @param head
* @param m
* @param n
* @return
*/
public ListNode reverseBetween3(ListNode head, int m, int n) {
if (head == null || head.next == null || m >= n) {
return head;
}

ListNode dummyNode = new ListNode(0);
dummyNode.next = head;
head = dummyNode;

ListNode preNode = head; // pre node

for (int i = 1; i < m; i++) {
preNode = preNode.next;
}

ListNode nodeA = preNode.next;
ListNode nodeB = preNode.next.next;

for (int i = 0; i < n - m; i++) {
nodeA.next = nodeB.next;
nodeB.next = preNode.next;
preNode.next = nodeB;
nodeB = nodeA.next;
}

return dummyNode.next;
}


Github :

https://github.com/crazy1235/BaseJavaProject/blob/master/BaseJavaProject/src/com/jacksen/java/leetcode/ReverseLinkedListII.java

bingo~~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: