给定一个数组,我想显示其总和等于K的不同元素对的计数 - 我已编写如下代码,但我无法正确使用array_diff:\
<?PHP
function numberOfPairs($a, $k) {
$cnt = 0;
for($i=0; $i<count($a); $i++){
for($j=$i; $j<count($a); $j++){
if($a[$i]+$a[$j] == $k){
$arrRes[$i][0] = $a[$i];
$arrRes[$i][1] = $a[$j];
$cnt++;
}
}
}
sort($arrRes);
//print $cnt;
$d = $cnt;
for($i=0; $i<count($arrRes); $i++){
for($j=0; $j<count($arrRes); $j++){
$diff = array_diff($arrRes[$i], $arrRes[$j]);
if($diff == null)
$d += 1;
}
}
print $d;
}
$a = [6,6,3,9,3,5,1];
$k = 12;
numberOfPairs($a, $k);
?>
这里,总和等于12的输出数组,即$ arrRes的结果是 -
[0] => Array ( [0] => 3 [1] => 9 )
[1] => Array ( [0] => 6 [1] => 6 )
[2] => Array ( [0] => 6 [1] => 6 )
[3] => Array ( [0] => 9 [1] => 3 )
计数为4,但计数应为2,因为(6,6)和(3,9)是唯一不同的对。
答案 0 :(得分:2)
您可以通过使用php中的数组是散列图的事实来简化您的解决方案:
function numberOfPairs($a, $k) {
$used=[];
for ($i=0; $i<count($a); $i++)
for ($j=$i+1; $j<count($a); $j++) {
$v1 = min($a[$i], $a[$j]);
$v2 = max($a[$i], $a[$j]);
if ($k == $v1+$v2)
$used[$v1.'_'.$v2] = true;
}
return count($used);
}
$a = [6,6,3,9,3,5,1];
$k = 12;
echo numberOfPairs($a, $k);
答案 1 :(得分:1)
您可以使用已使用的数字创建一个平面数组并进行检查,以便不再使用in_array。
function numberOfPairs($a, $k) {
$cnt = 0;
$used=[];
for($i=0; $i<count($a); $i++){
for($j=$i; $j<count($a); $j++){
if($a[$i]+$a[$j] == $k && !in_array($a[$i], $used) && !in_array($a[$i],$used)){
$arrRes[$i][0] = $a[$i];
$arrRes[$i][1] = $a[$j];
$used[] = $a[$i];
$used[] = $a[$j];
$used = array_unique($used);
$cnt++;
}
}
}
sort($arrRes);
//print $cnt;
// Not sure what the code below does, but I just left it the way it was.
$d = $cnt;
for($i=0; $i<count($arrRes); $i++){
for($j=0; $j<count($arrRes); $j++){
$diff = array_diff($arrRes[$i], $arrRes[$j]);
if($diff == null)
$d += 1;
}
}
print $d;
}
$a = [6,6,3,9,3,5,1];
$k = 12;
numberOfPairs($a, $k);
答案 2 :(得分:1)
对数组进行排序并从两端移动索引,直到它们不重叠,在接受的答案中得到O(n log n)而不是O(n ^ 2)
function numberOfPairs($a, $k) {
sort($a);
$i = 0;
$j = count($a)-1;
// save last inseted array to avoid duplicates
$last = [];
while($i < $j) {
$s = $a[$i] + $a[$j];
if($s == $k) {
$t = [$a[$i++], $a[$j--]];
// Check for duplicate
if ($t != $last) {
$d[] = [$a[$i++], $a[$j--]];
$last = $t;
}
}
elseif($s > $k) $j--;
else $i++;
}
return $d;
}
答案 3 :(得分:1)
这是我在给定数组和目标总和时找到不同加数对的方法。
array_count_values()
将通过压缩重复的加数并将它们存储为键(以及它们的出现次数作为值)来减少输入数组的大小。ksort()
以确保以递增顺序处理加数。这对于避免处理超出数字集中点的加数非常重要。k
的一半的加数并且具有匹配的加数。k
时,请勿继续迭代。代码:(Demo)
function numberOfPairs($a,$k){
$a=array_count_values($a); // enable use of the very fast isset() function and avoid iterating duplicates
ksort($a); // order so that only the lower values need to be iterated
foreach($a as $num=>$occur){
if(($double=$num*2)>=$k){ // we are at or past the middle
if($double==$k && $occur>1) $result[]=[$num,$k-$num]; // addends are equal and 2 exist, store before break
break;
}elseif(isset($a[$k-$num])){ // matching addend found, store & continue
$result[]=[$num,$k-$num];
}
}
var_export($result);
}
$a = [6,6,3,9,3,5,1];
$k = 12;
numberOfPairs($a,$k);
输出:
array (
0 =>
array (
0 => 3,
1 => 9,
),
1 =>
array (
0 => 6,
1 => 6,
),
)
array_count_values()
可能是代码段中最昂贵的函数调用,但它将所有后续进程设置为快速,简洁,直接和逻辑(我认为,可读)。