Given the head
of a singly linked list and two integers left
and right
where left <= right
, reverse the nodes of the list from position left
to position right
, and return the reversed list.
Example 1:
Input: head = [1,2,3,4,5], left = 2, right = 4 Output: [1,4,3,2,5]
Example 2:
Input: head = [5], left = 1, right = 1 Output: [5]
Constraints:
- The number of nodes in the list is
n
. 1 <= n <= 500
-500 <= Node.val <= 500
1 <= left <= right <= n
Follow up: Could you do it in one pass?
反转链表II。
也是不会做,会写homebrew也枉然的题目,但是非常容易错。题意是给一个链表和两个数字m和n,请反转m和n之间的node,只能走一次。
这题我借助了一个图,非得看着图做才行。
/*1 -> 2 -> 3 -> 4 -> 5guard p next*/
思路是头插法。我参考了一个很好的图示。照着例子跑一下吧。假设需要反转的部分是从2到4,反转的顺序是先把3拿出来插入1和2中间,然后再把4插入1和3中间,像这样。guard永远是需要反转的部分之前的一个节点,像个守卫一样不能动!p是需要反转的部分的第一个节点。
1 -> 2 -> 3 -> 4 -> 5
1 -> 3 -> 2 -> 4 -> 5
1 -> 4 -> 3 -> 2 -> 5
时间O(n)
空间O(1)
JavaScript实现
1 /** 2 * @param {ListNode} head 3 * @param {number} m 4 * @param {number} n 5 * @return {ListNode} 6 */ 7 var reverseBetween = function(head, m, n) { 8 let dummy = new ListNode(0); 9 dummy.next = head; 10 let pre = dummy; 11 let cur = dummy.next; 12 for (let i = 1; i < m; i++) { 13 cur = cur.next; 14 pre = pre.next; 15 } 16 for (let i = 0; i < n - m; i++) { 17 let temp = cur.next; 18 cur.next = temp.next; 19 temp.next = pre.next; 20 pre.next = temp; 21 } 22 return dummy.next; 23 };
Java实现
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ class Solution { public ListNode reverseBetween(ListNode head, int m, int n) { // corner case if (head == null) { return null; } // normal case ListNode dummy = new ListNode(0); dummy.next = head; ListNode pre = dummy; for (int i = 1; i < m; i++) { pre = pre.next; } ListNode cur = pre.next; for (int i = 0; i < n - m; i++) { ListNode next = cur.next; cur.next = next.next; next.next = pre.next; pre.next = next; } return dummy.next; } }
相关题目