我的解决方案在Codility上的得分仅为40%。
我做错了什么?
Here是测试结果(https://codility.com/demo/results/trainingU7KSSG-YNX/)
问题:
给出了由N个不同整数组成的零索引数组A.该数组包含[1 ..(N + 1)]范围内的整数,这意味着只缺少一个元素。
您的目标是找到缺少的元素。
解决方案:
function solution(A) {
var output = 1;
var arrayLength = A.length;
if(!arrayLength){
return output;
}
if(arrayLength == 1) {
return A[0] + 1;
}
var sorted = A.sort(sortingFn);
for(var i = 0; i < A.length - 1; i++) {
if(A[i+1] - A[i] > 1) {
output = A[i] + 1;
break;
}
}
return output;
}
function sortingFn(a, b) {
return a - b;
}
结果
答案 0 :(得分:3)
您的算法通过比较数组中的相邻元素来查找缺少的元素。这意味着它无法处理缺少第一个或最后一个元素的情况,因为它们只有一个邻居。
以[1, 2, 3]
为例。缺少的元素将是4.但由于4恰好有一个邻居(3
),因此算法无法找到它,并且将返回1。
此外,您的算法效率相当低,因为排序需要O(n lg n)
,而问题可以在O(n)
中解决:
find_missing(arr):
s = sum(arr)
s' = (len(arr) + 1) * (len(arr) + 2) / 2
return s' - s
如果所有元素都存在,此代码通过汇总数组中的所有元素并将其与预期总和进行比较来工作。这种方法的优点是它只需要线性操作,并且可以相对简单地找到缺失的元素。
答案 1 :(得分:1)
好吧,当最后一个元素丢失时,你显然会返回1,因为你的if语句的条件总是为假。第一个元素也一样。
以此输入为例:
1 2 3 4 5
差异将始终为1,但缺少元素6.
您的算法无法捕获这些案例的原因是,它会检查相邻元素(A[i + 1]
和A[i]
)。
答案 2 :(得分:0)
JS解决方案#1
function solution(A) {
if (A.length === 1) {
return A[0] > 1 ? 1 : 2;
}
const map = {};
let max = 0;
for (let i = 0, len = A.length; i < len; i++) {
map[A[i]] = A[i];
if (A[i] > max) {
max = A[i]
}
}
for (let i = 0, len = A.length; i < len; i++) {
if (!map[i + 1]) {
return i + 1;
}
}
return max + 1
}
JS解决方案2
function solution(A) {
const s = A.reduce((a, b) => {return a + b}, 0);
const s2 = (A.length + 1) * (A.length + 2) / 2
return s2 - s;
}
尝试此数组(如最终测试):
[1,2,3]
->必须返回4; [1]
->必须返回2; [2]
->必须返回1; [2,3]
->必须返回1; [1, 3]
-> 2 但是对于#2解决方案,[4]
返回-1
,对于[123]
返回-120
。测试将显示100分。但是实际上,它不符合我的预期。
这两个解决方案都具有相同的性能。
答案 3 :(得分:0)
在c#中尝试一下:
using System;
using System.Linq;
private static int PermMissingElem(int[] A)
{
if (!A.Any() || !A.Any(x => x == 1)) { return 1; }
var size = A.Length;
var numberTwoList = Enumerable.Range(1, size);
var failNumber = numberTwoList.Except(A);
if (!failNumber.Any()) { return A.Max() + 1; }
return failNumber.FirstOrDefault();
}
答案 4 :(得分:0)
Try this javascript function:
function solution(A) {
let givenSum = 0;
let expectedSum = 0;
let size = A.length;
for(let i = 1; i <= size +1; i++){
expectedSum = expectedSum + i;
}
for(let i = 0; i < size; i++){
givenSum += A[i];
}
return expectedSum - givenSum;
}