IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 面试必刷算法TOP101之链表篇 TOP11 -> 正文阅读

[数据结构与算法]面试必刷算法TOP101之链表篇 TOP11

合并k个已排序的链表

题目来源:Leetcode
1、问题描述
给定一个链表数组,每个链表都已经按升序排列。
请将所有链表合并到一个升序链表中,返回合并后的链表。
示例:
在这里插入图片描述

2、思路解析
思路一就是归并思想:
首先将前两个链表合并得到一个新的链表,遍历链表数组每次将数组和新得到一个链表合并得到一个新的链表具体步骤如下:

  • step1首先将链表数组的前两个链表合并为一个有序链表
  • step2遍历数组将新得到的链表和链表数组中下一个链表合并为一个新链表
  • step3重复步骤3直到遍历完数组

合并过程如下:
在这里插入图片描述

思路二优先级队列:
思路就是将数组中链表的按头节点数值大小插入到小堆中没插入一个链表,小堆每一个节点都是链表的头节点。小堆就按照链表头节点的数组大小调整数组,保证还是维持小堆的结构,当把链表数组链表遍历完是,就把链表全插入到小堆了。接下来是将小堆链表按顺序插入到新链表中了。遍历优先级队列取节点,因为优先级队列是按照链表头节点数值大小排序,所以每次只需将堆顶的链表拿出来将头节点插入到新链表中,再把取下来链表的头节点的下一个节点地址插入到堆中,堆会再次按照头节点得到数组大小调整堆结构。
合并过程如下:
在这里插入图片描述
假设数组就这3个链表为了后续的方便给每个链表都起了一个名字

接着将链表插入到优先级队列中
插入方式是按照链表头节点数值大小插入的
在这里插入图片描述
接下来是遍历优先级队列按照顺序构建有序链表
在这里插入图片描述
在这里插入图片描述
后续按照上边步骤一次进行,直到堆中再无链表
3、代码实现

   ListNode *_mergeKLists(ListNode *phead1,ListNode*phead2){
        //增加头节点
        
        ListNode*phead=new ListNode(-1);
        ListNode*cur=phead;
        while(phead1&&phead2){
            if(phead1->val<=phead2->val){
                cur->next=new ListNode(phead1->val);
                phead1=phead1->next;
                cur=cur->next;
            }else{
                  cur->next=new ListNode(phead2->val);
                  phead2=phead2->next;
                  cur=cur->next;
            }
        }
        //哪个链表先空就链接另一个
        cur->next=phead1?phead1:phead2;
        return phead->next;
    }
    //两两连接
    //归并解决问题线性解决来浪费时间
    //
    ListNode*marge(vector<ListNode*>lists,int row,int col){
        //先分在并
        //返回条件
        if(row==col){
            return lists[row];
        }
        if(row>col){
            return NULL;
        }
        int mid=(row+col)/2;
        //将lists分分割成一个一个的链表
        ListNode*li=marge(lists,row,mid);
        ListNode*l2=marge(lists,mid+1,col);


        //归并
        return _mergeKLists(li,l2);
    }
    ListNode *mergeKLists(vector<ListNode *> &lists) {
        if(lists.empty()){
            return NULL;
        }
      if(lists.size()==1){
          return lists[0];
      }
      return marge(lists,0,lists.size()-1);
    
    }


这种方法相对简单但是链表合并次数太多,对于有时间要求的地方不一定能过

class Solution {
public:
    //优先级队列解决
    //建造小堆
   struct cmp{
       bool operator()(ListNode*l1,ListNode*l2){
           return l1->val>l2->val;
       }
    };
    ListNode *mergeKLists(vector<ListNode *> &lists) {
        if(lists.empty()){
            return NULL;
        }
        if(lists.size()==1&&lists[0]==NULL){
            return NULL;
        }
       priority_queue<ListNode*,vector<ListNode*>,cmp> q;
        //先入队
        //排序是按照每个链表的头节点的值排序的
        for(int i=0;i<lists.size();i++){
            if(lists[i]){
            q.push(lists[i]);
            }
        }
        //入队时已经按照小队的顺序排序好了
        //对顶就是全部链表头节点的最小的值了
        
        
        //虚头节点
        ListNode*phead=new ListNode(-1);
        ListNode*cur=phead;
  
        
        while(!q.empty()){
                  
            //取对顶元素的头节点
             ListNode* top=q.top();
             cur->next=top;
            cur=cur->next;
            q.pop();
        //取堆顶链表的头节点头如果不为空又将其拆入队列,重新排序
        if(top->next){
            q.push(top->next);
        }
            
            
        }
        return phead->next;
        
    }
};

环形链表Ⅱ

题目来源:Leetcode
1、题目描述
给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。
不允许修改 链表。
示例:
在这里插入图片描述
2、思路解析;
将前边没有环的节点地址存储到数组中,然后判断数值中有没有节点地址,如果节点出现第一次在数组中找到这个节点地址就是环形链表的第一个节点
在这里插入图片描述
3、代码实现

class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        if(head==NULL){
            return NULL;
        }
       unordered_set<ListNode*>s;
       while(head){

//判断节点地址是不是再节点中存在存在就返回第一个存在的节点
           if(s.find(head)!=s.end()){
               return head;
           }
           s.insert(head);
           head=head->next;
       }
        return NULL;
    }
};
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-04-09 18:42:57  更:2022-04-09 18:47:15 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 10:25:05-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码