不修改数组找出重复的数字
问题描述:在一个长度为n的数组里的所有数字都在1~n-1的范围内, 所以数组中至少有一个数字是重复的。请找出数组中任意一个重复的数字,但是不能修改输入的数组。
时间最优方法:设置一个辅助数组记录即可 时间On 空间 On
空间最优方法:不使用辅助数组,本例是空间最优 ,空间 O1, 时间nlogn
思想:类似于二分查找,每次查找一个中间数,并且对整个数组计数,有重复的数字计数必然在数组长度的一半以上
持续更新...
代码附下
Java实现:
package 不修改数组找出重复的数字;
/**
* 问题描述:在一个长度为n的数组里的所有数字都在1~n-1的范围内,
* 所以数组中至少有一个数字是重复的。
* 请找出数组中任意一个重复的数字,但是不能修改输入的数组。
* @author user
*时间最优方法:设置一个辅助数组记录即可 时间n 空间 n
*空间最优方法:不适用辅助数组,本例是空间最优 空间 1 时间nlogn
*类似于二分,每次找一般
*/
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
int a[] = new int[] { 3, 3, 1, 3, 2, 3, 3 };
System.out.println(dup(a));
}
public static int dup(int a[]) {
for (int i = 0; i < a.length; i++) {
if (a[i] <= 0 || a[i] > a.length - 1) {
System.out.println("不合法的输入");
return -1;
}
}
int start = 1;
int end = a.length - 1;
int mid = 0;
while (end >= start) {
if (end == start) {
if (countRange(a, start, end) > 1) {
return start;
} else {
System.out.println("没找到!");// 理论上是不可能出现的
return -1;
}
}
mid = (start + end) / 2;
int count = countRange(a, start, mid);
if (count > mid - start + 1) {// 说明在start-mid之间有重复的元素
end = mid;
} else {
start = mid + 1;
}
}
return -1;
}
private static int countRange(int[] a, int start, int mid) {
// TODO Auto-generated method stub
int count = 0;
for (int i = 0; i < a.length; i++) {
if (a[i] <= mid && a[i] >= start) {
count++;
}
}
return count;
}
}
持续更新...欢迎赞赏!
https://blog.csdn.net/ustcer_93lk/article/details/80367091
如果有问题,欢迎大家留言,有更好的方法也期待大家告知。