`
fantasy
  • 浏览: 515357 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

去除重复数

阅读更多
   这是一道外企算法的面试题,前提是不允许使用util包之外的类,即任何集合类都不允许使用。 写出的算法效率越高,此题得分越高,大家可以试一下。题目是输入一串已经排序好的数组,输出消除重复数之后的数组。如:
输入{ 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5 };输出{ 1, 2, 3, 4, 5 };

/**
 * 消除重复数(已经排序好的数组)
 * 
 * @author fangtengfei
 * @date   2010-5-16
 */
public class Distinct {

	public static void main(String[] args) {
		int[] oNums = { 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5 };
		int[] newNums = new int[oNums.length] ;
		int count = 0,index=-1;
		for (int i = 0; i  count) {
		  newNums[++index]=oNums[i];
		  count = oNums[i];
		}
		
	}
}


分享到:
评论
31 楼 houyu533 2012-11-16  
跳跃表吧!
30 楼 codeincoffee 2011-05-02  
fivestarwy 写道
排序好的,最快应该是二分吧

二分相对于遍历来说,是需要空间来换时间的。二分需要建立一个O(N)的数组。而遍历可以不需要。

这是二分的代码:

public static void removeDuplicationByBinary(int[] src, int start, int end, int[] array) {
		if (start >= end) return;
		int middle = (end - start)/2;
		if (src[middle] != src[src[0]]) {
			src[src[0]++] = src[middle];
			return;
		}
		removeDuplicationByBinary(src, middle, end, array);
		removeDuplicationByBinary(src, start, middle, array);
	}
	
	public static int[] removeDuplicationByBinary(int[] src) {
		if (src == null || src.length < 2) return src;
		int[] array = new int[src.length+1];
		removeDuplicationByBinary(src, 0, src.length-1, array);
		int[] result = new int[array[0]];
		System.arraycopy(array, 1, result, 0, array[0]+1);
		return result;
	}
29 楼 fivestarwy 2011-05-01  
排序好的,最快应该是二分吧
28 楼 codeincoffee 2011-05-01  
sunney2012 写道
int[] a = { 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5 };
int[] bucket = new int[a.length];
for (int i = 0; i < a.length; i++) {
bucket[a[i]] = a[i];
}

如果a[i]是负数,会出错的,同学。

我能给出的最好答案只有这样了:

public static int[] removeDuplication(int[] src) {
		if (src == null || src.length < 2) return src;
		int index = 0;
		for (int i = 1; i < src.length; i++) 
			if (src[i] != src[index]) //这里(src[i]^src[index])!=0会不会更快?
				src[++index] = src[i];
		int[] result = new int[index+1];
		System.arraycopy(src, 0, result, 0, index+1);
		return result;
}
27 楼 jinceon 2011-05-01  
buptwhisper 写道
遍历一次,n难道比nlg(n) 慢?在n的规模在数十或者更大时,不是n要比nlg(n)小么。。

我也觉得,有时候,一听到算法,效率什么的,就去想啊想,却偏偏不去考虑最普通的方法。有点为了算法而算法的感觉
26 楼 ggzwtj 2011-03-18  
这个也叫算法。。。
25 楼 buptwhisper 2011-03-18  
遍历一次,n难道比nlg(n) 慢?在n的规模在数十或者更大时,不是n要比nlg(n)小么。。
24 楼 sunney2012 2011-03-12  
int[] a = { 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5 };
int[] bucket = new int[a.length];
for (int i = 0; i < a.length; i++) {
bucket[a[i]] = a[i];
}
23 楼 wkshippou 2011-03-07  
先分组,再将分组中list.size大于1的从最后一个删除到第一个,只保留第一个,这样就没有重复的了。
QQ:784222511
22 楼 宋建勇 2011-02-25  
package test;


public class Distinct {  
 
    public static void main(String[] args) {  
        int[] oNums = {-3,-3,-3,-2,-1,0,0,0,0,0, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5,7,8,8,8,8,9 };
        String a=String.valueOf(oNums[0])+",";
        for(int i=1;i<oNums.length;i++){
        String b[] = a.split(",");
        if(oNums[i]!=Integer.parseInt(b[b.length-1]))
        a=a+oNums[i]+",";
        }
        System.out.println(a.replace(',', ' '));
    }  
}
21 楼 宋建勇 2011-02-25  
public class Distinct {  
 
    public static void main(String[] args) {  
        int[] oNums = { 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5 };  
        List newNums = new ArrayList();  
        int count = 0;  
        for (int i = 0; i < oNums.length; i++) {  
            if (oNums[i] > count) {  
                newNums.add(oNums[i]);  
                count = oNums[i];  
            }  
        }  
    }  


以上中如果将
int[] oNums = { 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5 };
改为
int[] oNums = {0, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5 };
将会丢失第一个数字(0)
20 楼 sadawn 2011-02-25  
排序好的数组, 只需要遍历一次就可以了,拿当前的值与上一个值比较,就可以去除重复的数字,比较常规的做法
arr = [1,1,1,2,2,6,6,6,34,88,88,99,101]
newArr =[]
newArr.append(arr[0])

for i in arr[1:]:
    if i != newArr[len(newArr)-1]:
        newArr.append(i)

print newArr
19 楼 ray_linn 2011-02-24  
求模呗....hash算法
18 楼 jiminsc 2011-02-24  
有一个取巧的方法,楼主参考下
	public static void main(String[] args) {
		//质数数组
		int[] prime = new int[] { 2, 3, 5, 7, 11, 13, 17 };
		//目标数据
		int[] data = { 6, 1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5 };
		long tmp = 1;
		for (int i = 0; i < data.length; i++) {
			if (tmp % prime[data[i]] != 0) {
				System.out.println(data[i]);
				tmp *= prime[data[i]];
			}
		}
	}

17 楼 luobin23628 2010-12-08  
我的做法,参考合并排序递归把数组分成两半,然后再合并数组,效率nlgn。
合并数组的规则
1. 找出前一个数组中最后一个不为-1的数(这里用-1标志重复位)
2. 如果找不到,则直接合并
3. 如果找到这个数,则从下一个数组的开始位置开始,找出重复的数,置为-1。

	public static void main(String[] args) {
		int[]x = new int[]{1,1,2,3,3,3,4,4,4,4,4,5,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6};
		distinct(x, 0, x.length);
		System.out.println(Arrays.toString(x));
	}
	
	public static void distinct(int[] x,int p,int q){
		if(p==q-1){
			return;
		}
		int r = (p+q)>>>1;
		distinct(x, p, r);
		distinct(x, r, q);
		merge(x, p, r, q);
	}
	
	private static void merge(int[] x,int p,int r,int q){
		int key = -1;
		int k = r-1;
		while(k>=p){
			if(x[k]!=-1){
				key = x[k];
				break;
			}
			k--;
		}
		if(key!=-1){
			while(r<q&&(x[r]==key||x[r]==-1)){
				x[r] = -1;
				r++;
			}
		}
	}
         没有直接遍历快。。不过也是一个思路
16 楼 cozilla 2010-12-06  
<p>
</p>
<pre name="code" class="java"> private static int[] num = { 1, 1, 1, 2, 2, 2, 2, 3, 3, 4, 4, 4, 4, 4, 5,
6, 7, 7, 7 };

public static void main(String args[]) {
bSearch(0, num.length - 1);
}

public static void bSearch(int left, int right) {
if (left &gt; right)
return;
if (num[left] == num[right]) {
System.out.print(num[right]);
return;
}
int mid = (left + right) / 2;
if (num[left] == num[mid]) {
bSearch(mid, right);
} else if (num[mid] == num[right]) {
bSearch(left,mid);
} else {
int lower = lowerBound(left,mid);
int upper = upperBound(mid,right);
bSearch(left, lower-1);
System.out.print(num[mid]);
bSearch(upper+1, right);
}

}

private static int upperBound(int left, int right) {
if(num[left]== num[right])return right;
int mid = (left + right) / 2;
if(left == mid){ //即right= left+1
return left;
}
if(num[left]==num[mid])
return upperBound(mid,right);
else
return upperBound(left,mid);
}

private static int lowerBound(int left, int right) {
if(num[left]== num[right])return left;
int mid = (left + right) / 2;
if(left == mid){ //即right= left+1
return right;
}
if(num[mid]==num[right])
return lowerBound(left,mid);
else
return lowerBound(mid,right);
}</pre>
 
15 楼 cozilla 2010-12-06  
我觉得这道题目O(n)肯定不是最好的算法。
用二分搜索来者可以效率更高
14 楼 yiyidog125 2010-10-20  
这题和binary search有什么关系呢
这个数组是排好序的 直接相邻位比较就好了

   int[] removeDuplicates(int[] values)
   {
int current = 0;
int prev = current-1;
int count = 0;
int[] temp = new int[values.length];
for (int i = 0; i < values.length; i++) {
prev = current;
current = values[i];
if (current != prev) {
temp[count++] = current;
}
}
int[] result = new int[count];
System.arraycopy(temp, 0, result, 0, count);
temp = null;
return result;
   }
13 楼 terry12903 2010-10-14  
 def sort(list):
    sortList=[]
    for i in list:
        if sortList.count(i)==0:
            sortList.append(i)

    print(sortList)
12 楼 gteam.yu 2010-09-16  
10楼的朋友的忽略了1,1,1的情况吧,用递归是没有错了,我自己写了一个java版本的,贴上(注释没有写,抱歉了)
public static void main(String[] args) {
  int[] ints = { 1, 1, 1, 2, 2, 2, 2, 3, 3, 4, 4, 4, 4, 4, 5, 6, 7, 7, 7 };
distinct(ints, 0, ints.length - 1);
}
//递归、折半查找排除
public static void distinct(int[] ints, int sIndex, int eIndex) {
  int midIndex = (eIndex + sIndex) / 2;
  if (ints[sIndex] == ints[eIndex]) {
    System.out.println(ints[sIndex]);
  } else if (ints[midIndex] == ints[sIndex] && ints[midIndex] != ints[midIndex + 1]) {
    System.out.println(ints[midIndex]);
    distinct(ints, midIndex + 1, eIndex);
//不断的向右缩减成员,把2,2,2,2,3变成2,3
} else if (ints[sIndex] == ints[sIndex + 1]) {
    distinct(ints, sIndex + 1, eIndex);
} else {
    System.out.println(ints[sIndex]);
distinct(ints, sIndex + 1, eIndex);
    }
}

相关推荐

    matlab中如何去掉数组中重复的值

    2. 使用 SQL 语句删除重复记录:rs = exec(conn, 'SELECT * FROM TABLE_NAME WHERE ID IN (SELECT MIN(ID) FROM TABLE_NAME GROUP BY REPEAT_FIELD)'); 其中,TABLE_NAME 是数据库表的名称,REPEAT_FIELD 是重复...

    java,输入十个整数,去掉其中重复的数后输出

    用java编的一个小程序,输入10个整数,去掉其中重复的数后输出

    重复数据删除技术源代码C语言

    1.4.1版本可能提供了清晰的接口供外部调用,例如添加数据、检查重复、删除重复等方法。 总之,"重复数据删除技术源代码C语言"是一个涉及数据结构、哈希算法、比较逻辑和性能优化的复杂工程。通过深入分析和理解...

    plsql删除重复记录

    在开始删除重复记录之前,首先需要确定哪些记录是重复的。以下SQL语句可以用来查询`test`表中所有字段都重复的记录: ```sql SELECT * FROM test GROUP BY name, age, sex, id, sf HAVING COUNT(*) &gt; 1; ``` 这里...

    重复文件去除,清理重复文件

    3. 去除:选择要删除的重复文件后,工具会执行删除操作,同时可以设置保留一个原始文件或根据创建时间、修改时间等标准保留最新的或最早的副本。 对于NAS设备,如群晖或威联通,虽然它们通常配备有Web界面的管理...

    易语言源码易语言双数组去重复数源码.rar

    本源码"易语言双数组去重复数源码.rar"提供了一个解决特定问题的方案——去除双数组中的重复数字。 在易语言中,数组可以是一维或多维的,这里提到的“双数组”可能是指两个一维数组或者两个维度相同的多维数组。...

    C编程中常见的几种删除重复字符或者数字的方法

    "C编程中常见的几种删除重复字符或者数字的方法" C语言是一种广泛使用的高级编程语言,它广泛应用于操作系统、嵌入式系统、数据库等领域。对于字符串的处理是C语言编程中的一个非常重要的方面,其中删除重复字符...

    用算法去除数组中重复的数字

    用算法去除数组中重复的数字(不使用查重函数)通过嵌套for循环和if条件判断实现,用算法去除数组中重复的数字(不使用查重函数)通过嵌套for循环和if条件判断实现

    用筛选法删除输入的10个数中的重复的数

    筛选法是一种遍历数组或列表,检查并删除重复项的算法。在本示例中,它通过两层循环实现:外层循环遍历每个元素,内层循环则比较该元素与之后的所有元素,如果找到重复项,则将其标记为0(或任何特定值),以便后续...

    LabVIEW 删除数组中重复元素实例

    在本例中,我们关注的是如何处理一维数组,即线性数组,来删除重复的元素。 描述中提到的“查找重复元素并删除重复”是实现目标的关键步骤。这通常涉及到以下操作: 1. **查找重复元素**:在LabVIEW中,可以通过...

    去除重复数据,去除重复数据算法

    根据给定文件的信息,本文将围绕“去除重复数据”这一主题进行深入探讨,重点解析一个简单易懂且适用性广的去重算法,并通过具体的代码示例来展示其实现过程。 ### 去除重复数据的基本概念 在计算机科学中,“去除...

    SQL语句删除重复记录

    优点:这种方法可以灵活地删除重复记录,且可以根据需要指定删除的记录数。 缺点:使用游标可能会影响数据库性能,且需要注意游标的使用。 Knowledge Point 3: 使用存储过程删除重复记录 在这种方法中,我们创建...

    二维数组去除重复项

    3. **重构数组**:利用`array_unique()`函数去除`$temp`数组中的重复字符串,得到没有重复项的数组。然后再次遍历这个数组,根据`$stkeep`和`$ndformat`的值决定是否恢复原始的键名和子数组的键名。最后,将结果存储...

    随机产生8位无重复数

    2. **去除重复**:为了确保生成的随机数不重复,可以使用HashSet或数据库来存储已经生成过的随机数,每次生成新数时,都会先检查该数是否已存在,如果不存在则添加并返回,否则继续生成新的随机数。 3. **数据库...

    删除数据表中重复记录

    本文将详细介绍如何在不同的数据库系统(如MySQL、SQL Server、Oracle等)中删除重复记录。 #### SQL删除重复记录的基本思路 删除重复记录的核心思想是先识别出哪些记录是重复的,然后通过某种方式将这些重复记录...

    删除Access数据库中重复的数据

    6. **自动化过程**:如果经常需要进行此操作,可以考虑编写VBA宏或者使用Access的模块功能,自动化整个删除重复数据的过程。这样,只需点击一下按钮,Access就能自动检查并删除重复数据。 7. **预防措施**:为了...

    批量删除重复文件工具 完美

    本文将详细介绍批量删除重复文件的工具及其重要性,以及如何利用“DoubleKiller.exe”这一实用工具来解决这一问题。 批量删除重复文件工具的主要功能是快速检测并移除系统中相同内容的文件,以释放存储空间,提高...

    去除重复查找软件

    2. **高速扫描**:高效的算法使得软件能在短时间内扫描大量文件,大大提高了查找和删除重复文件的速度。 3. **智能选择**:在找到重复文件后,软件通常会提供多种处理策略,比如保留最新版本、最旧版本或者最小文件...

    超级实用去重复统计工具EditPlus

    在替换字段中留空,这样每次找到重复行时,它都会被删除,从而达到去重目的。如果数据量庞大,建议分批操作,以避免一次性处理过多数据导致编辑器卡顿。 此外,EditPlus还支持宏录制和播放,这对于执行重复任务非常...

    批量删除重复的文件

    在IT领域,尤其是在日常计算机操作和数据管理中,批量删除重复的文件是一项常见的需求。这不仅可以节省存储空间,还能保持文件系统的整洁。本篇将详细探讨如何实现这一目标,主要聚焦于“批量删除重复的文件”这个...

Global site tag (gtag.js) - Google Analytics