题目:一个大小为N的数组,里面是N个整数,怎样去除重复的数字;

要求时间复杂度为O(n),空间复杂度为O(1).

需要除掉重复的整数的数组,注意这里我没有处理负数情况,其实负数情况只要先用0快排分一下组,然后各自用以下算法进行处理即可。 另外因为是整数,这里没考虑32位符号位,只考虑31位。

题目分析:从要求来看,如果一个数组是排好序的,除掉重复就很简单,因此就转换成了排序算法寻找,这种算法需要满足:线性时间,常量内存,原地置换。但纵观这么多算法,比较排序肯定不行,那么就只有基数排序,桶排序和计数排序,计数排序排除,因为计数排序无法原地置换,桶排序也需要辅助空间,所以最后考虑用 基数排序,基数排序依赖于位排序,而且要求位排序是稳定的, 且不能过多使用辅助空间,这里问题是如何选择位排序,因为位上只有0和1,因此有其特殊性,使用快排的分组就可以达到线性,但问题是这种算法虽然是线性,原地置换,但不稳定。所以要利用一种机制来确保快排是稳定的。经过一段时间思考,发现,如果从高位开始排序,假设前K位是排好的,对K+1进行排序时,只针对前K位的相同的进行,前K位不相同,也不可能相等,第K+1位也不影响结果,而前K位相同的排序,就不怕快排的不稳定了,因为这个不稳定不会影响到最终结果。

C++代码实现如下:

  1. #include<iostream>
  2. using namespace std;
  3. bool isbitof1(int num,int index);//判断num的index位是否为1,index从0开始
  4. void partition_m(int data[],int start,int end,int index,bool (*cond)(int,int));//分割函数
  5. void linear_sort(int data[],int n);//线性排序,基于基数排序,关键字为某位二进制位是0还是1,一共32位
  6. int delete_repeated(int data[],int n);
  7. int main()
  8. {
  9. int N;//数组元素个数
  10. cin>>N;//用户输入
  11. int *data=new int[N];
  12. int i;
  13. for(i=;i<N;i++)
  14. cin>>data[i];//输入数组元素
  15. int len=delete_repeated(data,N);
  16. for(i=;i<len;i++)
  17. cout<<data[i]<<" ";
  18. cout<<endl;
  19. return ;
  20. }
  21. bool isbitof1(int num,int index)
  22. {
  23. num=(num>>=index)&;//判断index位是零还是1
  24. if(num==)
  25. return true;
  26. else
  27. return false;
  28. }
  29. void partition_m(int data[],int start,int end,int index,bool(*cond)(int,int))
  30. {
  31. if(data==NULL||start>end)
  32. return;
  33. int i=start-;
  34. int j=end+;
  35. while(true)
  36. {
  37. do
  38. {
  39. i++;
  40. }while(!cond(data[i],index)&&i<=end);
  41. do
  42. {
  43. j--;
  44. }while(cond(data[j],index)&&j>=start);
  45. if(i>j)
  46. break;
  47. int temp=data[i];
  48. data[i]=data[j];
  49. data[j]=temp;
  50. }
  51. }
  52. void linear_sort(int data[],int n)
  53. {
  54. if(data==NULL||n<=)
  55. return;
  56. int indexofbit,i,processed_bit;
  57. //从高位到低位
  58. for(indexofbit=;indexofbit>=;indexofbit--)
  59. {
  60. int start=;
  61. int end=;
  62. int prev=(data[]>>(indexofbit+))&(0x7FFFFFFF);
  63. for(i=;i<n;i++)
  64. {
  65. processed_bit=(data[i]>>(indexofbit+))&(0x7FFFFFFF);
  66. if(processed_bit==prev)
  67. end=i;
  68. else
  69. {
  70. partition_m(data,start,end,indexofbit,isbitof1);
  71. prev=(data[i]>>(indexofbit+))&(0X7FFFFFFF);
  72. start=i;
  73. end=i;
  74. }
  75.  
  76. }
  77. partition_m(data,start,end,indexofbit,isbitof1);
  78. }
  79. }
  80. int delete_repeated(int data[],int n)
  81. {
  82. linear_sort(data,n);
  83. int i,j;
  84. i=;
  85. j=i+;
  86. while(j<n)
  87. {
  88. if(data[j]!=data[i])
  89. {
  90. i++;
  91. data[i]=data[j];
  92. j++;
  93. }
  94. else
  95. {
  96. j++;
  97. }
  98. }
  99. return i+;
  100. }

转自:http://blog.csdn.net/jirongzi_cs2011/article/details/11626207

更多:http://blog.csdn.net/hawksoft/article/details/6867493

一个大小为N的数组,里面是N个整数,怎样去除重复的数的更多相关文章

  1. 在主方法中定义一个大小为10*10的二维字符型数组,数组名为y,正反对角线上存的是‘*’,其余 位置存的是‘#’;输出这个数组中的所有元素。

    //在主方法中定义一个大小为10*10的二维字符型数组,数组名为y,正反对角线上存的是‘*’,其余 位置存的是‘#’:输出这个数组中的所有元素. char [][]y=new char [10][10 ...

  2. 在主方法中定义一个大小为50的一维整型数组,数组i名为x,数组中存放着{1,3,5,…,99}输出这个数组中的所有元素,每输出十个换一行

    package hanqi; import java.util.Scanner; public class Test7 { public static void main(String[] args) ...

  3. 假设一个大小为100亿个数据的数组,该数组是从小到大排好序的,现在该数组分成若干段,每个段的数据长度小于20「也就是说:题目并没有说每段数据的size 相同,只是说每个段的 size < 20 而已」

    假设一个大小为100亿个数据的数组,该数组是从小到大排好序的,现在该数组分成若干段,每个段的数据长度小于20「也就是说:题目并没有说每段数据的size 相同,只是说每个段的 size < 20 ...

  4. 生成大小为100的数组,从1到100,随机插入,不连续,也不重复[C#]

    生成大小为100的数组,从1到100,随机插入,不连续,也不重复. 实现思路 生成一个100位的集合listA,放1到100 创建一个空的集合listB,用来存放结果 创建一个变量c,临时存储生成的数 ...

  5. C用malloc 向系统申请一个大小为n*4个字节的内存块

    #include <stdio.h> #include <malloc.h> void out(int *p, int n){ int i; for(i=0;i<n;i+ ...

  6. 按要求编写Java应用程序。 编写一个名为Test的主类,类中只有一个主方法; 在主方法中定义一个大小为50的一维整型数组,数组名为x,数组中存放着{1, 3,5,…,99}输出这个数组中的所有元素,每输出十个换一行;在主方法中定义一 个大小为10*10的二维字符型数组,数组名为y,正反对角线上存的是‘*’,其余 位置存的是‘#’;输出这个数组中的所有元素。

    int[]x=new int [50]; char[][]y=new char[10][10]; int j=1,w=0; for(int i=0;i<50;i++) { x[i]=j; j+= ...

  7. 编写一个名为Test的主类,类中只有一个主方法; 在主方法中定义一个大小为50的一维整型数组,数组名为x,数组中存放着{1, 3,5,…,99}输出这个数组中的所有元素,每输出十个换一行;在主方法中定义一 个大小为10*10的二维字符型数组,数组名为y,正反对角线上存的是‘*’,其余 位置存的是‘#’;输出这个数组中的所有元素。

    package liu0915; import java.util.Random; public class Test0915sz { public static void main(String[] ...

  8. 16.按要求编写Java应用程序。 编写一个名为Test的主类,类中只有一个主方法; 在主方法中定义一个大小为50的一维整型数组,数组名为x,数组中存放着{1, 3,5,…,99}输出这个数组中的所有元素,每输出十个换一行;在主方法中定义一 个大小为10*10的二维字符型数组,数组名为y,正反对角线上存的是‘*’,其余 位置存的是‘#’;输出这个数组中的所有元素。

    //分类 package com.bao; public class Shuchu { int[]yi=new int[50]; String[][]er=new String[10][10]; vo ...

  9. 给定数组A,大小为n,现给定数X,判断A中是否存在两数之和等于X

    题目:给定数组A,大小为n,现给定数X,判断A中是否存在两数之和等于X 思路一: 1,先采用归并排序对这个数组排序, 2,然后寻找相邻<k,i>的两数之和sum,找到恰好sum>x的 ...

随机推荐

  1. python 中去除BOM头

    在window的环境下,保存的文本文档会加上三个字符0xEF 0xBB 0xBF的头部,这三个字符可能会影响对文本的读取,形成乱码,在这里记录下如何避免. 首先发现直接保存为ASCII的文本文件是不包 ...

  2. 使用正则表达式限制TextBox输入

    /// <summary> /// 使用正则表达式限制输入 /// </summary> public class TextBoxRegex : TextBox { // 正则 ...

  3. linux自带有usb驱动,为什么还需要libusb呢

    linux里的软件分为用户层和内核层两种.比如内核里编译了温度传感器的驱动,还得有lm-sensors在用户层负责解释处理内核递交出的数据.usb驱动是硬件驱动方面的东西,libusb是给应用软件开发 ...

  4. VS2008编译boost库

    一.下载首先从boost官方主页http://www.boost.org/下载最新版boost安装包,我用的版本是boost.1.49.0二.新建文件夹 如果是使用下载的安装包,那么请将boost安装 ...

  5. sed(转)

    第一部分:sed基础 1)简介 sed 是一种在线编辑器,它一次处理一行内容.处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区中的内 ...

  6. Java中,当表单含有文件上传时,提交数据的如何读取

    http://blog.csdn.net/lian_zhihui1984/article/details/6822201

  7. DTW-js版

    最近想试试语音识别,然后看到了DTW这个算法 主要参考:http://www.cnblogs.com/rockyf/articles/4519352.html function dtw(arr1, a ...

  8. 理解Unity加载和内存管理

    转自:http://game.ceeger.com/forum/read.php?tid=4394#info Unity里有两种动态加载机制:一是Resources.Load,一是通过AssetBun ...

  9. Javascript禁止父元素滚动条滚动, pc、移动端均有效

    在网页中经常会遇到这样的场景, 网页比较长有滚动条, 然后网页内的某个内容块里面的内容也比较长, 也具有滚动条.当鼠标移到内容块中使用滚动条来滚动查看内容到达底部或头部的时候,父元素的滚动条也就开始滚 ...

  10. php这样实现伪静态

    mod_rewrite是Apache的一个非常强大的功能,它可以实现伪静态页面.下面我详细说说它的使用方法 1.检测Apache是否支持mod_rewrite 通过php提供的phpinfo()函数查 ...