PHP - Search Two Max

Posted by Oscaner on November 21, 2018

问题描述

找出数组中最大的两个数的下标, 用 x1x2 存储, 且 A[x1] >= A[x2]

要求: 递归算法

给定: $A = [10, 30, 400, 50, 10, 1000, 200, 60, 20, 10];

结果:

1
2
A[x1] = A[5] = 1000
A[x2] = A[2] = 400

代码实现

该算法详解请看: 《C语言数据结构 (一) 绪论 (5) 迭代与递归 (3)》

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<?php

function swap(int &$x1, int &$x2) {
    $temp = $x1;
    $x1 = $x2;
    $x2 = $temp;
}

function max2(array $A, int $lo, int $hi, int &$x1, int &$x2) {
  // $A[$lo, $hi) 中仅有两个元素
  if ($lo + 2 == $hi) {
    if ($A[$x1 = $lo] < $A[$x2 = $lo + 1]) swap($x1, $x2);
    return;
  }

  // $A[$lo, $hi) 中有三个元素
  if ($lo + 3 == $hi) {
    if ($A[$x1 = $lo] < $A[$x2 = $lo + 1]) swap($x1, $x2);
    if ($A[$x2] < $A[$lo + 2]) $x2 = $lo + 2;
    if ($A[$x1] < $A[$x2]) swap($x1, $x2);
    return;
  }

  $mi = ($lo + $hi) / 2;

  // 找出左半边的 two max
  $x1L = 0; $x2L = 0;
  max2($A, $lo, $mi, $x1L, $x2L);

  // 找出右半边的 two max
  $x1R = 0; $x2R = 0;
  max2($A, $mi, $hi, $x1R, $x2R);

  // 判断左右两边的 two max
  if ($A[$x1L] > $A[$x1R]) {
    // 左边最大值 > 右边最大值
    $x1 = $x1L;

    // 判断 左边第二大值 与 右边最大值
    // 右边第二大值必然是四个值里最小的, 无需参与比较
    $x2 = ($A[$x2L] > $A[$x1R]) ? $x2L : $x1R;
  } else {
      // 右边最大值 >= 左边最大值
      $x1 = $x1R;

      // 判断 右边第二大值 与 左边最大值
      $x2 = ($A[$x2R] > $A[$x1L]) ? $x2R : $x1L;
  }
}

$A = [10, 30, 400, 50, 10, 1000, 200, 60, 20, 10];

$x1 = 0; $x2 = 0;

max2($A, 0, count($A), $x1, $x2);

echo 'A[x1] = ' . 'A[' . $x1 . '] = ' . $A[$x1] . "\n" .
     'A[x2] = ' . 'A[' . $x2 . '] = ' . $A[$x2] . "\n";

1.png


本文由 Oscaner 创作, 采用 知识共享署名4.0 国际许可协议进行许可
本站文章除注明转载/出处外, 均为本站原创或翻译, 转载前请务必署名