zoukankan      html  css  js  c++  java
  • 【每天一道算法题】时间复杂度为O(n)的排序

    有1,2,……一直到n的无序数组,求排序算法,并且要求时间复杂度为O(n),空间复杂度为O(1),使用交换,而且一次只能交换两个数。

    这个是以前看到的算法题,题目不难。但是要求比较多,排序算法中,时间复杂度为O(n)就是基数排序了。

    现在介绍两种解法:

    解法一:用数组特性——下标实现交换

    扫描数组,每次arr[i],arr[arr[i]-1]交换,如果arr[i]=i+1,则什么都不做。这样交换一次保证一个数字被放到它应该被放置的位置上。最后数组有序。

    #include <vector>
    #include <iostream>
    using namespace std;
    
    void swap(int& a, int& b){
        a^=b;
        b^=a;
        a^=b;
    }
    vector<int>& Sort(vector<int>& vec1){
        if(vec1.size()==1)
            return vec1;
        for(int i=0;i<vec1.size();){
            if(vec1[i]==i+1)
                i++;
            else swap(vec1[i],vec1[vec1[i]-1]);
        }
        return vec1;
    }
    int main(){
        int arr[9]={1,3,7,2,9,6,8,5,4};
        vector<int> vec2(arr,arr+9);
        Sort(vec2);
        for(int i=0;i<vec2.size();i++)
            cout<<vec2[i]<<"    ";
        return 0;
    }

    上面的题目是每个数字只出现一次,如果不限制出现的次数,要求时间复杂度是O(n),空间复杂度为O(1)又该怎么做,给出数字的最大范围假设为65536。

    这个题用桶排序应该可以做。

    解法二:利用count[65536](和n无关,空间复杂度为O(1))数组记录出现的次数

    那么假设有下面这些数字:

    100
    200
    300
    119
    0
    6
    ...
    那么对于每个这个数字,都做在count中记录一下:
    100 => count[100]++
    200 => count[200]++
    300 => count[300]++
    119 => count[119]++
    0 => count[0]++
    6 => count[6]++
     
    最后,遍历一边所有这些数字就可得到0~65535每个数字的个数(在count数组中),然后再顺序遍历count数组,count[n] = m,则输出m个n,(比如说有count[3] = 2, 那么说明有2个数字3),依次输出,最后可得结果。
  • 相关阅读:
    VisualSVN-Server windows 版安装时报错 "Service 'VisualSVN Server' failed to start. Please check VisualSVN Server log in Event Viewer for more details."
    Pytest 单元测试框架之初始化和清除环境
    Pytest 单元测试框架入门
    Python(email 邮件收发)
    Python(minidom 模块)
    Python(csv 模块)
    禅道简介
    2020年最好的WooCommerce主题
    Shopify网上开店教程(2020版)
    WooCommerce VS Magento 2020:哪个跨境电商自建站软件更好?
  • 原文地址:https://www.cnblogs.com/LUO77/p/5780187.html
Copyright © 2011-2022 走看看