链表算法

本文主要总结链表算法中常用技术点

有序链表

1、合并有序链表

将两个有序链表合并为一个新的有序链表并返回,新链表是通过拼接给定的两个链表的所有节点组成的。 

https://leetcode-cn.com/problems/merge-two-sorted-lists/

该算法主要就步骤是:

(1)确定链表头结点

       第一种方法可以判断哪个链表头大或者小,选择其中一个座位头结点;第二种方法是创建一个新节点,他的next指向头结点

(2)选择结点放在新链表中(升序为例)

        两个指针分别指向两个链表,一次比较两个指针结点的值,将小的节点放在新链表后面,并将指向这个节点的指针后移

(3)将没有遍历完成的队列放在新链表后面

2、链表排序

    链表排序使用的是归并排序,该算法主要步骤如下:

      (1)找到中间位置

               使用快慢指针的方法找到中间节点,注意快节点的初始值为head->next,如果为fast=head的时候 当只有两个节点会出现无限循环( sortList)

     (2)中间节点左右两部分进行有序链表合并操作

              return mergerList(sortList(head), sortList(fast));,该算法由于递归会最终递归到2个节点排序,4个节点排序,依次类推完全符合归并排序的思路见(https://leetcode-cn.com/problems/sort-list/

反转链表

1、 反转链表

      反转链表有两种方法 

(1)指针法

思路是不断在老的链表中摘取节点,放在新链表的前面。

 head指针指向新链表头结点、q指针指向老链表的头结点,r指向老链表头结点的下一个节点

(2)栈结构

由于栈是先进后出,所以刚好满足反转,不过该方法的空间和时间复杂度高一些

2、 链表相加

链表相加就是数字相加,数据现加是从低位向高位进位,所以需要先把链表倒置,然后从前向后依次相加,注意进位;最终相加完再将链表倒置即可(https://leetcode-cn.com/problems/reverse-linked-list-ii/  https://leetcode-cn.com/problems/reverse-linked-list/

3、 链表回文

(1)后半部分倒转

先使用快慢指针找到中间位置,找到以后将后半部分进行倒转,倒转以后跟前半部分一一对比即可

(2)前半部分倒转

使用快慢指针找到中间部分,找的过程中用栈存储慢指针数据,注意快指针最后是否为空,不为空说明为奇数个节点,中间指针在向前移动一步,后半部分跟栈中数据进行比较即可

https://leetcode-cn.com/problems/palindrome-linked-list/

删除链表

由于删除数据可能会删除头结点数据,当删除头结点数据的时候不是很好操作,所以一般删除操作都会引入辅助结点,创建一个新节点,该节点的next为head,最后再删除该节点即可

1、 删除重复数据

链表中有重复的元素,删除所有重复元素或者删除重复元素使其不重复(https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list-ii/  https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list/

2、删除倒数第n个节点

两个指针一个指向辅助节点,一个指向头结点,然后先将指向头结点向后移动n个节点

之后两个指针同时向前移动,当指向头结点的指针指向尾部NULL时,指向辅助节点的next刚好为倒数第n个节点

3、 移除元素

没有给定链表,仅仅是给定了链表中执行删除的元素,并将该元素删除,

void deleteNode(ListNode* node) {
        ListNode* tmp=node->next;
        node->val=tmp->val;
        node->next=tmp->next;
        delete(tmp);
        
    }

相交链表

1、判断链表是否有环,有环的话找到相交点

 快慢指针相遇点到入环点的距离 = 头结点到入环点的距离”:将头结点到入环点的这一段环绕在环上,那么快慢指针相遇点即为出发点,即快慢指针相遇点到入环点的距离,等于头结点到入环点的距离。 步骤一:判断是否有环:快慢指针 步骤二:找出入环点:双指针

ListNode *detectCycle(ListNode *head) {
        if(head==NULL or head->next==NULL) return NULL;
        ListNode* fast=head;
        ListNode* slow=head;
        while(fast!=NULL && fast->next!=NULL){
            fast=fast->next->next;
            slow=slow->next;
            if(fast==slow ) {
                slow=head;
                while(slow!=fast){
                    slow=slow->next;
                    fast=fast->next;
                }
                return slow;
            }
        }
          
        return NULL;
    }

https://leetcode-cn.com/problems/linked-list-cycle-ii/

2、两个链表相交,求相交点

这个是没有环的相交,求该相交点的方式是:先得到两个链表的长度,然后求出差值diff,长链表指针先走diff步,然后两个链表指针一起走,两个指针第一次相同的位置就是相交处

https://leetcode-cn.com/problems/intersection-of-two-linked-lists/

 

链表类型主要是这么多,后续发现新题型在继续添加

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值