标签:tps fir 链表 com java 理解 交换 ppa 判断
给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
示例 :
给定 1->2->3->4, 你应该返回 2->1->4->3.
我们假设链表只有三个结点,交换前两个结点。交换后,头结点应连向原来的第三个结点,第二个结点连向第一个结点,交换完成,第二个结点就是新的头结点了。但我们要先记下第二个结点,不然头结点连向了第三个结点,第二个结点就丢失了。
public ListNode swapPairs(ListNode head) {
ListNode newHead = head.next;
head.next = head.next.next;
newHead.next = head;
return newHead;
}
这样只是处理了一次,要递归处理,我们就先进入递归去处理最后面的结点,然后再一路返回。就是先把每次的第三个结点当作头结点进行处理。我们把head.next = head.next.next
改成head.next = swapPairs(head.next.next)
就可以了。
这样我们的操作其实就已经完成了,接下来就是判断递归终止的条件,两个结点以上才能交换,所以终止条件应是头结点为空,或头结点的下一结点为空。
if (head == null || head.next == null) {
return head;
}
我们先定义一个哑结点 dumb,把它与头结点相连,并定义一个 pre 结点,pre 结点始终表示当前进行交换的第一个结点的上一个结点,起始时即 dumb。
ListNode dumb = new ListNode(0), pre = dumb;
dumb.next = head;
每次遍历,我们用 first 表示这次循环要交换的两个结点的第一个,second 表示第二个。像递归那样,我们还先假设链表只有三个结点,我们先把 first 连向第三个结点,second 连向 first,此时已交换了两个结点。
ListNode first = pre.next;
ListNode second = pre.next.next;
first.next = second.next;
second.next = first;
但此时前一个结点仍然连向 first,应连回 second,交换后的 second 才是前一个结点的下一个结点。pre 结点始终表示当前进行交换的第一个结点的上一个结点,此轮的两个结点已交换,准备下一轮,pre 应更新为第三个结点的上一个结点,即 first ,因为 first 和 second 已经完成了交换,此时 first 结点就是第二个结点。
pre.next = second;
pre = first;
循环进行的条件应该是当前进行交换的两个结点均不为空,即pre.next != null && pre.next.next != null
。
最后我们应该返回的是 dumb 的下一个结点 dumb.next。
class Solution {
public ListNode swapPairs(ListNode head) {
if (head == null || head.next == null) {
return head;
}
ListNode newHead = head.next;
head.next = swapPairs(head.next.next);
newHead.next = head;
return newHead;
}
}
class Solution {
public ListNode swapPairs(ListNode head) {
ListNode dumb = new ListNode(0), pre = dumb;
dumb.next = head;
while (pre.next != null && pre.next.next != null) {
ListNode first = pre.next;
ListNode second = pre.next.next;
first.next = second.next;
second.next = first;
pre.next = second;
pre = first;
}
return dumb.next;
}
}
个人觉得递归法很好理解,反而是迭代法有点绕,不过画一下图也就清楚了。
我发现,递归结束的条件和迭代进行的条件又是刚好相反。
标签:tps fir 链表 com java 理解 交换 ppa 判断
原文地址:https://www.cnblogs.com/qiu_jiaqi/p/LeetCode_24.html