反转部分单向链表
reverse-linked-list-ii
http://www.nowcoder.com/questionTerminal/b58434e200a648c589ca2063f1faf58c
1. 分析
此题存在换头的可能。
- 先判断m、n是否合法,不合法则直接返回head。需要计算list length,过程中同时确定m-1(即mPre)和n+1(nNext)的位置。
- 循环反转m-n部分,先把m.next=nNext确定,而mPre.next需要反转结束后,根据m是否为头作不同选择。
- 如果m为头,则直接换头,否则mPre.next = n。
2. 代码
public class Solution { public ListNode reverseBetween(ListNode head, int m, int n) { //计算length,同时把mPre和nNext找到出来 ListNode tmp = head; ListNode mPre = null; ListNode nNext = null; int len = 0; for(; tmp!=null; tmp = tmp.next){ len = len+1; if(len == m -1) mPre = tmp; if(len == n + 1) nNext = tmp; } //判断1<=m <= n <= length if(m > n || m < 1 || n > len) return head; //先把m-n反转,再设置mPre nNext的连接 //三个辅助指针用于反转 ListNode node1 = (mPre == null)?head : mPre.next;//指向m ListNode node2 = node1.next; ListNode node3 = null; node1.next = nNext;//m的next指向n的next //开始反转 while(node2 != nNext){ node3 = node2.next; node2.next = node1; node1 = node2; node2 = node3; }//循环结束,node1指向n //判断是否换头,根据m是否为head if(mPre == null){ return node1; }else{ mPre.next = node1; return head; } } }
3. 复杂度
空间:O(1)
时间: O(n)