题目:一个大小为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. mysql校对规则引起的不区分大小写

    CREATE TABLE `staticcatalogue` ( `Source` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL ...

  2. windows程序设计读书笔记4——字符显示3

    在之前的一章里我们使用InvalidateRect函数,生成窗口重绘消息进行重绘,但是并没有在处理滚动条消息时直接绘制,这样的代码效率并不高. 这里作者使用了UpdateWindow函数,直接进行窗口 ...

  3. ListView学习小结

    ListView小结 ListView 是Android UI中十分重要的一个组件,在数据的显示上能有着十分灵活的表现,其使用也比较简单,一般包括以下几个要点: 1.  可以通过编写ListActiv ...

  4. mac下配置java环境

    1.tomcat配置 http://www.cnblogs.com/freeyiyi1993/p/3436368.html 2.下载eclipse和jdk安装  jdk去oracle网站下载

  5. Catalog和Schema

    http://www.codeweblog.com/database-schema-and-catalog/ http://blog.sina.com.cn/s/blog_515015800100et ...

  6. 凯恩斯主义VS货币主义

    Milton Friedman在1960年代后期以及整个1970年代,到处不知疲倦地像传教士一般地宣讲他的货币主义.当时,美联储成员几乎清一色地是凯恩斯主义者.你可以想像Friedman的对手是多么强 ...

  7. Flex中如何通过设置GridLines对象的horizontalAlternateFill样式交错显示LineSeries图表背景颜色的例子

    原文 http://blog.minidx.com/2008/11/27/1652.html 接下来的例子演示了Flex中如何通过设置GridLines对象的horizontalAlternateFi ...

  8. cat监控平台环境搭建

    项目地址:https://github.com/dianping/cat 编译步骤: 这个项目比较另类,把编译需要的jar包,单独放在git分支mvn-repo里了,而且官方文档里给了一个错误的命令提 ...

  9. Unix/Linux环境C编程入门教程(19)Red Hat Entetprise Linux 7.0环境搭建

    位架构,包括英特尔X-86_64.Power和s390.动态定时能力将降低内核内部中断数量,Open vSwitch 2.0功能可调节虚拟机之间的流量.RHEL 7中默认的文件系统是XFS,包含了一个 ...

  10. php 验证身份证有效性,根据国家标准GB 11643-1999 15位和18位通用

    //验证身份证是否有效 function validateIDCard($IDCard) { if (strlen($IDCard) == 18) { return check18IDCard($ID ...