LeetCode206.反转链表
一、迭代
定义一个ListNode变量记录上一个节点的信息,一次遍历过程中用于让下一个节点的next指向上一个节点
public ListNode reverseList(ListNode head) {
ListNode prev = null;
ListNode curr = head;
while(curr != null){
//先获取当前节点的下一个节点,避免丢失
ListNode temp = curr.next;
curr.next = prev;
prev = curr;
curr = temp;
}
return prev;
}
二、递归
1->2->3->4->5->null
假设当递归进行到3时:1->2->3->4<-5
此时翻转代码应为 3.next.next = 3,翻转完成1->2->3<-4<-5
public ListNode reverseList(ListNode head) {
if(head == null || head.next == null){
return head;
}
ListNode newNode = reverseList(head.next);
head.next.next = head;
//最终节点1的next为null否则会出现环,对其余节点无影响
head.next = null;
//返回的始终是翻转后的起始节点,此题中为节点5
return newNode;
}
进阶
LeetCode92、反转链表Ⅱ
思路:先找到开始反转的节点的前一个节点,然后根据right-left进行相应次数的反转,方法和上面一样
public ListNode reverseBetween(ListNode head, int left, int right) {
ListNode node = new ListNode(-1);
node.next = head;
ListNode pre = node;
for(int i = 0; i < left - 1; i++){
//第一个反转节点的前一节点
pre = pre.next;
}
ListNode curr = pre.next;
ListNode before = null;
for(int i = 0; i <= right - left; i++){
//反转节点
ListNode temp = curr.next;
curr.next = before;
before = curr;
curr = temp;
}
//循环结束后,curr为最后一个反转节点的下一个节点,before为最后一个反转节点
//见下图
pre.next.next = curr;
pre.next = before;
return node.next;
}
方法二:LeetCode官方解答
public ListNode reverseBetween(ListNode head, int left, int right) {
// 设置 dummyNode 是这一类问题的一般做法
ListNode dummyNode = new ListNode(-1);
dummyNode.next = head;
ListNode pre = dummyNode;
for (int i = 0; i < left - 1; i++) {
pre = pre.next;
}
ListNode cur = pre.next;
ListNode next;
for (int i = 0; i < right - left; i++) {
next = cur.next;
cur.next = next.next;
next.next = pre.next;
pre.next = next;
}
return dummyNode.next;
}