c++ leetcode 24题两两交换链表节点8行代码非递归感受一下代码支配的恐怖吧!

c++ leetcode 24题两两交换链表节点8行代码非递归感受一下代码支配的恐怖吧!

前言

做完了题,昨天晚上看了一下国际站,
在这里插入图片描述

这人就是覃超老师说的光头哥(其实人家是有头发的),覃超老师对他的评价是"这人经常玩代码艺术",一看标题的话可能觉得他用的是递归,这个题的话一般循环都在20行开外,点开一看,不看不知道一看吓一跳啊,链接: https://leetcode.com/problems/swap-nodes-in-pairs/discuss/11019/7-8-lines-C%2B%2B-Python-Ruby

这是题目的链接:

https://leetcode-cn.com/problems/swap-nodes-in-pairs/submissions/

我昨天也发过这道题的代码的解法:

https://blog.csdn.net/qq_45569601/article/details/107750205

代码如下:

ListNode* swapPairs(ListNode* head) {
    ListNode** pp = &head,*a,* b;
    while ((a = *pp) && (b = a -> next)) {
    	a -> next = b -> next;
    	b -> next = a;
    	*pp = b;
    	pp = &(a -> next);
    }
    return head;
}

简洁漂亮,虽然代码的时间复杂度还是O(N);但是能把代码简洁这种程度,真是个高手.

个人简述代码:

第一行:

ListNode** pp = &head,*a,* b;

pp 是一个二级指针,指向指针的地址,首先pp 指向 指向头结点指针的地址;使用二级指针是一种非常老练的做法,虽然大多数人都知道二级指针,但实际用起来,可没有那么简单

第二行:

 while ((a = *pp) && (b = a -> next))

第二行就更牛批了,while循环的判断语句a = *pp 就是 a = head; pp 里面存放的是head 指针的地址, *解引出head 指针指向的地址,a 指针就指向了head 指针指向的地址,如果a为空,他就不执行&&后面的那条语句b = a ->next ; 它与||都具有断路特性,&& 是第一个条件不成立,它就不会执行后面的条件,||是如果第一个条件成立,它也不会执行后面的条件,起到了防御型编程的作用,执行完后判断语句后a 也就是第一个结点,b 是第二个节点

第三行和第四行:

a -> next = b -> next;
b -> next = a;

第三行和第四行经常刷链表题的朋友,不陌生吧? 就是我习惯用的是

ListNode* temp = b -> next;
b -> next = a;
a -> next = temp;

我以前也是没有去哪里想,脑子太笨,真学到了,a -> next = b -> next ; 第一个节点的next指向第三个节点,b -> next =a 第二个节点 的next 指向 第一个节点;

第五行:

*pp = b;

第五行也是最难理解的一行,虽然这只是一个简单的赋值语句, pp(二级指针) 是指向 第一个节点的指针的地址,这个一级指针地址没有变,变得是它这个一级指针指向的地址变成了第二个节点的地址,与最后一行return语句一块解释,

return head;

它的确返回的是head指针,但是它head指针指向的地址已经不是第一个节点的地址了,而是第二个节点的地址,第三四五行做的事情就是 a -> b -> (b -> next) 到 b -> a -> (b-> next) 第三四行已经做到了,但是head 指针指向的a 节点的地址,第五行,要改变的就是head 指针指向的地址

第六行:

pp = &(a -> next);

循环中最后一条语句,pp 指向了指向第三个节点的指针的地址,pp 二级指针指向一级指针的地址改变了,下一次循环的a 指针也就变成了指向第三个节点的地址;依次类推;直到a指针指向的节点地址的next为空循环结束;

总结

如果理解的和我不一样可以探讨一下,如果有不理解的我会在以我的理解再探讨,我把我唯一一张推荐票,给了这篇博客,光头哥绝非凡人,第一眼看到的时候,真就惊呆了,这就是代码的艺术啊.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值