大家好,请检查问题HackerRank Problem Statement
这是我针对上述问题的解决方案(链接)
static int migratoryBirds(List<Integer> arr) {
int ar[]=new int[arr.size()];
for(int i=0;i<arr.size();i++){
ar[i] = Collections.frequency(arr,arr.get(i));
// ar[i] = obj.occuranceOfElement(arr,arr.get(i));
}
int maxAt = 0;
for (int i = 0; i < ar.length; i++) {
maxAt = ar[i] > ar[maxAt] ? i : maxAt;
}
return arr.get(maxAt);
}
当数组较大时,我的代码无法处理,例如数组中的17623个元素。
由于超时而终止
问题出在第二个for循环中,该循环遍历数组并为我提供数组中最大数字的索引。还有其他方法可以提高性能。 >
答案 0 :(得分:4)
您的问题出在这部分:
for(int i = 0; i < arr.size(); i++)
ar[i] = Collections.frequency(arr, arr.get(i));
这是 O(N²):Collections.frequency()
遍历整个列表以仅计算一个元素的频率。您可以手动遍历列表以计算所有元素的频率。
此外,那里只有5只鸟,因此您只需要5个长度的阵列。
static int migratoryBirds(int[] arr) {
int max = 1;
int[] freq = new int[6];
for (int val : arr)
freq[val]++;
for (int i = 2; i < freq.length; i++)
max = freq[i] > freq[max] ? i : max;
return max;
}
答案 1 :(得分:3)
您的问题是对Colletions.frequency的调用,这是一个O(N)操作。当您从循环内部调用它时,它变成O(N²),这会占用您所有的时间。
此外,您确定您会收到List的哪些实现?您调用list.get(i)(如果实现是LinkedList,也可能是O(N)。
本练习的目标是计算输入中的每一个值的频率。您需要一个存储和增加每个值出现次数的地方,并且需要存储输入的最大值。
您还跳过了规范的关键部分。输入有限制,这使得解决问题比您现在想的要容易。
答案 2 :(得分:1)
这是另一个:
static int migratoryBirds(List<Integer> arr) {
int freq[]=new int[6];
for(int i=0;i<arr.size();i++){
++freq[arr.get(i)];
}
int maxAt = 1;
for (int i = 2; i < freq.length; i++) {
if (freq[i] > freq[maxAt]) {
maxAt = i;
}
}
return maxAt;
}
答案 3 :(得分:1)
我们可以在一圈中确定最常见鸟类的类型编号。这具有时间复杂度O(n)。
static int migratoryBirds(int[] arr) {
int highestFrequency = 0;
int highestFrequencyBirdType = 0;
int[] frequencies = new int[5]; // there are 5 bird types
for (int birdType : arr) {
int frequency = ++frequencies[birdType - 1];
if (frequency > highestFrequency) {
highestFrequency = frequency;
highestFrequencyBirdType = birdType;
} else if (frequency == highestFrequency && birdType < highestFrequencyBirdType) {
highestFrequencyBirdType = birdType;
}
}
return highestFrequencyBirdType;
}
对于数组arr
中的每个元素,我们更新整体highestFrequency
并存储代表highestFrequencyBirdType
的相应值。如果两个不同的鸟类类型的频率最高,则设置较低的类型( ID编号最小的)。