两两交换链表中的节点

Posted zhiyue-bit

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了两两交换链表中的节点相关的知识,希望对你有一定的参考价值。

两两交换链表中的节点

24. 两两交换链表中的节点 - 力扣(LeetCode)

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

示例 1:

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

Python

解一:

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution(object):
    def swapPairs(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        p = ListNode(next = head)
        if head != None and head.next != None:
            head = head.next
        while p.next != None and p.next.next != None:
            temp = p.next.next
            p.next.next = p.next.next.next
            temp.next = p.next
            p.next = temp
            p = p.next.next
        return head

解二:

# Definition for singly-linked list.
# class ListNode(object):
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution(object):
    def swapPairs(self, head):
        """
        :type head: ListNode
        :rtype: ListNode
        """
        def swap(head):
            if head == None or head.next == None:
                return head
            first = head
            second = head.next
            others = head.next.next
            
            second.next = first
            first.next = swap(others)
            return second
        return swap(head)

笔记

  1. 这道题解一思路较为简单,只要注意需要用到中间变量temp,保证不会有节点丢失即可,可以画图来辅助解题;
  2. 解二使用了递归,根据题意我们可以知道这个过程始终是first与second所指链点交换位置,而下一轮first和second也能在上一轮过程中得到,因此可以使用递归的做法,要注意返回值。

LeetCode 24 两两交换链表中的节点

24. 两两交换链表中的节点

给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。

示例:

给定 1->2->3->4, 你应该返回 2->1->4->3.
递归

思路:

  1. 返回值:交换完成的子链表
  2. 调用单元:设需要交换的两个点为 head 和 next,head 连接后面交换完成的子链表,next 连接 head,完成交换
  3. 终止条件:head 为空指针或者 next 为空指针,也就是当前无节点或者只有一个节点,无法进行交换
  4. 重要的是 找到递归单元 设置递归出口 返回调用自身的递归函数

结果: 64ms 还可以啦 时间复杂度是O (nlonn)级别的 但毕竟用了递归

/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */
/**
 * @param {ListNode} head
 * @return {ListNode}
 */
var swapPairs = function(head) {
    if(head === null || head.next === null) return head
    let next = head.next
    head.next = swapPairs(next.next)
    next.next = head
    return next
};
迭代

思路: 我们把链表分为两部分,即奇数节点为一部分,偶数节点为一部分,A 指的是交换节点中的前面的节点,B 指的是要交换节点中的后面的节点。在完成它们的交换,我们还得用 prevNode 记录 A 的前驱节点。
结果: 64ms 时间复杂度O(n)级别

/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */
/**
 * @param {ListNode} head
 * @return {ListNode}
 */
var swapPairs = function(head) {
    let dummyNode = new ListNode(-1)
    dummyNode.next = head
    let pre = dummyNode
    while(head !== null && head.next !== null) {
        // 奇数节点
        let first_node = head
        // 偶数节点
        let seconde_node = head.next
        // pre 指向 偶数节点
        pre.next = seconde_node

        //修改奇数节点 偶数节点的指向 
        first_node.next = seconde_node.next
        seconde_node.next = first_node

        // 类似于i++ j++ 这么理解
        pre = first_node
        head = head.next
    }    
    // dummyNode的下一个节点 就是我们所需的链表
    return dummyNode.next
}

// 优化了一下
/**
 * Definition for singly-linked list.
 * function ListNode(val) {
 *     this.val = val;
 *     this.next = null;
 * }
 */
/**
 * @param {ListNode} head
 * @return {ListNode}
 */
var swapPairs = function(head) {
    // 设置递归的出口
    let dummyNode = new ListNode()
    dummyNode.next = head
    let pre = dummyNode
    while(head !== null && head.next !== null) {
        let firstNode = head
        let secondNode = head.next

        pre.next = secondNode
        firstNode.next = secondNode.next
        secondNode.next = firstNode

        pre = head
        head = head.next
    }
    return dummyNode.next
};

// 这道题真的卡了半天 弄不清楚递归的最小重复单元 花了一点时间弄懂了 感觉对链表的理解更深层次了一些

以上是关于两两交换链表中的节点的主要内容,如果未能解决你的问题,请参考以下文章

24. 两两交换链表中的节点

LeetCode 24. 两两交换链表中的节点

LeetCode-024-两两交换链表中的节点

24. 两两交换链表中的节点

刷题13:两两交换链表中的节点

力扣——两两交换链表中的节点