Consider I have this array:
$array = array(
'word1',
'abc',
'abc',
'word2',
[other words]
'word1',
'dfg'
'word2',
[other words]
);
I need to find the minimum distance between 2 given words. (let 'word1' and 'word2' be these 2 words)
In this case the minium distance between word1
and word2
is 1 because in the second group of words they are separated by only 'dfg'.
I wrote a simple code but it's too expsensive and I am looking for a faster version.
//> 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);
}
Note the order of words in $array isn't important (that's why there is abs())
Do you think there could be a better version?
Please note the function must return 1 in this case too:
array(
[other words]
'word2',
'dfg',
'word1'
[other words]
);
I think a simple loop is enough. Keep track over the current minimum and of the last word1
and update current minimum if a word2
is found. Basically you are utilizing the fact that a word2
will always be closest to the last word1
found
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
}
}
You can do this in O(n)
but there might faster ways if pre processing can be done and you need to answer multiple queries
why set up an array for the positions? Why not just save them as values and then do absolute value of the difference?
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;
}
Based on parapura I wrote this, Dunno why but it seems it's working 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);
}
construct an array of ints as follows
now scan the array to find the minimum difference between any two pairs
repeat this process one more time except do step 4. with 'word1' instead of 'word2'
your answer is the smaller of the two minimums