刷题的日常-两两交换链表中的节点

54 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第21天,点击查看活动详情

刷题的日常-2022年10月18号

一天一题,保持脑子清爽

两两交换链表中的节点

来自leetcode的 24 题,题意如下:

给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。

示例1:

输入: head = [1,2,3,4]
输出: [2,1,4,3]

image.png

理解题意

通过题意,我们可以将信息整理如下:

  • 题目给定一个链表
  • 要求我们以两个一对进行翻转
  • 返回翻转之后的链表头节点

做题思路

这道题我们其实可以用暴力解来解决,直接将所有的节点放到list中,然后进行两两交换,交换完成之后在将所有的节点连接起来返回。这里我们采取另外一种思路,一边遍历一遍翻转。在遍历的过程中,如果遍历到两个的时候就翻转,步骤如下:

  • 如果头节点是空的,直接返回
  • 开辟一个虚拟的头节点
  • 往后一直遍历,如果下一个位置不是空的,进行翻转
  • 记录前指针和后指针,防止丢失链表信息
  • 翻转之后还需要将翻转过后的指针往后移动,将链表补全
  • 返回虚拟头节点的下一个指针,这个就是我们需要的结果

代码实现

代码实现如下,因为只需要遍历一次,所以时间复杂度为O(n):

public class Solution {
    public ListNode swapPairs(ListNode head) {
        if (head == null) {
            return null;
        }
        ListNode current = head = new ListNode(-1, head), tmp = current.next;
        while (tmp != null && (tmp = tmp.next) != null) {
            ListNode next = current.next;
            current.next = tmp;
            tmp = tmp.next;
            current.next.next = next;
            current = next;
            next.next = tmp;
        }
        return head.next;
    }
}

image.png