标签:
https://oj.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.
解题思路:
这题是 Reverse Nodes in k-Group 的一个子问题,但是我先做了前者。
这道题可以化解为转置一个已知头尾节点的链表,这个子问题。细节方面要注意,不能直接取到第m个节点。因为要把第m个节点的前一个节点的next指向转之后的链表,所以只能取到第m-1个节点。
因为可能m=1,也就是head以后就变成尾节点了,遇到这种情况,一般是预先声明一个dummy的节点,放在head前,最后返回dummy.next就可以了。这是一个常规的思路。
reverseList的方法里,要注意,一般已知head,tail为null的链表的转置,要借助三个指针才可以完成,当然next是可以放在循环里,也可以放在循环外的。这个问题里,tail不是null,而是一个具体的节点。特别要注意,循环终止的条件就不能是head != tail.next了,必须预先声明一个变量tailNext将其保存,再判断head != tailNext。因为tail.next最后转置了。
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { * val = x; * next = null; * } * } */ public class Solution { public ListNode reverseBetween(ListNode head, int m, int n) { ListNode dummy = new ListNode(0); dummy.next = head; ListNode traverse = dummy; //traverse从dummy开始,mNode实际上是第m个节点的前一个节点,因为要将他的next指向倒置的链表 for(int i = 1; i < m; i++){ traverse = traverse.next; } ListNode mNode = traverse; //nNode就是第n个节点 for(int i = 0; i < n - m + 1; i++){ traverse = traverse.next; } ListNode nNode = traverse; mNode.next = reverseList(mNode.next, nNode); return dummy.next; } public ListNode reverseList(ListNode head, ListNode tail){ ListNode pre = null; ListNode traverse = head; ListNode tailNext = tail.next; while(traverse != tailNext){ ListNode next = traverse.next; traverse.next = pre; pre = traverse; traverse = next; } //head此时变成尾节点,指向转置前tail的后一个节点 head.next = tailNext; return tail; } }
标签:
原文地址:http://www.cnblogs.com/NickyYe/p/4314115.html