找到数组中两个数字之间最小绝对差的最佳算法
|
有一个数组,可以包含多达1000个元素。它可以产生的数字范围是1到10 ^ 10。现在我必须找到数组中两个数字之间的最小绝对差。我已经想到了两种算法:
对于第一个,我已经定义了一个二进制搜索函数,它查找排序数组中被插入数字的位置。现在我启动排序数组,只有给定数组的第一个数字,并从第二个元素开始对给定的数组进行迭代。对于每个数字,我在排序的数组中找到它的位置。如果该位置的数字是这个数字,则差值为0,这是最低的数值,所以我退出循环。否则,我在该点将数字插入排序的数组,然后检查该数字与该数组中的前一个和下一个数字之间的差异。然后我存储此结果的最小值和以前的结果,并以此方式继续。 第二:我使用quicksort对数组进行排序。 (范围太大,所以我认为基数排序不会那么有效)。然后我重复一遍,如果两个连续的数字相等,则用0的答案展开,否则存储该数字与之前的数字和先前结果之间的差异的最小值。 哪一个会更有效率? 有没有更好的算法? Stackoverflow在这方面有很多职位,但是他们没有什么帮助。以下是我在Perl中的代码: sub position {
my @list = @{$_[0]};
my $target = $_[1];
my ($low,$high) = (0,(scalar @list)-1);
while ($low <= $high) {
$mid = int(($high + $low)/2);
if ( $list[$mid] == $target ) {
return $mid;
}
elsif ( $target < $list[$mid] ) {
$high = $mid - 1;
}
else {
$low = $mid + 1;
}
}
$low;
}
sub max { $_[0] > $_[1] ? $_[0] : $_[1]; }
sub min { $_[0] > $_[1] ? $_[1] : $_[0]; }
$ans = 10_000_000_000;
@numbers = (234,56,1,34...123); #given array
($max,$min) = @num[0,0];
@sorted = ($numbers[0]);
for ( @num[1 .. $#num] ) {
$pos = position(@sorted,$_);
if ( $sorted[$pos] == $_ ) {
$ans = 0;
last;
}
splice @sorted,$pos,$_;
if ( $#sorted == $pos ) {
$ans = min($_-$sorted[-2],$ans);
}
elsif ( 0 == $pos ) {
$ans = min($sorted[1]-$_,$ans);
}
else {
$ans = min(min(abs($sorted[$pos-1]-$_),abs($sorted[$pos+1]-$_)),$ans);
}
$max = max($_,$max);
$min = min($_,$min);
}
print "$ansn";
解决方法
你最多有5k个元素。
请注意,sandy bridge处理器具有32KB L1-Cache,假设为4字节整数 – 这意味着它可以包含8192个整数。 我会尽量避免创建额外的数据(除了计数器等等),并使用相同的数组来做所有事情。这将使得cache-misses的数量非常小,并且可能会超出任何算法。 因此,一个就地快速排序,而不是迭代数组中的元素,可能会比任何其他解决方案更好,无论是缓存高效还是保持O(nlogn)的体面渐近的复杂性。 注意 – 虽然这个解决方案可能会更有效率(至少在理论上),但是规模还是非常小的,除非你要做这么多的时间,否则你的时间过于优化。 一般提示:当谈到小规模问题(最多5000个元素符合这个标准)时,大O符号通常是不够的。缓存性能通常是这些问题的主要因素。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
