首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 判斷陣列是否有序 (單調遞增/遞減) 的 O(n) 演算法

     編輯:PHP 相關知識

PHP 判斷陣列是否有序 (單調遞增/遞減) 的 O(n) 演算法

判斷一個陣列是否為單調有序(嚴格遞增、嚴格遞減、或非嚴格),只需單次遍歷,時間複雜度 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;
}

變體:檢測旋轉有序陣列 (LeetCode 1752)

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;
}

效能基準 (PHP 8.1, 100 萬元素)

$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

應用場景

  • 資料驗證:導入 CSV/Excel 前檢查排序欄位是否有序。
  • 二分搜尋前置檢查:確保陣列有序才能用 binary_search。
  • 時間序列資料完整性:檢查時間戳是否單調遞增。
  • 演算法面試題:單調陣列判斷、旋轉陣列搜尋、山峰陣列驗證。

內建函式替代 (PHP 8.1+)

// 利用 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;
}

單次遍歷判斷有序是基礎且高頻的演算法操作。掌握方向狀態機模式,能靈活擴展至嚴格/非嚴格、旋轉、多維度等變體,面試與實戰皆受用。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved