| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1375 人关注过本帖
标题:求大佬压缩一下我这题的时间复杂度。给定 n 个数 a1,a2,...,an ,求满足条件 ...
只看楼主 加入收藏
Fjun
Rank: 1
等 级:新手上路
帖 子:9
专家分:0
注 册:2017-3-30
结帖率:100%
收藏
已结贴  问题点数:5 回复次数:6 
求大佬压缩一下我这题的时间复杂度。给定 n 个数 a1,a2,...,an ,求满足条件的 (i,j) 数量: i<j 且 a[i]<a[j]
★实验任务
给定n个数a1,a2,...,an,求满足条件的(i,j)数量:i<j且a[i]<a[j]
★数据输入
输入第一行为一个正整数n。第二行为n个数,第i个代表ai。
对于90%的数据,1<=n<=6666;对于100%的数据,1<=n<=100086,0<=ai<=1000,000,000;
★数据输出
输出满足条件的(i, j)的数量。
输入示例
输出示例
5
9 1 5 2 2
3
输入示例
输出示例
7
4 3 1 5 5 5 2
10




我就最普通的两重循环了一下,会超时,有什么时间复杂度小的解法吗?
#include<iostream>  
using namespace std;  
int a[100089];  
int main(){  
    int n ,i ,j ,count = 0 ;   
    cin>>n;  
    for(i=1 ;i<=n ;i++)  
        cin>>a[i];  
    for(i=1 ;i<n ;i++){  
        for(j=i+1 ;j<=n ;j++){  
            if(a[j] >a[i])  
               count++;  
        }  
    }  
    cout<<count;  
    return 0;  
}
搜索更多相关主题的帖子: 个数 条件 数量 输入 输出 
2017-09-26 17:31
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:528
帖 子:9007
专家分:53942
注 册:2011-1-18
收藏
得分:3 
从左至右,不停地插入排序,二分查找
9大于{}中的0个
1大于{9}中的0个
5大于{1,9}中的1个
2大于{1,5,9}中的1个
2大于{1,2,5,9}中的1个
共3个
2017-09-26 19:16
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:528
帖 子:9007
专家分:53942
注 册:2011-1-18
收藏
得分:0 
原来是C++呀,为什么在C论坛提问?
用scanf替代cin试试,会缩短时间
2017-09-26 19:19
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
收藏
得分:3 
r版的实现方法理论上效率超高~但实际上插入排序用数组的话感觉还是要移动数组的~插入排序本来的时间复杂度还是o(n^2)当然可以用链表结构……不过这样就不能用数组下标进行二分法查找了~当然可以用平衡树~但这个算法复杂度非常大……所以感觉可以考虑用时间复杂度为o(nlogn)的排序方法试试~

[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-09-27 00:24
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:528
帖 子:9007
专家分:53942
注 册:2011-1-18
收藏
得分:0 
回复 4楼 九转星河
对C++而言很简单,因为红黑树std::set(双端队列std::deque也不错)和二分std::lower_bound都已经有了
2017-09-27 00:48
九转星河
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:长长久久
等 级:贵宾
威 望:52
帖 子:5023
专家分:14003
注 册:2016-10-22
收藏
得分:0 
回复 5楼 rjsp
这样啊……C++的看来我还是见识到了~

[此贴子已经被作者于2017-9-27 00:56编辑过]


[code]/*~个性签名:bug是什么意思?bug是看上去没有可能的东西实际上是有可能做到的 就是这样~2018-08-08更~*/[/code]
2017-09-27 00:51
rjsp
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:版主
威 望:528
帖 子:9007
专家分:53942
注 册:2011-1-18
收藏
得分:0 
回复 6楼 九转星河
经过测试,结果很意外,使用平衡树反而是最慢的
对于100086个数据:
无优化原始算法,耗时  30.496 秒
使用平衡树容器,耗时 284.290 秒
使用链表作容器,耗时 117.960 秒
用分段数组容器,耗时   3.049 秒
使用简单的数组,耗时   1.412 秒

记得以前听说过一句话“现代CPU上,数组插入数据其实比链表插入数据还快”,看起来真是这样,平衡树因为数据分散,内存页面切换会耗费掉大量时间。

以下是测试代码:
程序代码:
#include <iostream>
#include <random>
#include <functional>
#include <chrono>
#include <algorithm>
#include <set>
#include <deque>
#include <list>
#include <vector>
using namespace std;

size_t foo1( const unsigned a[], size_t size ) // 无任何优化
{
    size_t num = 0;
    for( size_t i=0; i!=size; ++i )
        for( size_t j=i+1; j!=size; ++j )
            if( a[j] > a[i] )
                ++num;
    return num;
}

size_t foo2( const unsigned a[], size_t size ) // 平衡树
{
    size_t num = 0;
    std::multiset<unsigned> buf;
    for( size_t i=0; i!=size; ++i )
    {
        num += distance( buf.begin(), std::lower_bound(buf.begin(),buf.end(),a[i]) );
        buf.insert( a[i] );
    }
    return num;
}

size_t foo3( const unsigned a[], size_t size ) // 链表
{
    size_t num = 0;
    std::list<unsigned> buf;
    for( size_t i=0; i!=size; ++i )
    {
        auto p = std::lower_bound(buf.begin(),buf.end(),a[i]);
        num += distance( buf.begin(), p );
        buf.insert( p, a[i] );
    }
    return num;
}

size_t foo4( const unsigned a[], size_t size ) // 分段数组
{
    size_t num = 0;
    std::deque<unsigned> buf;
    for( size_t i=0; i!=size; ++i )
    {
        auto p = std::lower_bound(buf.begin(),buf.end(),a[i]);
        num += distance( buf.begin(), p );
        buf.insert( p, a[i] );
    }
    return num;
}

size_t foo5( const unsigned a[], size_t size ) // 数组
{
    size_t num = 0;
    std::vector<unsigned> buf;
    buf.reserve( size );
    for( size_t i=0; i!=size; ++i )
    {
        auto p = std::lower_bound(buf.begin(),buf.end(),a[i]);
        num += distance( buf.begin(), p );
        buf.insert( p, a[i] );
    }
    return num;
}

void test( unsigned foo(const unsigned [],size_t) )
{
    std::array<unsigned,100086> a;
    std::generate( begin(a), end(a), std::bind(std::uniform_int_distribution(0u,1000'000'000u),std::default_random_engine(0)) );
    std::chrono::time_point<std::chrono::steady_clock> now = std::chrono::steady_clock::now();
    unsigned n = foo( &a[0], a.size() );
    std::chrono::time_point<std::chrono::steady_clock> cur = std::chrono::steady_clock::now();
    std::cout << "result = " << n << ", Takes " << std::chrono::duration_cast<std::chrono::milliseconds>(cur-now).count() << " milliseconds.\n";
}

int main( void )
{
    test( foo1 );
    test( foo2 );
    test( foo3 );
    test( foo4 );
    test( foo5 );
}

收到的鲜花
  • 九转星河2017-09-27 10:28 送鲜花  20朵   附言:我很赞同
2017-09-27 10:09
快速回复:求大佬压缩一下我这题的时间复杂度。给定 n 个数 a1,a2,...,an ,求满 ...
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.023802 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved