• 不修改数组找出重复的数字


    在一个长度为n+1的数组里的所有数字都在1到n的范围内,所以数组中至少有一个数字是重复的。
    请找出数组中任意一个重复的数字,但不能修改输入的数组。
    例如,如果输入长度为8的数组{2, 3, 5, 4, 3, 2, 6, 7},那么对应的输出是重复的数字2或者3。

    思路

    按照二分查找的思路
    数组长度为n+1,而数字只从1到n,说明必定有重复数字。
    可以用二分查找扩展{2, 3, 5, 4, 3, 2, 6, 7} 取中间数4
    统计1-4,5-7 在数组出现的次数
    1-4 出现了5次,如果大于4则在1-4一定有重复
    接下来缩小范围1-2,3-4
    3-4出现了3次
    再分别统计 3,4
    3出现了两次 则3为重复元素

    实现

    public int getDuplicate(int[] arr) {
    	int start = 1, end = arr.length - 1;
    	while (start <= end) {
    		int mid = (end - start) / 2 + start;
    		int count = getCount(arr, start, mid);
    		if (start == end) {
    			if (count > 1) {
    				return start;
    			} else {
    				break;
    			}
    		}
    		if (count > (mid - start + 1)) {
    			//说明有重复元素
    			end = mid;
    		} else {
    			//相反
    			//因为 数组中肯定有重复的元素,不上一半就在这
    			start = mid + 1;
    		}
    	}
    	return -1;
    }
    //计算数组中start-end 中出现的次数
    private int getCount(int[] arr, int start, int end) {
    	if (arr == null) {
    		return 0;
    	}
    	int count = 0;
    	for (int i = 0; i < arr.length; i++) {
    		if (arr[i] >= start && arr[i] <= end) {
    			count++;
    		}
    	}
    	return count;
    }
    

    测试用例

    public void test() {
    	int[] a = { 1, 2, 3, 2, 4 };
    	int dup = getDuplicate(a);
    	System.out.println("重复数字为:" + dup);
    }
    

    输出

    重复数字为:2
    

    注意
    这种算法不能保证找到所有的重复数字。
    例如:{2,3,5,4,3,2,6,7} 中1-2范围有1和2两个数字,
    但这里这个范围的数字也出现了2次,此时我们用该算法不能确定是每个数字个
    各出现一次还是某一个数字出现了两次

  • 相关阅读:
    python标准库学习-SimpleHTTPServer
    迁移cnblog博客
    zabbix监控使用
    20 个 OpenSSH 最佳安全实践
    编写基本的 udev 规则
    Linux.Siggen.180
    在 CentOS 7.0 上安装配置 Ceph 存储
    常用 GDB 命令中文速览
    Kubernetes TLS认证
    音乐下载api
  • 原文地址:https://www.cnblogs.com/aiguozou/p/11438001.html
Copyright © 2020-2023  润新知