zoukankan      html  css  js  c++  java
  • 算法第二章上机实践报告

    题目: 两个有序序列的中位数 

    已知有两个等长的非降序序列S1, S2, 设计函数求S1与S2并集的中位数。有序序列,的中位数指A(N1)/2​​的值,即第⌊个数(A0​​为第1个数)。

    输入格式:

    输入分三行。第一行给出序列的公共长度N(0<N≤100000),随后每行输入一个序列的信息,即N个非降序排列的整数。数字用空格间隔。

    输出格式:

    在一行中输出两个输入序列的并集序列的中位数。


    题目需求:时间复杂度为 O(logN)

    解题思路:在考虑时间复杂度之前,一开始考虑的是使用第三个数组去归并两个数组,结果显然无法满足时间复杂度的需求;
    结合二分查找法以及分治法的思想,对两个有序数组进行二分,通过不断比较中位数来求得;
    可以用调用递归的方法去解决

    方法步骤:1)递归函数中的判断条件:当子数列仅剩一个数时,返回较小的数就是所求解;
    2)若当前ma > mb 下一次递归就取a左边的子数列和b右边的子数列,反之逆推;
    3)而且要保证两个数列的元素个数相同,若为偶数数列,则需要ma++或mb++;
    代码:
     1 #include<iostream>
     2 using namespace std;
     3 int a[100001],b[100001];
     4 
     5 int find(int la, int lb, int ra, int rb) {
     6     if (la == ra && lb == rb) {
     7         return a[la] > b[lb] ? b[lb] : a[la];
     8     }
     9     
    10     int ma = (la + ra) / 2;
    11     int mb = (lb + rb) / 2;
    12     
    13     if (a[ma] < b[mb]) {
    14         rb = mb;
    15         if ((ra - la) % 2) {
    16             ma++;
    17         }
    18         la = ma;
    19     } else {
    20         ra = ma;
    21         if ((rb - lb) % 2) {
    22             mb++;
    23         }
    24         lb = mb;
    25     }
    26      return find(la,lb,ra,rb);
    27 }
    28 
    29 
    30 int main() {
    31     int N;
    32     cin >> N;
    33     
    34     for (int i = 0; i < N; ++i) {
    35         cin >> a[i];
    36     }
    37     for (int i = 0; i < N; ++i) {
    38         cin >> b[i];
    39     }
    40     cout << find(0 , 0, N - 1, N - 1);
    41     return 0;
    42 }
    View Code

    算法分析:

         时间复杂度:二分查找:O(logN),输入数据:O(N),所以是O(logN);

         空间复杂度:并没有借助辅助变量,所以为O(1);

    心得体会:

         二分法虽然作用很大,但在实际运用中一定要先构思好左右两端是如何移动变换的,最好动手动笔,先画出示意图,这样更能便于代码书写。



  • 相关阅读:
    从句分析
    artDialog ( v 6.0.2 ) content 参数引入页面 html 内容
    Java实现 LeetCode 13 罗马数字转整数
    Java实现 LeetCode 13 罗马数字转整数
    Java实现 LeetCode 13 罗马数字转整数
    Java实现 LeetCode 12 整数转罗马数字
    Java实现 LeetCode 12 整数转罗马数字
    Java实现 LeetCode 12 整数转罗马数字
    Java实现 LeetCode 11 盛最多水的容器
    Java实现 LeetCode 11 盛最多水的容器
  • 原文地址:https://www.cnblogs.com/gwpsf/p/11567270.html
Copyright © 2011-2022 走看看