数组中重复的数字
2016-06-25 17:27
253 查看
题目
在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是重复的数字2或者3。解题
HashMap或者数组占用空间利用数组,A[i]表示i值出现的次数
public boolean duplicate(int numbers[],int length,int [] duplication) { if(numbers == null || numbers.length <=0) return false; boolean[] A = new boolean[length]; for(int num:numbers){ if(A[num]){ duplication[0] = num; return true; }else{ A[num] = true; } } return false; }
讨论中推荐解法
利用现有数组设置标志,当一个数字被访问过后,可以设置对应位上的数 + n,之后再遇到相同的数时,会发现对应位上的数已经大于等于n了,那么直接返回这个数即可。
public boolean duplicate(int numbers[],int length,int [] duplication) { if(numbers == null || numbers.length <=0) return false; for ( int i= 0 ; i<length; i++) { int index = numbers[i]; if (index >= length) { index -= length; } if (numbers[index] >= length) { duplication[0] = index; return true; } numbers[index] = numbers[index] + length; } return false; }
上面解题的关键就是:数组的id和数组值是对于的,根据数组值可以找到值得值。
题目说明是0-n-1内的数,这是个提醒
只要求返还其中一个重复的数
排序后找第一个重复数?
利用快排
public class Solution { // Parameters: // numbers: an array of integers // length: the length of array numbers // duplication: (Output) the duplicated number in the array number,length of duplication array is 1,so using duplication[0] = ? in implementation; // Here duplication like pointor in C/C++, duplication[0] equal *duplication in C/C++ // 这里要特别注意~返回任意重复的一个,赋值duplication[0] // Return value: true if the input is valid, and there are some duplications in the array number // otherwise false public boolean duplicate(int numbers[],int length,int [] duplication) { if(numbers == null || numbers.length <=0) return false; int low = 0; int high = numbers.length -1; quickSort(numbers,0,high); for(int i=0;i<high;i++){ if(numbers[i]==numbers[i+1]){ duplication[0]=numbers[i]; return true; } } return false; } public void quickSort(int[] A,int low,int high){ if(low >high) return; int mid = partition(A,low,high); quickSort(A,low,mid-1); quickSort(A,mid+1,high); } public int partition(int[] A,int low,int high){ int x = A[high]; int i = low -1; int j = low; while(j<high){ if(A[j] <= x){ i++; swap(A,i,j); } j++; } i++; swap(A,i,high); return i; } public void swap(int[] A,int i,int j){ int t = A[i]; A[i] = A[j]; A[j] = t; } }
本打算利用partition找到中间划分的id,id和numbers[id]比较,发现这样做不行,直接写出快排再找了
《剑指offer》上解法
1、判断输入数组有无元素非法
2、从头扫到尾,只要当前元素值与下标不同,就做一次判断,numbers[i]与numbers[numbers[i]],相等就认为找到了
重复元素,返回true,否则就交换两者,继续循环。直到最后还没找到认为没找到重复元素,返回false
public class Solution { public boolean duplicate(int numbers[],int length,int [] duplication) { if(numbers == null || numbers.length <=0) return false; //判断每一个元素是否非法 for(int i=0;i<length;++i){ if(numbers[i]<=0||numbers[i]>length-1) return false; } for(int i=0;i<length;++i){ while(numbers[i]!=i){ if(numbers[i]==numbers[numbers[i]]){ duplication[0] = numbers[i]; return true; } //交换numbers[i]和numbers[numbers[i]] swap(numbers,i,numbers[i]); } } return false; } public void swap(int[] A,int i,int j){ int t = A[i]; A[i] = A[j]; A[j] = t; } }
相关文章推荐
- POJ 3436 ACM Computer Factory (最大流)
- logiscope6.1 常用单词分析
- map优化 区间连续和为k
- 深浅拷贝
- React 开发环境搭建 以及emmet的简单语法
- Android知识整理<一>Activity
- Android JNI 传递对象
- Shiro系统权限管理、及原理剖析
- 各大HotFix热补丁方案分析和比较
- tomcat部署(idea)项目
- DuiLib学习(六)-自绘标题栏
- TCP协议深度解析
- H264规定了三种主要档次
- HDU2009 求数列的和
- Xcode 通过SourceControl版本控制
- Java中的Collection和Map
- Android中的Shape使用总结
- H264学习指南
- C preprocessor fails sanity check
- 关系型数据库之mysql-proxy实现读写分离