-1

For a given array of number I need to print the duplicates along with the number of time they occurred in the array in the key value pair or associative array.

Given Array

$arr = [1,2,2,2,4,5,5,5,8,9,10,2,5,9,10,10];

Desired result

Array
(
    [2] => 4
    [5] => 4
    [9] => 2
    [10] => 3
)

What I have tried:

$arr = [1,2,2,2,4,5,5,5,8,9,10,2,5,9,10,10];
sort($arr);

$duplicates = [];
$count = 1; // I assumed that at least one element is always there so I did not take 0 (if I am not wrong)

for($i = 0; $i<count($arr); $i++){  
  for($j = $i+1; $j<count($arr); $j++){
    if($arr[$i] == $arr[$j]){  
      if(!in_array($arr[$j], $duplicates)){
        // array_push($duplicates, $arr[$j]);
        $count++;
        $duplicates[$arr[$j]] = $count;
      }
    }else{
      $count = 1;
    }
  }
}

echo "<pre>";
print_r($duplicates);

This successfully returns the duplicates as key but number of occurrences are incorrect.

Current Output

Array
(
    [2] => 2
    [5] => 2
    [9] => 2
    [10] => 4
)

What mistake am I making? Is my logic incorrect?

Aurazo Script
  • 115
  • 1
  • 1
  • 9
  • 1
    Its too bad that the interviewer wants the most complicated method, here is a simple one liner: $dupes = array_filter(array_count_values($array), function($v) { return $v > 1; }); – imvain2 Jul 15 '22 at 20:01

2 Answers2

0

If you consider the time complexity of your solution, it's not very efficient apart from logical error. Here is a solution that works:

<?php
function solution($arr) {
    $result =   array();
    $i = 0;
    /* Increase count for each numbers */
    while( $i < count($arr) ) {
        $current = $arr[$i];
        if ( !array_key_exists("$current", $result) ) {
            $result["$current"] = 1;
        } else {
            $result["$current"] += 1;
        }
        $i++;
    }

    /* Remove values less than 2 */
    foreach ( $result as $k => $res ) {
        if ( $res < 2 ) {
            unset($result[$k]);
        }
    }

    echo json_encode($result);
}

solution([1,2,2,2,4,5,5,5,8,9,10,2,5,9,10,10]);
?>

Output:

{"2":4,"5":4,"9":2,"10":3}
mickmackusa
  • 43,625
  • 12
  • 83
  • 136
hemnath mouli
  • 2,617
  • 2
  • 17
  • 35
  • Okay, thanks. That looks like a good solution. But, let's consider that I want to stick to my code even if the time complexity is not efficient because of using the two iterations. So, taking my code how do I fix it to get the required result? I need to learn that too. The reason is, I received this question in an interview today and the interviewer wanted me to use the `i,j` iterations. The solution you gave is something I knew already and I was aware of the inefficient time complexity of using two iterations. But he wanted to test my logic with iterations. So, how do I fix it ? – Aurazo Script Jul 15 '22 at 19:33
  • You can keep the current solution and give a new solution with my code below it. Let's give the future readers both the approaches. – Aurazo Script Jul 15 '22 at 19:34
0

I prefer isset() instead of array_key_exists() (as suggested by babak-maziar).

$arr = [1,2,2,2,4,5,5,5,8,9,10,2,5,9,10,10];

foreach($arr as $i)
    isset($counters[$i])
        ? $counters[$i]++
        : $counters[$i] = 1;

var_export($counters);

output:

array (
  1 => 1,
  2 => 4,
  4 => 1,
  5 => 4,
  8 => 1,
  9 => 2,
  10 => 3,
)%
sensorario
  • 20,262
  • 30
  • 97
  • 159