标签:style java ar for sp on c log 时间
题目:数组中有一个数字出现的次数超过了数组长度的一半,找出这个数字。
解法1:将数组利用快速排序进行排序,因为数组中有一个数字出现的次数超过了数组长度的一半,则排序以后直接取得最中间的那个数字即可!
时间复杂度为:o(n*logN),因为时间主要花费在快速排序上面了!
public static int find1(int[] a) { Arrays.sort(a); int mid = 0 + (a.length - 0) / 2; int result = a[mid]; return result; }
// 根据hash表来计算,将其中的key为数字,值为key出现的次数 public static int find2(int[] a) { Map<Integer, Integer> map = new HashMap<>(); map.put(a[0], 1); for (int i = 1; i < a.length; i++) { if (map.containsKey(a[i])) { map.put(a[i], map.get(a[i]) + 1); } else { map.put(a[i], 1); } } Set<Integer> set = map.keySet(); Iterator<Integer> iterator = set.iterator(); int max = -1; int index = -1; while (iterator.hasNext()) { int key = (int) iterator.next(); int value = map.get(key); if (value > max) { max = value; index = key; } } return index; }
前面两种思路都没有考虑到题目中数组的特性:数组中有个数字出现的次数超过了数组长度的一半。也就是说,有个数字出现的次数比其他所有数字出现次数的和还要多。因此我们可以考虑在遍历数组的时候保存两个值:一个是数组中的一个数字,一个是次数。当我们遍历到下一个数字的时候,如果下一个数字和我们之前保存的数字相同,则次数加1。如果下一个数字和我们之前保存的数字不同,则次数减1。如果次数为零,我们需要保存下一个数字,并把次数设为1。由于我们要找的数字出现的次数比其他所有数字出现的次数之和还要多,那么要找的数字肯定是最后一次把次数设为1时对应的数字。
public static int find3(int[] a) { // 初始化出现在爱第一个数字,并将第一个数字出现的次数设置为1; int count = 1; int number = a[0]; for (int i = 1; i < a.length; i++) { if (a[i] == number) { count++; } else { count--; } if (count == 0) { number = a[i]; count = 1; } } return number; }
标签:style java ar for sp on c log 时间
原文地址:http://blog.csdn.net/shiyeqiangldh/article/details/39500225