一个短数组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数组内剩余元素无需再比较,直接结束。
有问题欢迎大佬指出
相关文章推荐
- 经典程序面试题 题目:一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。 分析:这是一道很新颖的关于位运算的
- 一个整型数组里除了一个或者两个或者三个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)
- 一个整型数组 nums 里除两个数字之外,其他数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)。
- 一个整型数组里除了一个或者两个或者三个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)
- 一个整型数组里除了两个数字之外,其他的数字都出现了两次。 请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n), 空间复杂度是O(1)
- 一个整型数组里除了一个或者两个或者三个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)
- 一个数组中,存在两个只出现一次的数字,其余的数字均出现两次。要求在时间复杂度o(n),空间复杂度为o(1)的情况下找出这两个数字
- 问题描述如下: 有2.5亿个整数(这2.5亿个整数存储在一个数组里面,至于数组是放在外存还是内存,没有进一步具体说明); 要求找出这2.5亿个数字里面,不重复的数字的个数; 另外,可用的内存限定为600M; 要求算法尽量高效,最优;
- 一个整型数组里除了一个数字之外,其他的数字都出现了两次。要求时间复杂度是O(n),空间复杂度是O(1),如何找出数组中只出现一次的数字
- 给定一个大小为 n 的数组,找出其中所有出现超过 n/3 次的元素。 说明: 要求算法的时间复杂度为 O(n),空间复杂度为 O(1)。 示例 1: 输入: [3,2,3] 输出: [3] 示例
- 取值为[1,n-1]含n个元素的整数数组,至少存在一个重复数,即可能存在多个重复数,O(n)时间内找出其中任意一个重复数,不使用额外存储空间。
- 《数据结构》2.10设计一个算法,删除顺序表中值为item的元素,要求算法的时间复杂度是O(n),空间复杂度是O(1)
- 长度为n的整数数组,找出其中任意(n-1)个乘积最大的那一组,只能用乘法,不可 以用除法。要求对算法的时间复杂度和空间复杂度作出分析,可以写思路也可以写程序。
- 取值为[1,n-1] 含n 个元素的整数数组至少存在一个重复数,O(n) 时间内找出其中任意一个重复数
- 谷歌面试题--一个大小为n的数组,里面的数都属于范围[0, n-1],有不确定的重复元素,找到至少一个重复元素,要求O(1)空间和O(n)时间
- 一个大小为n的数组,里面的数都属于范围[0, n-1],有不确定的重复元素,找到至少一个重复元素,要求O(1)空间和O(n)时间。
- 试设计一个算法,将数组A(0..n-1)中的元素循环右移k位,并要求空间复杂度为O(1),时间复杂度为O(n)。
- 如何快速找出一个数组中只出现一次的两个数,其他元素出现两次?保证时间复杂度O(n),空间复杂度O(1)
- 一个数组中除了两个数字之外,其余数字均出现了两次,如{1,2,3,4,5,3,2,1}.查找出这两个只出现一次的数字。要求时间复杂度为O(n),空间复杂度为O(1)。
- 给定一个存放整数的数组,重新排列数组使得数组左边为奇数,右边为偶数。 要求:空间复杂度O(1),时间复杂度为O(n)。