PTA题---求两个有序序列中位数所体现的思想。
---恢复内容开始---
近日,在做PTA题目时,遇到了一个这样的题,困扰了很久。题目如下:已知有两个等长的非降序序列S1, S2, 设计函数求S1与S2并集的中位数。有序序列A0,A1,⋯,AN−1的中位数指A(N−1)/2的值,
即第⌊(N+1)/2⌋个数(A0为第1个数)。输入分三行。第一行给出序列的公共长度N(0<N≤100000),随后每行输入一个序列的信息,即N个非降序排列的整数。数字用空格间隔。
首先,分析题可知:该题中的序列是一个升序
的序列(可能存在连续几个相等数的序列),要求这两个序列的并集,可以使用两个顺序表实现,这两个顺序表所需要的操作是:构造函数、插入函数(用于求集)、析构函数(不需要)、求中位数(因为对象无法访问其私有成员)、再者就是求并集的函数(是本文的重点,稍后奉上)。其次,在三行中输入数,我在N值取法还存在很大疑问,也致使本题始终得不到完全正确的结果, 下次重点分析这个问题。
求两个序列的并集,会想到的是,遍历其中一个顺序表,将另外一个顺序表一次插入到该顺序表中。注:连个序列中可能分别存在相同的元素,求并是指,将不同的元素插入。下面具体分析一下这问题。
该函数可以使用顺序表作为函数参数的。一个顺序表调用该函数,另外一个作为函数参数,传入进去。
void Seqlist::Union(Seqlist L){
//定义两个变量去遍历两个顺序表
int q = 0;
int w = 0;
//循环结束的标志是遍历完两个顺序表,注意的是q在插入w后其长度会变,而w应该不变
while(q <= length && w < L.length){
//当前data[q] < L.data[w]的话,q++,w保持不变。说明w中的数更大,应该插在后面。
if(data[q] < L.data[w])
q++;
else if(data[q] == L.data[w])
{
q++;
w++;
}
//当data[q]<L.data[w],执行插入
else
insert(q, L.data[w]);
}
//当第一个顺序表遍历完成,而第二个未循环完,将第二个循序表的元素全部插入到第一个循序表中
for( w; w < L.length; w++){
data[q-1] = L.data[w];
q++;
length++;
}
}
上面的比较过程是一个完成的过程,如下面两个序列1 3 5 7 9、 2 3 4 5 6. 首先1 大于 2, 不执行插入,第一个循环表往下,到了3,3相等,不变。接着,4小于5 则执行插入。往后依次类推。
另附本题的完整答案:
#include<iostream>
using namespace std;
//定义最大连个数列的最大值
const int MaxSize = 100; class Seqlist{
public:
Seqlist(){length = 0;}
Seqlist(int a[], int n);
~Seqlist(){}
void insert(int i, int x);
void Union(Seqlist L2);
void GetMidNum();
private:
int length;
int data[MaxSize];
};
Seqlist::Seqlist(int a[], int n){
for(int i = 0; i < n; i++)
data[i] = a[i];
length = n;
}
void Seqlist::insert(int i, int x){
for(int j = length; j > i; j--){
data[j] = data[j - 1];
}
data[i] = x;
length++;
}
void Seqlist::GetMidNum(){
cout << data[(length - 1) / 2] << endl;
}
void Seqlist::Union(Seqlist L){
int q = 0;
int w = 0;
while(q <= length && w < L.length){
if(data[q] < L.data[w])
q++;
else if(data[q] == L.data[w])
{
q++;
w++;
}
else
insert(q, L.data[w]);
}
for( w; w < L.length; w++){
data[q-1] = L.data[w];
q++;
length++;
}
}
int main(){ int a[MaxSize] = {0};
int b[MaxSize] = {0};
int m ;
cin >> m;
int n = 0;
while(n < 2){
int k = 0;
while(k < m){
if(n == 0)
cin >> a[k];
else
cin >> b[k];
k++;
}
n++;
}
Seqlist L1(a, m);
Seqlist L2(b, m);
L1.Union(L2);
L1.GetMidNum();
return 0;
}
但是
---恢复内容结束---
近日,在做PTA题目时,遇到了一个这样的题,困扰了很久。题目如下:已知有两个等长的非降序序列S1, S2, 设计函数求S1与S2并集的中位数。有序序列A0,A1,⋯,AN−1的中位数指A(N−1)/2的值,
即第⌊(N+1)/2⌋个数(A0为第1个数)。输入分三行。第一行给出序列的公共长度N(0<N≤100000),随后每行输入一个序列的信息,即N个非降序排列的整数。数字用空格间隔。
首先,分析题可知:该题中的序列是一个升序
的序列(可能存在连续几个相等数的序列),要求这两个序列的并集,可以使用两个顺序表实现,这两个顺序表所需要的操作是:构造函数、插入函数(用于求集)、析构函数(不需要)、求中位数(因为对象无法访问其私有成员)、再者就是求并集的函数(是本文的重点,稍后奉上)。其次,在三行中输入数,我在N值取法还存在很大疑问,也致使本题始终得不到完全正确的结果, 下次重点分析这个问题。
求两个序列的并集,会想到的是,遍历其中一个顺序表,将另外一个顺序表一次插入到该顺序表中。注:连个序列中可能分别存在相同的元素,求并是指,将不同的元素插入。下面具体分析一下这问题。
该函数可以使用顺序表作为函数参数的。一个顺序表调用该函数,另外一个作为函数参数,传入进去。
void Seqlist::Union(Seqlist L){
//定义两个变量去遍历两个顺序表
int q = 0;
int w = 0;
//循环结束的标志是遍历完两个顺序表,注意的是q在插入w后其长度会变,而w应该不变
while(q <= length && w < L.length){
//当前data[q] < L.data[w]的话,q++,w保持不变。说明w中的数更大,应该插在后面。
if(data[q] < L.data[w])
q++;
else if(data[q] == L.data[w])
{
q++;
w++;
}
//当data[q]<L.data[w],执行插入
else
insert(q, L.data[w]);
}
//当第一个顺序表遍历完成,而第二个未循环完,将第二个循序表的元素全部插入到第一个循序表中
for( w; w < L.length; w++){
data[q-1] = L.data[w];
q++;
length++;
}
}
上面的比较过程是一个完成的过程,如下面两个序列1 3 5 7 9、 2 3 4 5 6. 首先1 大于 2, 不执行插入,第一个循环表往下,到了3,3相等,不变。接着,4小于5 则执行插入。往后依次类推。
另附本题的完整答案:
#include<iostream>
using namespace std;
//定义最大连个数列的最大值
const int MaxSize = 100; class Seqlist{
public:
Seqlist(){length = 0;}
Seqlist(int a[], int n);
~Seqlist(){}
void insert(int i, int x);
void Union(Seqlist L2);
void GetMidNum();
private:
int length;
int data[MaxSize];
};
Seqlist::Seqlist(int a[], int n){
for(int i = 0; i < n; i++)
data[i] = a[i];
length = n;
}
void Seqlist::insert(int i, int x){
for(int j = length; j > i; j--){
data[j] = data[j - 1];
}
data[i] = x;
length++;
}
void Seqlist::GetMidNum(){
cout << data[(length - 1) / 2] << endl;
}
void Seqlist::Union(Seqlist L){
int q = 0;
int w = 0;
while(q <= length && w < L.length){
if(data[q] < L.data[w])
q++;
else if(data[q] == L.data[w])
{
q++;
w++;
}
else
insert(q, L.data[w]);
}
for( w; w < L.length; w++){
data[q-1] = L.data[w];
q++;
length++;
}
}
int main(){ int a[MaxSize] = {0};
int b[MaxSize] = {0};
int m ;
cin >> m;
int n = 0;
while(n < 2){
int k = 0;
while(k < m){
if(n == 0)
cin >> a[k];
else
cin >> b[k];
k++;
}
n++;
}
Seqlist L1(a, m);
Seqlist L2(b, m);
L1.Union(L2);
L1.GetMidNum();
return 0;
}
但是
PTA题---求两个有序序列中位数所体现的思想。的更多相关文章
- 求两个有序序列合并成新有序序列的中位数,求第k小数
此算法涉及一个重要数学结论:如果A[k/2-1]<B[k/2-1],那么A[0]~A[k/2-1]一定在第k小的数的序列当中,可以用反证法证明. 算法思想如下: 1,假设A长度为m,B长度为n, ...
- 求两个有序数组的中位数(4. Median of Two Sorted Arrays)
先吐槽一下,我好气啊,想了很久硬是没有做出来,题目要求的时间复杂度为O(log(m+n)),我猜到了要用二分法,但是没有想到点子上去.然后上网搜了一下答案,感觉好有罪恶感. 题目原型 正确的思路是:把 ...
- 求两个有序数组的中位数或者第k小元素
问题:两个已经排好序的数组,找出两个数组合并后的中位数(如果两个数组的元素数目是偶数,返回上中位数). 设两个数组分别是vec1和vec2,元素数目分别是n1.n2. 算法1:最简单的办法就是把两个数 ...
- 【python】【补】Leetcode每日一题-合并两个有序数组
[python]Leetcode每日一题-合并两个有序数组 [题目描述] 给你两个有序整数数组 nums1 和 nums2,请你将 nums2 合并到 nums1 中,使 nums1 成为一个有序数组 ...
- PAT 2-13. 两个有序序列的中位数(25)
题目链接:http://www.patest.cn/contests/ds/2-13 解题思路及代码如下: /* 解题思路: 分别求出序列A 和B 的中位数,设为a 和b,求序列A 和B 的中位数过程 ...
- leetcode第四题:两个有序数组的中位数
给定两个大小为 m 和 n 的有序数组 nums1 和 nums2. 请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n)). 你可以假设 nums1 和 nums2 ...
- LeetCode刷题:第四题 寻找两个有序数组的中位数
题目描述: 给定两个大小为 m 和 n 的有序数组 nums1 和 nums2. 请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n)). 你可以假设 nums1 和 ...
- 2-13. 平均两个有序序列(25)(ZJU_PAT 名单 | 排列 )
主题链接:http://pat.zju.edu.cn/contests/ds/2-13 已知有两个等长的非降序序列S1, S2, 设计函数求S1与S2并集的中位数.有序序列A0, A1-AN-1的中位 ...
- 【递归打卡2】求两个有序数组的第K小数
[题目] 给定两个有序数组arr1和arr2,已知两个数组的长度分别为 m1 和 m2,求两个数组中的第 K 小数.要求时间复杂度O(log(m1 + m2)). [举例] 例如 arr1 = [1, ...
随机推荐
- 第三方软件内嵌IE出现纵向滚动条消失的BUG,奇葩的IE BUG 真是无奇不有
混了这么久 竟然还有这样难以解决的BUG,最后都跑到英文的MSDN上提问了,因为谷歌都谷不出朕的忧伤了,有木有. 提问原文如下:https://social.msdn.microsoft.com/Fo ...
- Spring IOC容器分析(3) -- DefaultListableBeanFactory
上一节介绍了封装bean对象的BeanDefinition接口.从前面小结对BeanFactory的介绍中,我们知道bean对象是存储在map中,通过调用getBean方法可以得到bean对象.在接口 ...
- [转载] Java集合框架之小结
转载自http://jiangzhengjun.iteye.com/blog/553191 1.Java容器类库的简化图,下面是集合类库更加完备的图.包括抽象类和遗留构件(不包括Queue的实现): ...
- StackExchange.Redis学习笔记(四) 事务控制和Batch批量操作
Redis事物 Redis命令实现事务 Redis的事物包含在multi和exec(执行)或者discard(回滚)命令中 和sql事务不同的是,Redis调用Exec只是将所有的命令变成一个单元一起 ...
- iOS设置圆角的方法及指定圆角的位置
在iOS开发中,我们经常会遇到设置圆角的问题, 以下是几种设置圆角的方法: 第一种方法: 通过设置layer的属性 代码: UIImageView *imageView = [[UIImageView ...
- [最短路]P1828 香甜的黄油 Sweet Butter
题目描述 农夫John发现做出全威斯康辛州最甜的黄油的方法:糖.把糖放在一片牧场上,他知道N(1<=N<=500)只奶牛会过来舔它,这样就能做出能卖好价钱的超甜黄油.当然,他将付出额外的费 ...
- 大神博客链接系列---C#SubSonic3.0搭建ORM
一.C#框架 C#ORM框架: SubSonic3.0制作ORM--- http://www.cnblogs.com/EmptyFS/p/3659679.html
- 微信小程序与Java后台的通信
一.写在前面 最近接触了小程序的开发,后端选择Java,因为小程序的代码运行在腾讯的服务器上,而我们自己编写的Java代码运行在我们自己部署的服务器上,所以一开始不是很明白小程序如何与后台进行通信的, ...
- Java数据结构和算法(三)——冒泡、选择、插入排序算法
上一篇博客我们实现的数组结构是无序的,也就是纯粹按照插入顺序进行排列,那么如何进行元素排序,本篇博客我们介绍几种简单的排序算法. 1.冒泡排序 这个名词的由来很好理解,一般河水中的冒泡,水底刚冒出来的 ...
- C语言之浮点数
#include<stdio.h> int main(){printf("请分别输入身高的英尺和英寸," "如输入\"5 7\"表示5英尺 ...