199/1 = Good pairs
We are given a list of integers, @list and asked to write a script to find the total count of Good Pairs. A pair (i, j) is called good if list[i] == list[j] and i < j.
If @list contains $n entries then the obvious way to do this is:
for $i (0 .. $n - 1) {
for $j ($i + 1 .. $n) {
if ($list[$i] == $list[$j]) {
-- we have an answer
}
}
}
Doing the loops like this ensures that we have tested all possible values of $i, $j where $i < $j.
The test for $list[$i] == $list[$j] is performed ($n - 1)**2/2 times, but it is not obvious to me that there is a more efficient way of doing this.
199/2 = Good triplets
We are given an array of $n integers, @array and three integers $x, $y, $z and asked to write a script to find out total Good Triplets in the given array.
The triplet $array[$i], $array[$j], $array[$k] is good if:
$i < $j < $k and
abs($array[$i] - $array[$j]) <= $x and
abs($array[$j] - $array[$k]) <= $y and
abs($array[$i] - $array[$k]) <= $z
Once again it seems inevitable that we perform nested loops:
for $i (0 .. $n - 2) {
for $j ($i + 1 .. $n - 1) {
for $k ($j + 1 .. $n) {
if (abs($array[$i] - $array[$j]) <= $x
and abs($array[$j] - $array[$k]) <= $y
and abs($array[$i] - $array[$k]) <= $z) {
-- we have an answer
}
}
}
}
As before, the for loop limits impose $i < $j < $k and we only need to test the three differences against $x, $y and $z to identify good triplets.
If @array is long then this will be quite time-consuming, but we can optimise the algorithm somewhat because in the loop over $j we can already test for the first of the 'abs' conditions and skip the loop over $k:
for $i (0 .. $n - 2) {
for $j ($i + 1 .. $n - 1) {
next unless abs($array[$i] - $array[$j]) <= $x;
for $k ($j + 1 .. $n) {
if (abs($array[$j] - $array[$k]) <= $y
and abs($array[$i] - $array[$k]) <= $z) {
-- we have an answer
}
}
}
}
No comments:
Post a Comment