Merge Sorted Array

原题链接Merge Sorted Array

意思是给定两个有序数组,将其合并成一个有序数组,存在nums1中。


如果先只是简单合并成一个新数组,然后将新数组赋值给nums1,基本就算完成了。现在考虑不适用其它内存空间,在nums1上原地合并新数组。
遇到的问题是如果nums1[i] > nums2[j],那么nums1[i]的位置就应该被赋值给nums2[j],可是nums1[i]原先的值应该放在哪里呢,接下来还有用这个nums1[i]和nums2[j+1]继续比较呢。如果nums1[i]一直大于nums2[j],那么所有的nums1[i]又应该放在哪里呢。
方法是在开始合并前就给nums1的前面留出n个大小的空间,而把nums1原来的数据全移动到后面的位置(这里是移动到nums1[n : m+n)),这样,即使nums2全都小于nums1,nums2也可以原封不动的放进nums1中,并且不需要移动nums1原有的数据

0   1   2   3   4   5   下标
1   3   5               nums1
2   4   6               nums2初始时
0   1   2   3   4   5   下标
            1   3   5   nums1
2   4   6               nums2开始合并
0   1   2   3   4   5   下标
1           1   3   5   nums1
2   4   6               nums2
------------------------------
1   2       1   3   5   nums1
2   4   6               nums2
------------------------------
1   2   3   1   3   5   nums1
2   4   6               nums2
------------------------------
1   2   3   4   3   5   nums1
2   4   6               nums2
------------------------------
1   2   3   4   5   5   nums1
2   4   6               nums2
------------------------------
1   2   3   4   5   6   nums1
2   4   6               nums2
------------------------------
合并完成

因为初始时nums1前面已经留有n个大小的空间(nums2的大小),所以在给nums1[0 : m+1)赋值时覆盖的都是合并完成,被放到前面的数据,不会丢失数据
代码如下

class Solution {
public:void merge(vector<int>& nums1, int m, vector<int>& nums2, int n) {for(int i = m - 1; i >= 0; --i)nums1[i + n] = nums1[i];int p1 = n;int p2 = 0;int idx = 0;while(p1 < m + n && p2 < n){nums1[idx++] = (nums1[p1] > nums2[p2]) ? nums2[p2++] : nums1[p1++];}while(p1 < m + n)nums1[idx++] = nums1[p1++];while(p2 < n)nums1[idx++] = nums2[p2++];}
};

Merge Two Sorted Lists

原题链接Merge Two Sorted Lists

意思是合并两个有序链表成为一个新的有序链表,比较简单,依次比较即可
细节方法是构造一个头节点,可以解决返回值是null的情况

/*** Definition for singly-linked list.* struct ListNode *     int val;*     ListNode *next;*     ListNode(int x) : val(x), next(NULL) {}* };*/
class Solution {
public:ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {ListNode* header = new ListNode(-1);ListNode* cur = header;while(l1 || l2){int n = 0;if(l1 == NULL || (l1 && l2 && l1->val > l2->val)){n = l2->val;l2 = l2->next;}else if(l2 == NULL || (l1 && l2 && l1->val <= l2->val)){n = l1->val;l1 = l1->next;}cur->next = new ListNode(n);cur = cur->next;}ListNode *ans = header->next;delete header;return ans;}
};

Merge k Sorted Lists

原题链接Merge k Sorted Lists

意思是合并k个有序链表,要求合成的链表也是有序的
两个链表时可以每次比较大小决定取哪个链表的值,k个就不能这么乱来了,不然复杂度会飙升。
可以维护一定大小的最小堆(优先级队列),堆中元素是ListNode类型,每次取最小的,然后插入取出的节点的下一个节点(如果是null就不用插入),直到堆变空为止。
需要注意的是如果ListNode设计时内部重载了operator<函数,那么直接创建优先级队列即可。但是题中给出的ListNode定义没有提供这样的函数,就需要自己实现,此时如果使用优先级队列的话,模板参数要提供三个

/*** Definition for singly-linked list.* struct ListNode {*     int val;*     ListNode *next;*     ListNode(int x) : val(x), next(NULL) {}* };*/class Solution {
public:ListNode* mergeKLists(vector<ListNode*>& lists) {if(lists.size() == 0)return NULL;/** 三个模板参数* ListNode,存储的元素类型* vector<ListNode>,内部存储方式,默认是vector,传入vector就好* cmp,因为没有提供比较大小的函数,需要自己提供,但是不能简单的创建一个函数,需要一个函数对象(行为像函数的类),即重载了operator()的类*/std::priority_queue<ListNode, vector<ListNode>, cmp> pq;for(auto node : lists){if(node != NULL)pq.push(std::move(*node));}ListNode* header = new ListNode(-1);ListNode* cur = header;while(pq.size() > 0){ListNode node = pq.top();pq.pop();cur->next = new ListNode(node.val);cur = cur->next;if(node.next)pq.push(std::move(*node.next));}ListNode* ans = header->next;delete header;return ans;}private:struct cmp{/* * 如果是增序,就判断是否大于* 如果是减序,就判断是否小于* 真怪...*/bool operator()(const ListNode& lhs, const ListNode& rhs){return lhs.val > rhs.val;}  };
};

每天一道LeetCode-----合并两个/多个有序链表为一个新链表相关推荐

  1. LeetCode——合并两个有序数组

    LeetCode--合并两个有序数组 题目描述: 给你两个有序整数数组 nums1 和 nums2,请你将 nums2 合并到 nums1 中,使 nums1 成为一个有序数组. 说明: 初始化 nu ...

  2. 编写下面的函数合并两个有序列表构成一个新的有序列表: def merge(list1,list2): 编写测试程序提示用户输入两个有序列表,然后显式合并后的有序列表。

    题目内容:编写下面的函数合并两个有序列表构成一个新的有序列表:def merge(list1,list2):编写测试程序提示用户输入两个有序列表,然后显式合并后的有序列表.要求:不允许使用系统提供的s ...

  3. 合并两个有序数组为一个新的有序数组

    题目:有两个有序数组a,b,现须要将其合并成一个新的有序数组. 简单的思路就是先放到一个新的数组中,再排序.可是这种没体现不论什么算法,这里考的不是高速排序等排序算法.关键应该是怎样利用有序已知这个条 ...

  4. LeetCode - 合并两个有序链表

    日常刷题中!

  5. 合并两个递增的有序数组

    利用双指针的方法,每次将两个数组中的较小的数放入新数组,两个数组遍历一遍即可 int[] arr = new int[nums1.length];int i = 0;int j = 0;while ( ...

  6. 有两个磁盘文件 A 和 B, 各存放一行字母,要求把这两个文件中的信息合并(按字母顺序排列), 输出到一个新文件 C 中

    fp = open('test1.txt', encoding='utf8') a = fp.read() fp.close()fp = open('test2.txt', encoding='utf ...

  7. 《LeetCode力扣练习》剑指 Offer 25. 合并两个排序的链表 Java

    <LeetCode力扣练习>剑指 Offer 25. 合并两个排序的链表 Java 一.资源 题目: 输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的. 示例1: ...

  8. LeetCode 27 合并两个排序的链表

    题目:输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的. 示例1:   输入:1->2->4, 1->3->4                 输出:1 ...

  9. Leetcode链表题目笔记2 合并两个排序的链表

    合并两个排序的链表:合并有序链表 输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的. 示例: 输入:1->2->4, 1->3->4 输出:1-> ...

最新文章

  1. R语言生成仿真的3D高斯簇数据集、使用scale函数进行数据缩放、并使用KMeans进行聚类分析、数据反向缩放并比较聚类生成的中心和实际数据的中心的差异、预测新的数据所属的聚类簇
  2. 网站HTML删除数据库中数据语句,如何以编程方式删除WebSQL中的数据库?
  3. @RequestParam:将请求参数绑定到你控制器的方法参数上(是springmvc中接收普通参数的注解)
  4. 什么是PCB板上的鼠牙洞?
  5. CTRL+SHIFT
  6. quartus管脚分配后需要保存吗_掉电保存数据到EEPROM
  7. java创建一副牌_用java怎么创建一副扑克牌
  8. Spring Cloud Eureka(三)实现一个高可用的注册中心
  9. 使用jdbcTemplate查询返回自定义对象集合
  10. 机器学习入门笔记(一):模型性能评价与选择
  11. grid php 用法,grid布局主要用法
  12. python编写窗口怎么清除内容_如何删除或销毁tkinter中的标签?
  13. linux系统之上搭建maven 之nexus服务篇
  14. Servlet是什么
  15. easydarwin php,Windows版本EasyDarwin
  16. java开发中的dorado_dorado7开发常用技巧及代码
  17. [linux]scp与服务器互传文件
  18. 采取HEXO+NexT主题+github.io的方式建立自己的个人主页
  19. 把计算机器显示桌面,怎样将电脑显示器和桌面匹配
  20. 一天学会MYSQL数据库_笔记

热门文章

  1. python定义构造函数、包括颜色价格品牌_《Python编程与算法基础教程》(第二版),蒋洪宇,青松,第9章:课后练习,程序设计,版江红余,第九章,习题,答案...
  2. Java黑皮书课后题第10章:***10.8(金融:Tax类)编程练习题8.12使用数组编写一个计算税款的程序。设计一个名为Tax类,该类包含下面的实例数据域
  3. flask 项目基本框架的搭建
  4. mint-ui 中 Infinite scroll 在tab-container中使用数据全部加载的问题
  5. QuickStart系列:docker部署之MariaDB
  6. HTMl5的sessionStorage和localStorage
  7. linux下eclipse+pdt(PHP集成开发环境安装)
  8. 如何解决复杂条件下的程序流的控制问题?
  9. C# 系统应用之清除Cookies、IE临时文件、历史记录
  10. 【数据结构与算法】之深入解析“冗余连接”的求解思路与算法示例