写出一段代码将链表中的两个节点位置互换位置_LeetCode 第二十四题 两两交换链表中的节点

52c658d4d0922d41fba3f1603c8b08db.png
给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。 你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。 示例:
给定 1->2->3->4, 你应该返回 2->1->4->3.

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/swap-nodes-in-pairs 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

又是一道链表题目,要求是两两交换链表中的节点,看似很复杂的一个问题,但是使用分治法,可以很简单的解决这个问题,我们只需将链表中的节点两两取出,交换位置,并在其后连接上后两个交换过位置的链表即可,那么我们就开始编写代码吧。

首先根据题目我们可以构建出来函数头,输入为一个链表,输出也为一个链表:

public ListNode SwapPairs(ListNode head)

分治法多用递归来实现,那么我们要找到递归终结的条件,因为需要两两交换,那么在最后一组之后,没有节点或只剩下一个节点均为递归结束,那么判断条件为node == null || node.next == null,有了终止条件,我们可以构建代码如下

public ListNode SwapPairs(ListNode head)
{
    if (head == null || head.next == null) //判断是否无法组成一组
    {
        return head;
    }
    ListNode result = head.next; //第二个节点
    head.next = SwapPairs(result.next); //将第一个节点的next指向后边交换后的节点
    result.next = head;//将第二个节点的next指向第一个节点
    return result;
}

放入LeetCode 跑一下

执行用时 :104 ms, 在所有 C# 提交中击败了86.22%的用户

内存消耗 :22.9 MB, 在所有 C# 提交中击败了93.22%的用户

性能不错,而且代码十分简洁。但是我们这里使用了递归,递归尤其很明显的缺点,当数据量过大时,因为递归每一次函数调用都会在内存调用栈中分配空间,而调用栈的空间是有限的,所以会导致栈溢出。曾经听一位前辈说过所有的递归都可以改写成循环,那么既然今天这道题目很容易就解出来了,我们就再花一点时间将之改造成循环吧。中间过程不赘述,直接上代码

public ListNode SwapPairs(ListNode head)
{
    ListNode current = head;
    ListNode preNode = new ListNode(-1);//记录前一个节点
    preNode.next = head;//将现在链表写入pre的后边
    ListNode result = preNode;
​
    while (current != null && current.next != null) 
    {
        ListNode first = current;
        ListNode second = current.next; //取出需要交换的两个节点
        preNode.next = second;//将第二个节点接入上一个节点中
        first.next = second.next;//将第二个节点的下一个节点接入第一个节点
        second.next = first;//将第一个节点放入第二个节点后边
        preNode = first;//此时第一个节点即为下次循环的前一个节点
        current = first.next;//此时第一个节点的下一个即为下一次循环的起始节点
    }
    return result.next;
}

放入LeetCode 跑一下

执行用时 :100 ms, 在所有 C# 提交中击败了95.92%的用户

内存消耗 :23.1 MB, 在所有 C# 提交中击败了72.03%的用户

性能有所提升,但是代码的可读性会降低不少,那么今天这道题目就讲到这里了。

6f11bdaaffd2d21a5e104384e38a3735.png
想了解更多,扫码关注我的公众号 IP的dotNet吧
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值