两两交换链表中的节点
题目链接:https://leetcode.cn/problems/swap-nodes-in-pairs/description/?envType=study-plan-v2&envId=top-100-liked
我的解答:
public ListNode swapPairs(ListNode head) { if(head==null||head.next==null){ return head; } ListNode dummy = new ListNode(-1,head); ListNode pre=dummy; ListNode left=head, right=head.next; while(right!=null){ left.next=right.next; right.next=left; pre.next=right; pre=left; left=left.next; if(left!=null){ right=left.next; } else{ right=null; } } return dummy.next; }分析:代码的时间复杂度为O(n),空间复杂度为O(1)。解题思路:在链表头节点添加一个哑节点,避免单独处理边界情况。使用三个指针,left和right为当前交换的一对左右节点,pre为当前交换的一对节点的前置节点。每次先将左右节点进行交换,然后更改前置节点的下一个节点,移动时先移动pre,再移动left和right。
看了官方题解后的解答:
//方法一:递归 //实践复杂度:O(n) //空间复杂度:O(n) public ListNode swapPairs(ListNode head) { if(head==null||head.next==null){ return head; } ListNode newHead=head.next; head.next=swapPairs(newHead.next); newHead.next=head; return newHead; } //方法二:迭代 //实践复杂度:O(n) //空间复杂度:O(1) public ListNode swapPairs(ListNode head) { ListNode dummyHead = new ListNode(-1,head); ListNode pre=dummyHead; ListNode node1, node2; while(pre.next!=null&&pre.next.next!=null){ node1=pre.next; node2=pre.next.next; node1.next=node2.next; node2.next=node1; pre.next=node2; pre=node1; } return dummyHead.next; }分析:
1、方法一采用递归。链表节点两两一组进行交换,若一组节点不足两个,则不用交换直接返回。不断递归交换每一组节点,每一次递归交换完成后返回新的头节点作为上一组交换完成后第二个节点的后置节点。
2、方法二采用迭代。添加一个哑节点避免单独处理边界情况,temp作为每一组交换节点的前置节点,根据temp定位两个需要交换的节点,然后交换指针,使得节点关系从temp—>node1—>node2变为temp—>node2—>node1,再令temp=node1,即可定位下一组进行交换的节点,重复此过程直到不存在节点或者只剩一个节点。
3、我的解答思路与官方解答的方法二一致,只不过实现上有所出入。
总结
- 本题可以采用递归和迭代两种方法。
- 递归每次返回每组交换后节点的第一个节点,连接到上一组交换后第二个节点的末尾即可。
- 迭代通过前置节点定位一组进行交换的两个节点,然后更改节点之间关系,直到不存在节点或者只剩一个节点。