题目:
Reverse a linked list from position m to n. Do it in one-pass.
Note: 1 ≤ m ≤ n ≤ length of list.
Example:
Input: 1->2->3->4->5->NULL, m = 2, n = 4 Output: 1->4->3->2->5->NULL
反转链表中的一部分,比反转整个链表要复杂。自己写了个巨丑无比的还很难懂的,变量名也起的乱七八糟,但思路应该挺直观的,就是先遍历到要反转的部分,第一个for loop里的begin已经是要反转的第二个节点了,beginPrev才是真正的起点,还需要一个变量来存前面不动的就是beginPrevPrev。然后遍历要反转的部分,思路跟普通reverse相同,就是存后一个节点,当前的next指向前一个。for loop结束以后,begin指向的就是后面不需要动的那部分,beginPrev就是要reverse的最后一个节点,于是我们要把beginPrevPrev后面接上beginPrev,并把需要reverse的第一个点(也就是第二次遍历之前的beginPrev,用另一个变量存起来先)后面接上begin。这里遇到了个坑,就是如何解决beginPrevPrev为null,也就是要从第一个节点开始反转的问题,直接把head指向beginPrev就好了。总之是真的复杂。
Runtime: 0 ms, faster than 100.00% of Java online submissions for Reverse Linked List II.
Memory Usage: 36.7 MB, less than 16.27% of Java online submissions for Reverse Linked List II.
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode reverseBetween(ListNode head, int m, int n) {
ListNode begin = head;
ListNode beginPrev = null;
ListNode beginPrevPrev = null;
for (int i = 0; i < m; i++) {
beginPrevPrev = beginPrev;
beginPrev = begin;
begin = begin.next;
}
ListNode reverseLast = beginPrev;
for (int i = 0; i < n - m; i++) {
ListNode temp = begin.next;
begin.next = beginPrev;
beginPrev = begin;
begin = temp;
}
if (beginPrevPrev == null) {
head = beginPrev;
} else {
beginPrevPrev.next = beginPrev;
}
reverseLast.next = begin;
return head;
}
}
看了眼solutions里的解法,代码写的比我的优雅,但思路其实是一样的,不可避免的最后处理null的问题也一样。
Runtime: 0 ms, faster than 100.00% of Java online submissions for Reverse Linked List II.
Memory Usage: 36.8 MB, less than 16.27% of Java online submissions for Reverse Linked List II.
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode reverseBetween(ListNode head, int m, int n) {
if (head == null) {
return null;
}
ListNode curr = head;
ListNode prev = null;
while (m > 1) {
prev = curr;
curr = curr.next;
m--;
n--;
}
ListNode reverseStart = curr;
ListNode beginPrev = prev;
while (n != 0) {
ListNode temp = curr.next;
curr.next = prev;
prev = curr;
curr = temp;
n--;
}
if (beginPrev == null) {
head = prev;
} else {
beginPrev.next = prev;
}
reverseStart.next = curr;
return head;
}
}
recursion解法看在他是一道medium并且我没时间的份上,就先不写了……