两两交换链表中的节点
Posted zhiyue-bit
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了两两交换链表中的节点相关的知识,希望对你有一定的参考价值。
两两交换链表中的节点
给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
示例 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)
笔记
- 这道题解一思路较为简单,只要注意需要用到中间变量temp,保证不会有节点丢失即可,可以画图来辅助解题;
- 解二使用了递归,根据题意我们可以知道这个过程始终是first与second所指链点交换位置,而下一轮first和second也能在上一轮过程中得到,因此可以使用递归的做法,要注意返回值。
LeetCode 24 两两交换链表中的节点
24. 两两交换链表中的节点
给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。
你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。
示例:
给定 1->2->3->4, 你应该返回 2->1->4->3.
递归
思路:
- 返回值:交换完成的子链表
- 调用单元:设需要交换的两个点为 head 和 next,head 连接后面交换完成的子链表,next 连接 head,完成交换
- 终止条件:head 为空指针或者 next 为空指针,也就是当前无节点或者只有一个节点,无法进行交换
- 重要的是 找到递归单元 设置递归出口 返回调用自身的递归函数
结果: 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
};
// 这道题真的卡了半天 弄不清楚递归的最小重复单元 花了一点时间弄懂了 感觉对链表的理解更深层次了一些
以上是关于两两交换链表中的节点的主要内容,如果未能解决你的问题,请参考以下文章