递归解法
递归写法要观察本级递归的解决过程,形成抽象模型,因为递归本质就是不断重复相同的事情。而不是去思考完整的调用栈,一级又一级,无从下手,应该关注一级调用小单元的情况,也就是单个f(x)。
其中我们应该关心的主要有三点:
-
返回值
-
调用单元做了什么
-
终止条件
要注意终止条件:head为空(没有结点了)或者head.next为空(只剩一个结点了,不用再换了)
head是函数传进来的参数,head随着递归的过程中,每次传进来的都是不一样的。(是second.next
代码如下:
class Solution {
public ListNode swapPairs(ListNode head) {
if(head == null||head.next == null){
return head;
}
ListNode first = head;
ListNode second = head.next;
first.next = swapPairs(second.next);
second.next = first;
return second;
}
}
时间复杂度:O(N),其中 N 指的是链表的节点数量。
空间复杂度:O(N),递归过程使用的堆栈空间。
迭代
这是第三次用到哑结点了,哑结点真的会省去很多判断
至于为什么prev=first,这个要仔细看题目描述,21已经换过一次了,13不用再换了,直接换34
class Solution {
public ListNode swapPairs(ListNode head) {
ListNode dummy = new ListNode(-1);
dummy.next = head;
ListNode prev = dummy;
while (head != null && head.next != null){
ListNode first = head;
ListNode second = head.next;
prev.next = second;
first.next = second.next;
second.next = first;
prev = first;
head = first.next;
}
return dummy.next;
}
}
时间复杂度:O(N),其中 N 指的是链表的节点数量。
空间复杂度:O(1)