链表题目整理

141.环形链表

快慢指针slow == fast,即存在

142.环形链表2:求环的起点

slow== fast后,令slow = head,然后来个while(slow != fast)里面每个走一步,再次重合的点就是起点

a+b+c+b = 2(a+b)     即a=c

扩展问题:求环长

当两个指针首次相遇,证明链表有环的时候,让两个指针从相遇点继续循环前进,并统计前进的循环次数,直到两个指针第2次相遇。此时,统计出来的前进次数就是环长。因为指针p1每次走1步,指针p2每次走2步,两者的速度差是1步。当两个指针再次相遇时,p2比p1多走了整整1圈。因此,环长 = 每一次速度差 × 前进次数 = 前进次数。

160.相交链表:得到两个链表的交点

双指针法:显然,当两个链表长度相同时最容易找到公共节点。双指针法相当于把链表A接到链表B后面,同理又把链表B接到链表A后面,使两个链表长度相等。

设链表A的长度为a+c,链表B的长度为b+c,a为链表A不公共部分,b为链表B不公共部分,c为链表A、B的公共部分。将两个链表连起来,A->B和B->A,长度:a+c+b+c=b+c+a+c,若链表AB相交,则a+c+b与b+c+a就会抵消,它们就会在c处相遇;若不相交,则c为nullptr,则a+b=b+a,它们各自移动到尾部循环结束,即返回nullptr

思路二:链表A结束后指向B的头结点,这时就出现了环,用上面的判断环起点的方法即可。

83.删除有序链表中的重复元素:保留一个

判断当前指针的值和下一个的是否重复,是就指向下下个

82.删除有序链表中的重复元素2:都删除

遍历的时候需要记录一个prev节点,用来处理删除节点之后节点重新连接的问题,这里用到了哨兵

ListNode dummy(0);
dummy.next = head;
ListNode* p = &dummy;

21.合并两个有序链表

也需要哨兵节点。然后分别比较val大小,小的就放进去再指向下一个。最后判断哪个还有,就整个指向。

23.合并k个有序链表

采用 divide and conquer 的方法,首先两两合并,然后再将先前合并的继续两两合并。时间复杂度为O(NlgN)。

206.反转链表

207.反转[m,n]区间的链表

也得有哨兵。先指到m的位置,再在里面循环反转。

25.K个一组反转链表(困难)

遍历链表,两两交换

也有哨兵,用到前驱节点。

对链表进行排序,用分治算法,依次递归对左右两半进行排序。,最后就是合并左右两半。

旋转链表

首先需要遍历链表,得到链表长度n,因为k可能大于n,所以我们需要取余处理,然后将链表串起来形成一个环,在遍历 n - k % n 个节点,断开,就成了。譬如上面这个例子,k等于2,我们遍历到链表结尾之后,连接1,然后遍历 5 - 2 % 5 个字节,断开环,下一个节点就是新的链表头了。

两数之和

19.删除链表的倒数第N个节点

也用哨兵,双指针,当快的前进n时,慢的开始;当快的到结尾时,慢的正好到可以删除的那个节点前一个

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值