题目还是同一个题目,
昨天用了HashMap来做——【http://blog.csdn.net/u014282557/article/details/61937089】
今天用交换下标的方式来做——【今天能够在同样的时间内用O(1)的空间做】
/**
*
*/
package dianer;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Scanner;
/**
* * @author LilyLee
* @date 2017年3月14日
* @Version
* 题目描述:在一个长度为n的数组里的所有数字都在0到n-1的范围内。
数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。
例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是重复的数字2或者3。
示例输入
7
2 3 1 0 2 5 3
示例输出
2 3
如果没有重复元素,则输出 no。
*
*解法来自《剑指offer》
从头扫描这个数组,当扫描到下标为i的数字时,
首先比较这个数字m是不是等于i,
如果等于,就继续扫描下一个数字。
如果不是,再拿他和位置m的数字进行比较。
如果和位置m的数字相等,就找到一个重复数字:位置i和位置m的数字。
如果和位置m的数字不相等,就把位置i和位置m的数字进行交换,把m放到属于他的位置上。
接下来重复这个过程,直到发现重复数字。
代码中尽管有一个两重循环,但是每个数字最多只要交换两次就能找到属于他自己的位置,
因此总的时间复杂度* 是O(n),不需要额外空间,空间复杂度是O(1)
*/
public class Array_find_dup {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int[] num = new int[n];
for (int i = 0; i < n; i++) {
num[i] = in.nextInt();
}
duplicate2(num);
}
public static void duplicate2(int []num){
int len=num.length;
if (len<2||num==null) { System.out.println("no");return ;}
ArrayList res= new ArrayList();
for(int i=0;i<len;i++){
if(num[i]<0||num[i]>len-1){System.out.println("no");return ;}
if(num[i]!=i){
if(num[num[i]]==num[i]){
res.add(num[i]);
}
swap(num,i,num[i]);
}
}
Iterator <Integer> it=res.iterator();
while(it.hasNext()){
System.out.print(it.next()+" ");
}
}
public static void swap(int[] num, int i,int j){
int temp=num[i];
num[i]=num[j];
num[j]=temp;
}
}