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

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

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值