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

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

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

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

C++代码实现如下:

#include<iostream>
using namespace std;
bool isbitof1(int num,int index);//判断num的index位是否为1,index从0开始
void partition_m(int data[],int start,int end,int index,bool (*cond)(int,int));//分割函数
void linear_sort(int data[],int n);//线性排序,基于基数排序,关键字为某位二进制位是0还是1,一共32位
int delete_repeated(int data[],int n);
int main()
{
int N;//数组元素个数
cin>>N;//用户输入
int *data=new int[N];
int i;
for(i=;i<N;i++)
cin>>data[i];//输入数组元素
int len=delete_repeated(data,N);
for(i=;i<len;i++)
cout<<data[i]<<" ";
cout<<endl;
return ;
}
bool isbitof1(int num,int index)
{
num=(num>>=index)&;//判断index位是零还是1
if(num==)
return true;
else
return false;
}
void partition_m(int data[],int start,int end,int index,bool(*cond)(int,int))
{
if(data==NULL||start>end)
return;
int i=start-;
int j=end+;
while(true)
{
do
{
i++;
}while(!cond(data[i],index)&&i<=end);
do
{
j--;
}while(cond(data[j],index)&&j>=start);
if(i>j)
break;
int temp=data[i];
data[i]=data[j];
data[j]=temp;
}
}
void linear_sort(int data[],int n)
{
if(data==NULL||n<=)
return;
int indexofbit,i,processed_bit;
//从高位到低位
for(indexofbit=;indexofbit>=;indexofbit--)
{
int start=;
int end=;
int prev=(data[]>>(indexofbit+))&(0x7FFFFFFF);
for(i=;i<n;i++)
{
processed_bit=(data[i]>>(indexofbit+))&(0x7FFFFFFF);
if(processed_bit==prev)
end=i;
else
{
partition_m(data,start,end,indexofbit,isbitof1);
prev=(data[i]>>(indexofbit+))&(0X7FFFFFFF);
start=i;
end=i;
} }
partition_m(data,start,end,indexofbit,isbitof1);
}
}
int delete_repeated(int data[],int n)
{
linear_sort(data,n);
int i,j;
i=;
j=i+;
while(j<n)
{
if(data[j]!=data[i])
{
i++;
data[i]=data[j];
j++;
}
else
{
j++;
}
}
return i+;
}

转自: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. 浏览器加载模式:window.onload和$(document).ready()的区别(详解)

    jQuery库文件是在body元素之前加载的,必须等待所有的DOM元素加载后,延迟支持DOM操作,否则就无法获取到. 在延迟等待加载,JavaScript提供了一个事件为load,方法如下: wind ...

  2. Scala基础入门-3

    学习Scala——映射和元组 映射和和元组,也就是Maps和Tuples.Map这东西应该都挺明白的,就是键值对的集合.而元组,tuple,这东西并不是每个语言都有(Python中是有的,不过当时学的 ...

  3. perl 创建包

    <pre name="code" class="python"><pre name="code" class=" ...

  4. 数值分析1:三角函数的计算(C语言实现)

    之前学习C语言的时候,一直有个疑问,计算机从芯片设计的角度来看,只能计算常规的加减乘及移位之类的操作,那么对于像sin .cos这些三角函数,人脑尚无可以直接运算的法则,那么计算机是怎么实现的呢?最近 ...

  5. atitit.软件开发GUI 布局管理优缺点总结java swing wpf web html c++ qt php asp.net winform

    atitit.软件开发GUI 布局管理优缺点总结java swing wpf web html c++ qt php asp.net winform 1. Absoluti 布局(经常使用) 1 2. ...

  6. 软交所--微软将对IE浏览器进行关键性安全更新

    微软于当地时间周四宣布下周二,即本月的"补丁星期二"推送九个安全升级. 当中最重要的就是解决IE浏览器远程运行代码(RCE)漏洞,这个漏洞影响从IE6至IE11全版本号,全部Win ...

  7. 自学php的几个例子(包含AMP(Apache、MySQL、PHP)环境搭建链接)

    学习PHP之前需要先搭建PHP运行的环境(即服务器+PHP+数据库)来使PHP成功运行,具体环境搭建教程可参考pharen(http://www.cnblogs.com/pharen/archive/ ...

  8. localhost和127.0.0.1区别

    详情见: http://blog.csdn.net/xifeijian/article/details/12879395

  9. Schema-based AOP support

    本文参考至:spring-framework-reference.pdf的7.3 章节 [Schema-based AOP support] If you are unable to use Java ...

  10. Struts2核心包

    Commons-logging.jar  --------------   用于通用日志处理 Freemarker.jar  --------------   表现层框架,定义了struts2的可视组 ...