本次题目
206 反转链表
- (1)双指针法:不用定义一个新的链表,直接反转链表的指针指向。定义右指针(快指针)从头结点开始,指向要改变指针方向的节点,左指针(慢指针)从null开始,为右指针指向节点修改后的方向。两个指针依次向前移动,然后改变方向,直到右指针为null,左指针指向新的头结点(即原来链表中最后一个节点)。
- 注意:改变右指针节点时需要先用临时指针将前进方向的下一个节点保存下来。
class Solution {
public ListNode reverseList(ListNode head) {
ListNode left = null;
ListNode right = head;
ListNode tmp = null;
while(right != null){
tmp = right.next;
right.next = left;
left = right;
right = tmp;
}
return left;
}
}
- (2)递归:同双指针,注意:第一次输入递归函数的值为初始化值。
class Solution {
public ListNode reverseList(ListNode head) {
return resverse(null, head);
}
public ListNode resverse(ListNode left, ListNode right){
if(right == null){
return left;
}
ListNode tmp = null;
tmp = right.next;
right.next = left;
left = right;
right = tmp;
return resverse(left,right);
}
}
- (3)从后向前递归
- 注意:递归调用在函数中间,递归时先不断调用,直到找到最后节点,返回时反序。
class Solution {
public static ListNode reverseList(ListNode head) {
if(head == null) return null;
if (head.next == null) return head;
ListNode last = reverseList(head.next);
head.next.next = head;
head.next = null;
return last;
}
}
24 两两交换链表中的节点
- 可以使用虚拟头结点,不用每次针对头结点单独处理。
- 明确处理步骤:使用虚拟头结点指向头结点,此时需要交换此时的头结点1和头结点指向的下一个节点2,
- 将虚拟头结点指向2;
- 将2指向1;
- 将1指向2原来指向的下一个节点,在1之前先存为临时指针。
- 然后将虚拟头结点和头结点都向前一位,循环以上步骤,循环结束条件为头结点指向的下一个节点为最后一个节点或者头结点为最后一个节点。
- 注意循环中需要重新定义节点等于虚拟头结点开始循环。
- 递归:同上。可以debug看递归流程。
class Solution {
public static ListNode swapPairs(ListNode head) {
ListNode virtualHead = new ListNode(0);
virtualHead.next = head;
ListNode pre = virtualHead;
while(pre.next != null && head.next != null){
ListNode tmp = head.next.next;
pre.next = head.next;
head.next.next = head;
head.next = tmp;
pre = head;
head = head.next;
}
return virtualHead.next;
}
}