第3关:寻找两个等长有序序列的中位数

TOC\]寻找两个等长有序序列的中位数 对于一个长度为n的有序序列(假设均为升序序列)a\[0...n-1\],处于中间位置的元素称为a的中位数。 设计一个算法求给定的两个有序序列的中位数。 例如,若序列a=(11,13,15,17,19),其中位数是15,若b=(2,4,6,8,20),其中位数为6。两个等长有序序列的中位数是含它们所有元素的有序序列的中位数,例如a、b两个有序序列的中位数为11。 任务描述 本关任务:编写一个能计算两个等长有序序列的中位数。 相关知识 如何求解? 对于含有n个元素的有序序列a\[s...t\],当n为奇数时,中位数是出现在m=(s+t)/2(下取整)处;当n为偶数时,中位数下标有m=(s+t)/2(下取整)(下中位)和m=(s+t)/2+1(上取整)(上中位)两个。为了简单,仅考虑中位数为m=(s+t)/2(下取整)处。 采用二分法求含有n个有序元素的序列a、b的中位数的过程如下: (1)若n=1,较小者为中位数。 (2)其他又分为3种情况。 分别求出a、b的中位数a\[m1\]和b\[m2\]:   ① 若a\[m1\]=b\[m2\],则a\[m1\]或b\[m2\]即为所求中位数,算法结束。 ② 若a\[m1\]\b\[m2\],则舍弃序列a中后半部分(较大的一半),同时舍弃序列b中前半部分(较小的一半),要求舍弃的长度相等。舍弃一半即n/2个元素。 编程要求 根据提示,在右侧编辑器补充代码,计算并输出两个等长有序序列的中位数。 测试说明 平台会对你编写的代码进行测试 测试输入:5 11,13,15,17,19 2,4,6,8,20 输出结果: a:11 13 15 b:6 8 20 a:11 13 b:8 20 a:11 b:20 中位数:11 开始你的任务吧,祝你成功! ```java import java.util.Scanner; // 导入Scanner类用于输入 import java.util.Arrays; // 导入Arrays类用于数组操作 /** * @author hainingLi */ public class MinNUMBER { /begin // 定义方法用于查找两个已排序数组的中位数 // 定义的数组,中位数,查找中位数 public static int findMedianSortedArrays(int[] a, int[] b) { // 定义的一个findMedian, 数组排序的方法。分别传三叔 数组,对数组啊,和b 进行操作。 while (a.length > 1 && b.length > 1) { // 当两个数组长度都大于1时循环 int amid = a[a.length / 2]; // 获取数组a的中位数 ,a[a.length/2] int bmid = b[b.length / 2]; // 获取数组b的中位数 // 特殊情况处理:数组长度为2时直接取第一个元素 if (a.length == 2) { // 如果a.length 的长度为2 amid = a[0]; // 数组的第一个元素就是中位数 bmid = b[0]; // 数组第一个元素就是中位数 } // 根据中位数大小决定如何切分数组 // 根据中位数的大小决定如何切分数组 if (amid < bmid) { // 如果第一个数组的中位数小于第二个数组的中位数 a = Arrays.copyOfRange(a, a.length / 2, a.length); // 将a数组切分为后半部分 b = Arrays.copyOf(b, (b.length + 1) / 2); // 将b数组切分为前半部分 // 打印当前数组状态 // 打印当前数组的状态 System.out.print("a:"); for (int i = 0; i < a.length; i++) { System.out.print(a[i] + " "); // 打印数组a的当前状态 } System.out.println(); // 换行 System.out.print("b:"); for (int i = 0; i < b.length; i++) { // 遍历第二个数组 System.out.print(b[i] + " "); // 打印数组b的当前状态 } System.out.println(); // 换行 } else { b = Arrays.copyOfRange(b, b.length / 2, b.length); // 将b数组切分为后半部分 a = Arrays.copyOf(a, (a.length + 1) / 2); // 将a数组切分为前半部分 // 打印当前数组状态 System.out.print("a:"); for (int i = 0; i < a.length; i++) { System.out.print(a[i] + " "); // 打印数组a的当前状态 } System.out.println(); // 换行 System.out.print("b:"); for (int i = 0; i < b.length; i++) { System.out.print(b[i] + " "); // 打印数组b的当前状态 } System.out.println(); // 换行 } } // 当其中一个数组为空时,返回非空数组的第一个元素作为中位数 if (a.length == 0) { return b[0]; } if (b.length == 0) { return a[0]; } // 返回两数组首元素中较小的那个作为中位数 return Math.min(a[0], b[0]); // 返回两个数组元素中较小的那个作为中位数 } public static void main(String[] args) { Scanner scanner = new Scanner(System.in); // 创建Scanner对象用于读取输入 // 读取输入的数组长度 int n = scanner.nextInt(); // 输入的随机数n scanner.nextLine(); // 读取换行符 // 读取第一个数组的元素 String[] aInput = scanner.nextLine().split("\\s+"); // 随机数组,第一个 int[] a = new int[aInput.length]; // 循环第一个数组元素 放到新的额数组a中 for (int i = 0; i < n; i++) { // 遍历这个随机输入的这个n 数 a[i] = Integer.parseInt(aInput[i].trim()); // 将字符串转换为整数 } // 读取第二个数组的元素 String[] bInput = scanner.nextLine().split("\\s+"); int[] b = new int[bInput.length]; for (int i = 0; i < n; i++) { b[i] = Integer.parseInt(bInput[i].trim()); // 将字符串转换为整数 } // 对输入的数组进行排序 Arrays.sort(a); Arrays.sort(b); // 计算并输出中位数 int median = findMedianSortedArrays(a, b); // 调用方法计算中位数 这个中位数是两个数组中较小的中位数 System.out.print("中位数:" + median); // 输出中位数 // 关闭scanner以释放资源 scanner.close(); } } ```

相关推荐
coderSong25683 分钟前
Java高级 |【实验八】springboot 使用Websocket
java·spring boot·后端·websocket
Mr_Air_Boy1 小时前
SpringBoot使用dynamic配置多数据源时使用@Transactional事务在非primary的数据源上遇到的问题
java·spring boot·后端
豆沙沙包?1 小时前
2025年- H77-Lc185--45.跳跃游戏II(贪心)--Java版
java·开发语言·游戏
年老体衰按不动键盘2 小时前
快速部署和启动Vue3项目
java·javascript·vue
咖啡啡不加糖2 小时前
Redis大key产生、排查与优化实践
java·数据库·redis·后端·缓存
liuyang-neu2 小时前
java内存模型JMM
java·开发语言
int型码农2 小时前
数据结构第八章(一) 插入排序
c语言·数据结构·算法·排序算法·希尔排序
UFIT2 小时前
NoSQL之redis哨兵
java·前端·算法
喜欢吃燃面2 小时前
C++刷题:日期模拟(1)
c++·学习·算法
刘 大 望2 小时前
数据库-联合查询(内连接外连接),子查询,合并查询
java·数据库·sql·mysql