zoukankan      html  css  js  c++  java
  • [作业系列]算法第二章上机实践报告

    1.实践题目:

    两个有序序列的中位数 

    2.问题描述:

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

    输入格式:

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

    输出格式:

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

    3.算法描述:

    #include<iostream>
    using namespace std;
    const int maxn = 2e5+5;
    int a[maxn];
    int n,x,cnt=1; 
    int main()
    {
        		cin>>n;
        for(int i=1;i<=2*n;i++)
                cin>>a[i];
                int cnt1=1,cnt2=n+1;
        for(;cnt<n+1;cnt++){
         	if  (a[cnt1]<a[cnt2])     	x=a[cnt1++];
         	else                     	x=a[cnt2++];
        }
                cout<<x<<endl;
    }
    

      

    开两个数组存两个序列,然后用两个指针从头按大小一路扫过去并用,cnt和x记录新序列的位置和值,由于没有去重,那么新序列的中位数就是指针扫到n时的值。

    4.算法时间及空间复杂度分析:

    由于是线性的直接遍历一遍,所以时间复杂度是O(N)的;

    空间复杂度上,我开了1个2e5+5的数组,所以空间复杂度是O(2e5);

    5.心得体会

    这题虽然说是并集但其实不用去重,去重的话你最后一个样例是过不了的,因为这个原因我debug了大半小时。

    其实这题还有一个log的算法,大概的思路是先在两个序列里找到N/2的子序列,判断子序列的最大值(由于是有序的,这个可以O(1)达到)把小的那个序列扔出去,并且维护扔出去的元素的最大值,然后在从小到大找到max(N/4,1)的子序列,再一次把小的那个子序列扔出去,维护扔出去的元素的最大值(包含之前扔出去的元素),继续对接下来的序列进行同样的操作(长度变为max(N/8,1)).......直至扔出的序列长度达到N,此时扔出去的最大值就是所要求的中位数,这个时间复杂度度是log级别的,因为每次都进行了二分的操作(寻找子序列的位置的时候由于是有序的所以是O(1)的),这个由于一开始没想出来所以我也没有敲代码,不过思路上来讲挺好实现的。

    想了一下还是补充一下log的代码吧(没有特意出测试来调,但应该没错)

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn =1e5+5;
    int a[maxn];
    int b[maxn]; 
    int main()
    {
    	int n,mid1=0,mid2=0;
    	cin>>n;
    	for(int i=1;i<=n;i++)
    	cin>>a[i];
    	for(int i=1;i<=n;i++)
    	cin>>b[i];
    	int r1=n,r2=n,l1=0,l2=0,len=n,_max=0,l=0;
    	while(l!=n)
    	{
    		len=max(len/2,1);
    		mid1=l1+len;
    		mid2=l2+len;
    	//	cout<<len<<" "<<mid1<<" "<<mid2<<endl;
    		if(a[mid1]<b[mid2])
    		{
    			_max=max(_max,a[mid1]);
    			l1=mid1;
    	//		cout<<_max<<"   A"<<endl;
    		}
    		else
    		{
    			_max=max(_max,b[mid2]);
    			l2=mid2;
    	//		cout<<_max<<"   B"<<endl;
    		}
    		l+=len;
    	}
    	cout<<_max<<endl;
    }
    

      

  • 相关阅读:
    javascript小括号、中括号、大括号学习总结
    第二次面试
    Python 类编码风格
    Python常见初级错误
    2.傅里叶变换
    1.仿射变换
    Leetcode 136. 只出现一次的数字
    003 Python与类C语言的区别(未完)
    01 C++ 多线程入门实例
    Leetcode 503. 下一个更大元素 II
  • 原文地址:https://www.cnblogs.com/kgs719/p/9784167.html
Copyright © 2011-2022 走看看