考虑我有这个数组:
$array = array(
'word1',
'abc',
'abc',
'word2',
[other words]
'word1',
'dfg'
'word2',
[other words]
);
我需要找到2个给定单词之间的最小距离。 (让' word1'和' word2'是这两个词)
在这种情况下,word1
和word2
之间的最小距离为1,因为在第二组单词中,它们仅由' dfg'分开。
我写了一个简单的代码,但它过于苛刻,我正在寻找更快的版本。
//> PSEUDO CODE
function minDistance( $words, $word1, $word2 ) {
foreach( $words as $k=>$v)
if ( $v == $words1 )
$positionsOfFirstWord[] = $k;
if ( $v == $words2 )
$positionsOfSecondWord[] = $k;
//> If word1 or word2 was not found in the array then
//> return max distance possibile (count($words))
//> Now we have 2 array containg the position of both word we need.
foreach( $positionsOfFirstWord as $v )
foreach( $positionsOfSecondWord as $vv )
$distance = abs($vv-$v);
}
请注意$ array中单词的顺序并不重要(这就是为什么有abs())
您认为可以有更好的版本吗?
请注意此功能必须在这种情况下返回1:
array(
[other words]
'word2',
'dfg',
'word1'
[other words]
);
答案 0 :(得分:2)
我认为一个简单的循环就足够了。如果找到last word1
,请跟踪当前最小值和word2
并更新当前最小值。基本上你利用的事实是word2
总是最接近找到的word1
let minimum = INFINITY
let lastword1 = -1
let lastword2 = -1
foreach word w in words
{
if ( w is word1 )
{
lastword1 = current position;
find distance between lastword2 and w update minimum if needed
}
if ( w is word2 )
{
lastword2 = current position;
find distance between lastword1 and w update minimum if needed
}
}
您可以在O(n)
中执行此操作,但如果可以完成预处理并且您需要回答多个查询,可能会有更快的方法
答案 1 :(得分:1)
构造一个int数组,如下所示
现在扫描数组以找到任意两对之间的最小差异
再次重复此过程,除了执行步骤4.使用'word1'而不是'word2'
你的答案是两个最小值中的较小者
答案 2 :(得分:0)
为什么要为这些职位设置数组?为什么不将它们保存为值然后做差异的绝对值呢?
function distance($words, $first, $second) {
$result = new Array();
for(i=0; i<words.length; i++) {
if($words[i] == $first) {
$firstPos = i;
} elseif($words[i] == $second) {
$secondPos = i;
$result[] = (abs($firstPos - $secondPos));
}
}
// Find the smallest number in the result array
$min = $result[0];
for(i=0; i<result.length; i++) {
if(result[i] < $min) {
$min = result[i];
}
}
return $min;
}
答案 3 :(得分:0)
基于parapura我写了这个,不知道为什么,但似乎它正在工作SLOWER
function minDistance2($words,$key1,$key2) {
if ($key1 == $key2)
return 0;
$min = false;
$p1 = false;
$p2 = false;
foreach($words as $k=>$v) {
$calc = false;
if ($v == $key1) {
$p1 = $k;
$calc = true;
} else if ($v == $key2) {
$p2 = $k;
$calc = true;
}
if ($calc) {
if ($p1===false || $p2===false)
continue;
$d = abs($p1-$p2) - 1;
if ($min === false || $d<$min )
$min = $d;
}
if ($min!==false && $min<=0)
return 0;
}
return ($min===false ? 0 : $min);
}