一个短数组a,一个长数组b,元素都为正整数,找出两个数组重复的元素,要求不用其他数据结构,时间复杂度与空间复杂度尽量最优
1.最刚的办法:
public static void main(String[] args) {
int[] a = new int[10000];
int[] b = new int[100000];
// Set<Integer> set = new HashSet<Integer>();
Random rd = new Random();
for (int i = 0; i < a.length; i++) {
a[i] = rd.nextInt(8000);
}
for (int j = 0; j < b.length; j++) {
b[j] = rd.nextInt(15000);
}
long s1 = System.currentTimeMillis();
compare2(a, b);
// Iterator<Integer> iterator = set.iterator();
// while (iterator.hasNext()) {
// System.out.println(iterator.next());
// }
System.out.println("----------------------");
System.out.println(System.currentTimeMillis() - s1);
}
/**
* 最刚的办法,一个数一个数比较,时间复杂度O(a.length * b.length)
* @param a
* @param b
* @param set
*/
public static void compare2(int[] a, int[] b) {
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < b.length; j++) {
if (a[i] == b[j]) {
System.out.println(a[i]);
}
}
}
}
平均耗时: 900毫秒
2.我目前想到的办法
public static void main(String[] args) {
int[] a = new int[10000];
int[] b = new int[100000];
// Set<Integer> set = new HashSet<Integer>();
Random rd = new Random();
for (int i = 0; i < a.length; i++) {
a[i] = rd.nextInt(8000);
}
for (int j = 0; j < b.length; j++) {
b[j] = rd.nextInt(15000);
}
long s1 = System.currentTimeMillis();
compare1(a, b);
// Iterator<Integer> iterator = set.iterator();
// while (iterator.hasNext()) {
// System.out.println(iterator.next());
// }
System.out.println("----------------------");
System.out.println(System.currentTimeMillis() - s1);
}
/**
* 先将2数组快速排序排为升序,短数组在外层循环,长数组在内层循环,定义2个内外层游标,从左向右移动
* @param a
* @param b
* @param set
*/
public static void compare1(int[] a, int[] b) {
quickSort(a, 0 , a.length - 1);
quickSort(b, 0 , b.length - 1);
// System.out.println(Arrays.toString(a));
// System.out.println(Arrays.toString(b));
// System.out.println("----------------------");
int i = 0;
int j = 0;
while (i < a.length) {
while (i + 1 < a.length && a[i] == a[i + 1]) {
i++;
}
if (a[i] < b[j]) {
i++;
continue;
}
while (j < b.length) {
while (j + 1 < b.length && b[j] == b[j + 1]) {
j++;
}
if (a[i] < b[j]) {
i++;
break;
}
if (a[i] == b[j]) {
System.out.println(a[i]);
// set.add(a[i]);
i++;
j++;
break;
}
if (a[i] > b[j]) {
j++;
continue;
}
}
}
}
public static void quickSort(int[] arr, int left, int right) {
if (left >= right) {
return;
}
int i = left;
int j = right;
int base = arr[i];
while (i < j) {
while (i < j && arr[j] >= base) {
j--;
}
if (i < j) {
arr[i] = arr[j];
}
while (i < j && arr[i] <= base) {
i++;
}
if (i < j) {
arr[j] = arr[i];
}
}
arr[i] = base;
quickSort(arr, left, i - 1);
quickSort(arr, j + 1, right);
}
平均耗时:50毫秒
我这里求重复元素的思路
3.发现问题以及改进
上面代码发现有个bug,如果i没有走完,而j先走完了,a[i] < b[j] 比较时会抛索引越界异常。当时没有考虑到存在b数组最大值小于a数组最大值这种情况,现做如下修改:
public static void compare1(int[] a, int[] b) {
quickSort(a, 0 , a.length - 1);
quickSort(b, 0 , b.length - 1);
// System.out.println(Arrays.toString(a));
// System.out.println(Arrays.toString(b));
// System.out.println("----------------------");
int i = 0;
int j = 0;
while (i < a.length) {
while (i + 1 < a.length && a[i] == a[i + 1]) {
i++;
}
if (j == b.length)
break;
if (a[i] < b[j]) {
i++;
continue;
}
while (j < b.length) {
while (j + 1 < b.length && b[j] == b[j + 1]) {
j++;
}
if (a[i] < b[j])
break;
if (a[i] == b[j]) {
System.out.println(a[i]);
// set.add(a[i]);
j++;
break;
}
j++;
}
i++;
}
}
当j先走完,b数组不会存在再和a数组内重复的元素了,a数组内剩余元素无需再比较,直接结束。
有问题欢迎大佬指出