题目:给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
示例 1:
输入:head = [1,2,3,4] 输出:[2,1,4,3]
示例 2:
输入:head = [] 输出:[]
示例 3:
输入:head = [1] 输出:[1]
第一种解题思路+代码:(迭代方法)
代码:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode swapPairs(ListNode head) {
/**
思路:
1.判断该链表是否为空或者单结点链表,是直接返回
2.创建一个辅助指针temp,指向当前要交换的节点的前一个节点,交换节点后指针后移
4.最后返回两两节点交换数据后的链表
*/
if(head == null || head.next == null){
return head;
}
//虚拟头节点
ListNode list = new ListNode(0);
list.next = head;
//创建辅助指针
ListNode temp = list;
while(head != null && head.next != null){
//当前节点 和 下一个节点
ListNode node = head;
ListNode downNode = head.next;
//节点交换
temp.next = downNode;
node.next = downNode.next;
downNode.next = node;
//指针后移
temp = node;
head = node.next;
}
return list.next;
}
}
第二种解题思路+代码:(栈的后进先出) 引用力扣(作者昵称:王尼玛 题解:https://leetcode.cn/problems/swap-nodes-in-pairs/solutions/41485/dong-hua-yan-shi-24-liang-liang-jiao-huan-lian-bia/)
代码:
class Solution {
public ListNode swapPairs(ListNode head) {
if(head==null || head.next==null) {
return head;
}
//用stack保存每次迭代的两个节点
Stack<ListNode> stack = new Stack<ListNode>();
ListNode p = new ListNode(-1);
ListNode cur = head;
//head指向新的p节点,函数结束时返回head.next即可
head = p;
while(cur!=null && cur.next!=null) {
//将两个节点放入stack中
stack.add(cur);
stack.add(cur.next);
//当前节点往前走两步
cur = cur.next.next;
//从stack中弹出两个节点,然后用p节点指向新弹出的两个节点
p.next = stack.pop();
p = p.next;
p.next = stack.pop();
p = p.next;
}
//注意边界条件,当链表长度是奇数时,cur就不为空
if(cur!=null) {
p.next = cur;
} else {
p.next = null;
}
return head.next;
}
}
总结:解答这道题我使用的是迭代方法来两两交换链表中的节点,需要通过辅助指针来指向当前要交换节点的前一个节点,然后逐一交换,这里也是解答题目最容易出错的地方。在解答完这道题后,我看到题解中大佬的解法是利用栈的后进先出(先存入两个数,取出;再存入两个数,再取出),按照该栈的存取可以很快得到两两节点交换后的链表。相对于迭代方法交换而言,利用栈的存取会更加逻辑清晰,简单高效。