两个无序数组分别叫A和B,长度分别是m和n,求中位数,要求时间复杂度O(m+n),空间复杂度O(1) 。
#include <iostream>
using namespace std;
/*函数作用:取待排序序列中low、mid、high三个位置上数据,选取他们中间的那个数据作为枢轴*/
int median(int arr[], int b[], int len1, int low, int high) {
int mid = low + ((high - low) >> 1); //计算数组中间的元素的下标
int &lowData = low >= len1 ? b[low - len1] : arr[low];
int &midData = mid >= len1 ? b[mid - len1] : arr[mid];
int &highData = high >= len1 ? b[high - len1] : arr[high];
//使用三数取中法选择枢轴
if (midData > highData) //目标: arr[mid] <= arr[high]
{
swap(midData, highData);
}
if (lowData > highData) //目标: arr[low] <= arr[high]
{
swap(lowData, highData);
}
if (midData > lowData) //目标: arr[low] >= arr[mid]
{
swap(midData, lowData);
}
//此时,arr[mid] <= arr[low] <= arr[high]
return lowData;
//low的位置上保存这三个位置中间的值
//分割时可以直接使用low位置的元素作为枢轴,而不用改变分割函数了
}
int kth_elem(int a[], int b[], int len1, int low, int high, int k) {
int pivot = median(a, b, len1, low, high);
//要么是选取数组中中位数作为枢纽元,保证最坏情况下,依然为线性O(N)的平均时间复杂度。
int low_temp = low;
int high_temp = high;
while (low < high) {
int tmp = high >= len1 ? b[high - len1] : a[high];
while (low < high && tmp >= pivot) {
--high;
tmp = high >= len1 ? b[high - len1] : a[high];
}
if (low >= len1) {
b[low - len1] = tmp;
} else {
a[low] = tmp;
}
int tmp1 = low >= len1 ? b[low - len1] : a[low];
while (low < high && tmp1 < pivot) {
++low;
tmp1 = low >= len1 ? b[low - len1] : a[low];
}
if (high >= len1) {
b[high - len1] = tmp1;
} else {
a[high] = tmp1;
}
}
if (low >= len1) {
b[low - len1] = pivot;
} else {
a[low] = pivot;
}
//以下就是主要思想中所述的内容
if (low == k - 1) {
if (low >= len1) {
return b[low - len1];
}
return a[low];
} else if (low > k - 1)
return kth_elem(a, b, len1, low_temp, low - 1, k);
else
return kth_elem(a, b, len1, low + 1, high_temp, k);
}
void printArray(int* arr, int len) {
if (!arr) {
return;
}
for (int i = 0; i < len; ++i) {
cout << arr[i] << " ";
}
cout << endl;
}
void print2SortedArray(int* a, int* b, int len1, int len2) {
int* arr = new int[len1 + len2];
for (int i = 0; i < len1; ++i) {
arr[i] = a[i];
}
for (int i = len1, j = 0; j < len2; ++i, j++) {
arr[i] = b[j];
}
sort(arr, arr + len1 + len2);
printArray(arr, len1 + len2);
delete arr;
}
int main() {
int arr1[] = { 2, 12, 5, 10, 43, 24, 33, 4 };
int arr2[] = { 10, 23, 41, 70, 84, 29, 6 };
int len1 = sizeof(arr1) / sizeof(int);
int len2 = sizeof(arr2) / sizeof(int);
print2SortedArray(arr1, arr2, len1, len2);
int mid1 = (len1 + len2) / 2 + 1;
int mid2 = (len1 + len2) % 2 == 0 ? mid1 - 1 : mid1;
int midData1 = kth_elem(arr1, arr2, len1, 0, len1 + len2 - 1, mid1);
int midData2 = kth_elem(arr1, arr2, len1, 0, len1 + len2 - 1, mid2);
// cout << midData1 << ',' << midData2 << endl;
cout << "中位数: " << (midData1 + midData2) / 2 << endl;
return 0;
}
两个无序数组分别叫A和B,长度分别是m和n,求中位数,要求时间复杂度O(m+n),空间复杂度O(1) 。的更多相关文章
- 已知大小分别为m、n的两个无序数组A、B和一个常数c,求满足A[i]+B[j]=c的所有A[i]和B[j]
方法一:枚举法.该方法是最容易.也是最简单的方法,枚举出数组A和数组B中所有的元素对,判断其和是否为c,如果是,则输出. 方法二:排序+二分查找法.首先,对两个数组中长度较大数组,不妨设为A,排序:然 ...
- 从0打卡leetcode之day 5 ---两个排序数组的中位数
前言 我靠,才坚持了四天,就差点不想坚持了.不行啊,我得把leetcode上的题给刷完,不然怕是不好进入bat的大门. 题目描述 给定两个大小为 m 和 n 的有序数组 nums1 和 nums2 . ...
- 如何寻找无序数组中的第K大元素?
如何寻找无序数组中的第K大元素? 有这样一个算法题:有一个无序数组,要求找出数组中的第K大元素.比如给定的无序数组如下所示: 如果k=6,也就是要寻找第6大的元素,很显然,数组中第一大元素是24,第二 ...
- 对无序数组的并发搜索的java实现
对无序数组的并发搜索的实现可以充分的用到多cpu的优势 一种简单的策略是将原始数组按照期望的线程数进行分割,如果我们计划使用两个线程进行搜索,就可以把一个数组分成两个,每个线程各自独立的搜索,当其中有 ...
- 从长度为 M 的无序数组中,找出N个最小的数
从长度为 M 的无序数组中,找出 N个最小的数 在一组长度为 n 的无序的数组中,取最小的 m个数(m < n), 要求时间复杂度 O(m * n) 网易有道面试题 const minTopK ...
- 无序数组求第K大的数
问题描述 无序数组求第K大的数,其中K从1开始算. 例如:[0,3,1,8,5,2]这个数组,第2大的数是5 OJ可参考:LeetCode_0215_KthLargestElementInAnArra ...
- [LeetCode] Median of Two Sorted Arrays 两个有序数组的中位数
There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the two ...
- 取两个String数组的交集
import org.testng.annotations.Test; import java.util.HashMap; import java.util.LinkedList; import ja ...
- 有1,2,3一直到n的无序数组,排序
题目:有1,2,3,..n 的无序整数数组,求排序算法.要求时间复杂度 O(n), 空间复杂度O(1). 分析:对于一般数组的排序显然 O(n) 是无法完成的. 既然题目这样要求,肯定原先的数组有一定 ...
随机推荐
- JS实现手机访问pc网址自动跳转到wap网站
之前写pc端直接跳转wap端一直是后端java写的,跟js一样都是根据navigator.userAgent来判断设备是电脑还是手机的,我知道这种前端也可已完成的功能,只是后台比较强势,本人本着以和为 ...
- bootStrap Table 如何使用
最近在使用bootStrap Table 的表格功能有一些自己的理解写下来分享一下主要用的是一个bootStrapTable 和 jquery 的混合开发 具体怎样引入bootStrap Table ...
- Linux(七)开机,重启和用户登录注销
7.1 关机&重启命令 基本介绍: shutdown -h now 立刻进行关机 shutdown -h 1 1分钟后关机 shutdown -r now ...
- [POI 2006]OKR-Periods of Words
Description 题库链接 定义 \(A\) 串为 \(B\) 串的循环串,当且仅当 \(A\) 是 \(B\) 的前缀(不包括 \(B\) 本身),且 \(B\) 为连续的 \(A\) 串拼接 ...
- [HNOI 2010]Planar
Description 题库链接 给出 \(T\) 个 \(N\) 个节点 \(M\) 条边的无向图(无重边自环),并给出它们各自的哈密顿回路.分别判断每个图是否是平面图. \(T\leq 100,3 ...
- [HNOI 2017]单旋
Description H 国是一个热爱写代码的国家,那里的人们很小去学校学习写各种各样的数据结构.伸展树(splay)是一种数据 结构,因为代码好写,功能多,效率高,掌握这种数据结构成为了 H 国的 ...
- [HNOI2012]射箭
Description 沫沫最近在玩一个二维的射箭游戏,如下图 1 所示,这个游戏中的 x 轴在地面,第一象限中有一些竖直线段作为靶子,任意两个靶子都没有公共部分,也不会接触坐标轴.沫沫控制一个位于( ...
- [USACO12JAN]爬山Mountain Climbing
题目描述 Farmer John has discovered that his cows produce higher quality milk when they are subject to s ...
- 如何在Windows系统中设置Python程序定时运行
文章出处:http://blog.csdn.net/wwy11/article/details/51100432 首先,我们肯定是要用到Windows下的[计划任务]功能 之后点击右侧的[创建基本任务 ...
- Cisco 的基本配置实例之四----vlan的规划及配置(核心交换机)
4.vlan的规划及配置 在本节中我们讲解vlan的规划及具体的配置命令.在此例中我们用的是vtp(VLAN Trunking Protocol)server的模式,在这种模式中我们需要配置核心交换机 ...