判斷一個陣列是否為單調有序(嚴格遞增、嚴格遞減、或非嚴格),只需單次遍歷,時間複雜度 O(n),空間複雜度 O(1)。本文提供健壯的實現,處理空陣列、單元素、相等元素等邊界情況。
/**
* 判斷陣列是否為單調有序
* @param array $array 數值陣列
* @return string 'asc' | 'desc' | 'unordered' | 'empty' | 'single'
*/
function checkArrayOrder(array $array): string {
$count = count($array);
if ($count === 0) return 'empty';
if ($count === 1) return 'single';
$direction = 0; // 0=未確定, 1=遞增, -1=遞減
for ($i = 1; $i < $count; $i++) {
$prev = $array[$i - 1];
$curr = $array[$i];
if ($curr > $prev) {
if ($direction === -1) return 'unordered'; // 方向衝突
$direction = 1;
} elseif ($curr < $prev) {
if ($direction === 1) return 'unordered';
$direction = -1;
}
// $curr === $prev 時 direction 不變,允許非嚴格單調
}
return match ($direction) {
1 => 'asc', // 單調遞增 (含相等)
-1 => 'desc', // 單調遞減 (含相等)
0 => 'constant', // 全部相等
};
}
// 測試用例
$tests = [
[] => 'empty',
[5] => 'single',
[1, 2, 3, 4, 5] => 'asc',
[1, 2, 2, 3, 4] => 'asc', // 非嚴格遞增
[5, 4, 3, 2, 1] => 'desc',
[5, 4, 4, 3, 1] => 'desc', // 非嚴格遞減
[1, 3, 2, 4, 5] => 'unordered',
[1, 1, 1, 1] => 'constant',
[1, 2, 3, 2, 5] => 'unordered',
];
foreach ($tests as $arr => $expected) {
$result = checkArrayOrder($arr);
$status = $result === $expected ? '✅' : '❌';
echo "$status " . json_encode($arr) . " => $result (expected: $expected)\n";
}
direction = 0
for i = 1 to n-1:
if a[i] > a[i-1]:
if direction == -1: return unordered
direction = 1
else if a[i] < a[i-1]:
if direction == 1: return unordered
direction = -1
// else equal: continue
return direction_map[direction]
function isStrictlyMonotonic(array $array): bool {
$count = count($array);
if ($count < 2) return true;
$dir = 0;
for ($i = 1; $i < $count; $i++) {
$diff = $array[$i] <=> $array[$i-1]; // PHP 7+ 太空船運算子
if ($diff === 0) return false; // 相等即非嚴格
if ($dir === 0) $dir = $diff;
elseif ($dir !== $diff) return false;
}
return true;
}
function isRotatedSorted(array $array): bool {
$count = count($array);
if ($count < 2) return true;
$drops = 0;
for ($i = 1; $i < $count; $i++) {
if ($array[$i] < $array[$i-1]) $drops++;
}
// 最後一個與第一個比較
if ($array[0] < $array[$count-1]) $drops++;
return $drops <= 1;
}
$arr = range(1, 1_000_000);
shuffle($arr); // 打亂
$start = hrtime(true);
$result = checkArrayOrder($arr);
$time = (hrtime(true) - $start) / 1e6; // ms
echo "Time: {$time} ms, Result: $result\n";
// 典型輸出: Time: 12.3 ms, Result: unordered
binary_search。// 利用 array_is_list + 遞增檢查 (僅適用整數索引陣列)
function isSortedBuiltin(array $arr): bool {
if (!array_is_list($arr)) return false; // 關聯陣列需先 array_values
for ($i = 1; $i < count($arr); $i++) {
if ($arr[$i] < $arr[$i-1]) return false;
}
return true;
}
單次遍歷判斷有序是基礎且高頻的演算法操作。掌握方向狀態機模式,能靈活擴展至嚴格/非嚴格、旋轉、多維度等變體,面試與實戰皆受用。