前言
力扣第二十四题 两两交换链表中的节点
如下所示:
给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
示例 1:
输入:head = [1,2,3,4]
输出:[2,1,4,3]
示例 2:
输入:head = []
输出:[]
示例 3:
输入:head = [1]
输出:[1]
一、思路
既然要置换链表中的两两节点,很简单的思路就是从左至右遍历这个链表,只要碰到两个节点就交换。
上面的这种遍历的形式,其实也可以通过递归来实现链表中的相邻节点交换。具体的步骤如下所示:
假设如下:
head:初始化指向原链表首节点
temp:临时变量
- 如果 head 指向的链表没有两个节点,则直接返回 head
- temp = head.next,指向head后面的一个节点
- 开始递归 temp.next(因为前两个元素已处理过了,所以这里需要开始处理第三个元素)
- temp.next = head,再temp.next指向将处理过后的head
举个例子:
假设链表为 1->2->3->4->5
head
开始指向1
(1->2->3->4->5)temp
指向2
,(2->3->4->5)- 递归处理
temp.next
,即处理3->4->5,最终递归的返回结果为 4->3->5 - 将递归的结果给
head.next
,即head仍未1,但整个链表变为了 1->4->3->5 - 再将
temp.next = head.next
,即temp指向的链表变为了 2->1->4->->5
二、实现
如上面思路所说,共有两种方案来实现。迭代和递归,我认为迭代比较好理解,递归更需要明确什么时候开始递归。
迭代
实现代码
变量说明
ret:结果集
temp:临时变量,用于保存交换时的结果
tips:因为初始化时ret的首节点为null,所以返回结果时需要返回 ret.next
/**
* 迭代
*
*/
public ListNode swapPairs(ListNode head) {
ListNode ret = new ListNode();
ListNode temp = ret;
while (head != null) {
if (head.next != null) {
temp.next = new ListNode(head.next.val);
temp = temp.next;
temp.next = new ListNode(head.val);
temp = temp.next;
head = head.next.next;
} else {
// 没有两个元素的话,将当前值放到最后即可
temp.next = new ListNode(head.val);
break;
}
}
return ret.next;
}
测试代码
public static void main(String[] args) {
new Number24().swapPairs(new ListNode(1, new ListNode(2,
new ListNode(3, new ListNode(4, new ListNode(5))))));
}
结果
递归
实现代码
变量说明
temp:临时变量
/**
* 官方推荐:递归
*/
public ListNode swapPairs(ListNode head) {
// 终止条件:当前节点为空或者没有next
if (head == null || head.next == null) {
return head;
}
ListNode temp = head.next;
head.next = swapPairs(temp.next);
temp.next = head;
return temp;
}
结果
三、总结
不禁感慨,递归写起来也太爽了!
感谢看到最后,非常荣幸能够帮助到你~♥