有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()==)
return vec1;
for(int i=;i<vec1.size();){
if(vec1[i]==i+)
i++;
else swap(vec1[i],vec1[vec1[i]-]);
}
return vec1;
}
int main(){
int arr[]={,,,,,,,,};
vector<int> vec2(arr,arr+);
Sort(vec2);
for(int i=;i<vec2.size();i++)
cout<<vec2[i]<<" ";
return ;
}

上面的题目是每个数字只出现一次,如果不限制出现的次数,要求时间复杂度是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),依次输出,最后可得结果。

【每天一道算法题】时间复杂度为O(n)的排序的更多相关文章

  1. 每天一道算法题(4)——O(1)时间内删除链表节点

    1.思路 假设链表......---A--B--C--D....,要删除B.一般的做法是遍历链表并记录前驱节点,修改指针,时间为O(n).删除节点的实质为更改后驱指针指向.这里,复制C的内容至B(此时 ...

  2. 从一道算法题实现一个文本diff小工具

    众所周知,很多社区都是有内容审核机制的,除了第一次发布,后续的修改也需要审核,最粗暴的方式当然是从头再看一遍,但是编辑肯定想弄死你,显然这样效率比较低,比如就改了一个错别字,再看几遍可能也看不出来,所 ...

  3. 提前批笔试一道算法题的Java实现

    题目描述 这是2021广联达校招提前批笔试算法题之一. 我们希望一个序列中的元素是各不相同的,但是理想和显示往往是有差距的.现在给出一个序列A,其中难免有相同的元素,现在提供了一种变化方式,使得经过若 ...

  4. 每天一道算法题-leetcode136-只出现一次的数字

    前言 打卡第一天 2019.10.26日打卡 算法,即解决问题的方法.同一个问题,使用不同的算法,虽然得到的结果相同,但是耗费的时间和资源是不同的.这就需要我们学习算法,找出哪个算法更好. 大家都知道 ...

  5. 每天一道算法题(14)——N个降序数组,找到最大的K个数

     题目: 假定有20个有序数组,每个数组有500个数字,降序排列,数字类型32位uint数值,现在需要取出这10000个数字中最大的500个. 思路 (1).建立大顶堆,维度为数组的个数,这里为20( ...

  6. 一道算法题加深我对C++中map函数的理解

    一.一道题目引发我对map函数的考量 首先是题目大意:有n个银行,a[i]表示这个人在第i个银行有a[i]块钱(可以是负数),所有银行的钱加起来正好是0.每次只能在相邻的银行之间转账,问最少要转多少次 ...

  7. 认真对待每一道算法题 之 两个排序好的数组寻找的第k个大的数

    转载博客:http://www.cnblogs.com/buptLizer/archive/2012/03/31/2427579.html 题目意思:给出两个排好序的数组 ,不妨设为a,b都按升序排列 ...

  8. 《github一天一道算法题》:分治法求数组最大连续子序列和

    看书.思考.写代码. /*************************************** * copyright@hustyangju * blog: http://blog.csdn. ...

  9. 《github一天一道算法题》:插入排序

    看书.思考.写代码! /*********************************************** * copyright@hustyangju * blog: http://bl ...

随机推荐

  1. python简单实现websocket

    协议选择的是新的Hybi-10,参考文章如下: http://www.cnblogs.com/zhuweisky/p/3930780.html http://blog.mycolorway.com/2 ...

  2. spring +springmvc+mybatis组合applicationContext.xml文件配置

    <?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.spr ...

  3. html中的锚点

    一.页面内跳转的锚点设置 页面内的跳转需要两步: 方法一: ①:设置一个锚点链接<a href="#miao">去找喵星人</a>:(注意:href属性的属 ...

  4. es6的新内容

    前端学习总结(十八)ES6--新一代的javascript 发表于2016/6/11 21:44:27  2733人阅读 分类: javascript 简介 ECMAScript 6(以下简称ES6) ...

  5. Iterator、for..of,for...in和自定义遍历器**

    Iterator.for..of,for...in和自定义遍历器 Iterator: var arr = [1,2,3,4,5]; var ite = arr[Symbol.iterator](); ...

  6. 二叉树 - 建立与遍历使用Java

    二叉树的遍历(traversing binary tree)是指从根节点出发,按照某种次序依次访问二叉树中所有节点,使得每个节点仅被访问一次 前序遍历:若二叉树为空,则空操作返回null.否则先访问根 ...

  7. nyoj_600:花儿朵朵(树状数组+坐标离散化)

    http://acm.nyist.net/JudgeOnline/problem.php?pid=600 只附代码好了 #include<bits/stdc++.h> using name ...

  8. Jenkins2 实现持续交付初次演练(MultiJob,Pipeline,Blue Ocean)

    背景 项目需要用到自动部署,但可获取外网的节点机器只有一台,那只能同过主节点机器进行构建完成然后分发至对应服务器进行启动更新. 目前已尝试过三种方式: 1.Pipeline-Trigger param ...

  9. Unity Shader入门教程(四)反射光斑的实现

    本节内容介绍PhongModel(也就是上文说的反射光的计算模型),采用的计算方法是BlinPhong(也即是用视线方向V+光源方向L的和,与N做点积,随后幂化得到高光反射系数)下图采用了csdn博文 ...

  10. es6 解构赋值

    ES6允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring). 关于给变量赋值,传统的变量赋值是这样的: var arr = [1,2,3];//把数组的值 ...