反转链表 II
解题思路
反转链表,首先我简单回忆了一下递归逆置链表的算法,大概有些忘了,但是稍微调整一下好像可以了。
递归逆置链表的算法思想是:根据链表一直往下next,这样可以找到最后的那个结点。这个结点也就是新的首元结点。用一个变量记录下来。
然后往上回溯,回溯的过程不停的 返回首元结点,然后更改链接方向即可。
先贴出来反转链表的代码
public ListNode reverseListNode(ListNode head){
if(head == null || head.next == null){
return head;
}
ListNode newHead = reverseListNode1(head.next); //一直向下递归,找到最后一个结点作为新的头结点
head.next.next = head; //head记录每一层的上一个结点,利用这个关系 向上回溯更改链接关系
head.next = null; //注意更改
return newHead;
}
然后考虑这道题的思路
- 通过一次遍历,截取需要反转的区间,记录区间两头的结点
- 然后调用反转链表的方法(需要稍微修改些,进行反转)
- 成功反转后首尾链接
注意:为了方便(减少出错机会,我们可以新建一个头结点myHead)
/**
* 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 || head.next == null){
return head;
}
ListNode startNode,endNode,p,myTail;
ListNode myHead = new ListNode(0);
myHead.next = head;
myTail = p = myHead;
startNode = endNode = myHead;
int idx = 0;
while( idx <=n && p!=null){
if(idx == m-1){
startNode = p.next;
myTail = p;
}else if(idx == n){
endNode = p;
}
idx++;
p = p.next;
}
myTail.next = null; //断开链表 myHead ---- myTail 是首段
endNode = endNode.next;
ListNode newNode = reverseListNode(startNode,endNode);
myTail.next = newNode;
startNode.next = endNode;
return myHead.next;
}
public ListNode reverseListNode(ListNode head,ListNode endNode){
if(head == endNode || head.next == endNode){
return head;
}
ListNode newHead = reverseListNode(head.next,endNode);
head.next.next = head;
head.next = null;
return newHead;
}
}