一个大小为N的数组,里面是N个整数,怎样去除重复的数
题目:一个大小为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个整数,怎样去除重复的数的更多相关文章
- 在主方法中定义一个大小为10*10的二维字符型数组,数组名为y,正反对角线上存的是‘*’,其余 位置存的是‘#’;输出这个数组中的所有元素。
//在主方法中定义一个大小为10*10的二维字符型数组,数组名为y,正反对角线上存的是‘*’,其余 位置存的是‘#’:输出这个数组中的所有元素. char [][]y=new char [10][10 ...
- 在主方法中定义一个大小为50的一维整型数组,数组i名为x,数组中存放着{1,3,5,…,99}输出这个数组中的所有元素,每输出十个换一行
package hanqi; import java.util.Scanner; public class Test7 { public static void main(String[] args) ...
- 假设一个大小为100亿个数据的数组,该数组是从小到大排好序的,现在该数组分成若干段,每个段的数据长度小于20「也就是说:题目并没有说每段数据的size 相同,只是说每个段的 size < 20 而已」
假设一个大小为100亿个数据的数组,该数组是从小到大排好序的,现在该数组分成若干段,每个段的数据长度小于20「也就是说:题目并没有说每段数据的size 相同,只是说每个段的 size < 20 ...
- 生成大小为100的数组,从1到100,随机插入,不连续,也不重复[C#]
生成大小为100的数组,从1到100,随机插入,不连续,也不重复. 实现思路 生成一个100位的集合listA,放1到100 创建一个空的集合listB,用来存放结果 创建一个变量c,临时存储生成的数 ...
- C用malloc 向系统申请一个大小为n*4个字节的内存块
#include <stdio.h> #include <malloc.h> void out(int *p, int n){ int i; for(i=0;i<n;i+ ...
- 按要求编写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+= ...
- 编写一个名为Test的主类,类中只有一个主方法; 在主方法中定义一个大小为50的一维整型数组,数组名为x,数组中存放着{1, 3,5,…,99}输出这个数组中的所有元素,每输出十个换一行;在主方法中定义一 个大小为10*10的二维字符型数组,数组名为y,正反对角线上存的是‘*’,其余 位置存的是‘#’;输出这个数组中的所有元素。
package liu0915; import java.util.Random; public class Test0915sz { public static void main(String[] ...
- 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 ...
- 给定数组A,大小为n,现给定数X,判断A中是否存在两数之和等于X
题目:给定数组A,大小为n,现给定数X,判断A中是否存在两数之和等于X 思路一: 1,先采用归并排序对这个数组排序, 2,然后寻找相邻<k,i>的两数之和sum,找到恰好sum>x的 ...
随机推荐
- WebApp 里Meta标签大全
1.先说说mate标签里的viewport: viewport即可视区域,对于桌面浏览器而言,viewport指的就是除去所有工具栏.状态栏.滚动条等等之后用于看网页的区域.对于传统WEB页面来说,9 ...
- IO-02
/** 2 *A2-IO-02. 整数四则运算(10) 3 *C语言实现 4 *测试已通过 5 */ #include "stdio.h" #include "stdli ...
- SQL Server 数据的创建、增长、收缩
第一步: create database Studio on primary (name = 'Studio',filename='E:\DB\Studio.mdf' ...
- 【OpenGL游戏开发之三】OpenGl核心函数库汇总
OpenGl核心函数库 glAccum 操作累加缓冲区 glAddSwapHintRectWIN 定义一组被SwapBuffers拷贝的三角形 glAlphaFunc允许设置alpha检测功能 glA ...
- C语言的本质(2)——二进制、八进制、十六进制与十进制
二进制是计算技术中广泛采用的一种数制.二进制数据是用0和1两个数码来表示的数.它的基数为2,进位规则是"逢二进一",借位规则是"借一当二",由18世纪德国数理哲 ...
- 匹配html标签的正则式
$reg = "/<" + element + "[^<>]*?\s+" + attr + "=['\"]?(.*?)[' ...
- C# 数据库dataGridView刷新数据和主外键判断
本文主要讲诉在使用VS2012+SQL Server数据库做系统中,通常会遇到几个问题.使用dataGridView控件在修改.删除.插入数据后,怎样刷新数据显示操作后的结果.同时在对数据操作时通常会 ...
- PHP自学2——将用户提交表单存储到外部普通文件中
在上一节中我们已经实现了将用户的订单信息提交到服务器端,然后服务器端将提交信息返回并显示到页面上.这一节将把上一节用户的订单信息保存到外部的普通文件中(即.txt文本文件中). 本节代码将用户提交的订 ...
- 改良版的SQL Service 通用存储过程分页
上次写了通用存储过程.感觉还是有很大的BUG.就是条件不能参数画化.这个BUG可以说是致命的.但是我一直想在用什么方法能解决这个东西.其实我只是想写少量的代码来做更多的事情.我想能不能传集合给存储过程 ...
- LocalStorage存储
1.localStorage存储服务: .factory('storageSvc', [function () { return { //保存数据 save: function (key, valu ...