您的位置:首页 > 理论基础 > 数据结构算法

一个短数组a,一个长数组b,都为正整数,找出两个数组重复的元素,要求不用其他数据结构,时间复杂度与空间复杂度尽量最优

2020-07-14 05:47 447 查看

一个短数组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数组内剩余元素无需再比较,直接结束。
有问题欢迎大佬指出

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐