【刷题之路】LeetCode24——详解两两交换链表中的结点的细节

一、题目描述

原题链接:https://leetcode.cn/problems/swap-nodes-in-pairs/comments/

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

二、解题

方法1:迭代(哨兵位)

思路分析:

  这道题目要是没有使用哨兵位的话,会写的十分复杂。首先我们知道要两个两个地翻转链表(不能交换链表中的值),需要先知道这两个结点的前一个结点(如需翻转cur和last,则需要prev)

具体操作为last->next=cur,prev->next=last,cur应该指向NULL但是我们发现此时找不到了,所以在操作last->next之前我们应该先保存last->next(struct ListNode*tmp=last-》next),即cur->next=tmp。

但是在翻转头两个结点的时候就会出现问题,因为此时没有头结点的前一个结点,所以这个时候就需要一个哨兵位了,不然头两个就要额外操作,写起来就十分麻烦了。

哨兵位还有另外一个好处,就是dummyhead的next就是翻转完需要返回的头结点,而没有哨兵位就需要额外记录一下head->next,最后再返回,有点麻烦。

至此,总体的思路就有了,就是创建dummyhead,然后两个两个翻转,不断迭代,那么迭代的条件是什么呢?当链表有偶数个的时候所有的结点都参与翻转,但是当链表有奇数个的时候最后一个结点就不参与翻转,所以迭代结束的条件就是prev或者cur或者last为空了,即while(prev&&cur&&last),这里仍有一个小细节需要注意,就是cur需要写在last之前,不然可能会出现空指针的解引用,因为cur比last前一个位置。

有了思路,写起来也就行云流水啦。

代码实现:

struct ListNode* swapPairs(struct ListNode* head){
    //使用双指针避免使用中间变量
    typedef struct ListNode ListNode;
    ListNode *dummyhead = (ListNode *)malloc(sizeof(ListNode));
    dummyhead->next = head;

    ListNode* prev = dummyhead; 
    ListNode* cur = dummyhead->next;
    while(prev && cur && cur->next )
    {
        prev->next = cur->next;
        cur->next = prev->next->next;
        prev->next->next = cur;
        prev = cur;
        cur = prev->next;
    }
    return dummyhead->next;
}

总结

总的来说这道题不算很难,但十分考验我们对链表的基础操作,以及对哨兵位的使用,相信对每个人都会有所帮助。

希望大家多多支持,我也会继续输出我的编程知识的!

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值