[英]Unsorted array - Getting index from next higher value | Complexity O(n), PHP
我搜索了一個復雜度為 O(n)的 PHP 算法。 我有一個整數數組,我想要每個元素的索引號比這個最近的大值或 -1 如果它不存在。
注意:每個值都是唯一的。
示例:
$arr = [7, 3, 5, 4];
$result = [-1, 3, 0, 2];
解釋:
function follows ($arr, $index) {
$filter = array_filter($arr, function($el) use ($arr, $index) { return $el > $arr[$index]; });
if (count($filter)===0)
return -1;
else
return array_search(min($filter), $arr);
}
$res = [];
for ($i=0; $i<count($arr); $i++) {
$res[] = follows($arr,$i);
}
var_dump($res); // => [-1, 3, 0, 2]
我應該使用asort
(例如: [3, 4, 5, 7]
),所以這些值被排序,我可以在那里獲得下一個元素的原始索引。
這是它的想法的一部分:
$arr = [ 7, 3, 5, 4];
asort($arr);
for($i=0; $i<count($arr); $i++) {
echo 'For: ' . $i . ': ' . $arr[$i].'<br>';
}
echo "<br>";
foreach ($arr as $key => $val) {
echo 'ForEach; ' . $key . ': ' . $val .'<br>';
}
echo '<br><br>' . $arr[2];
使用 asort 排序后,索引與您在for-loop
看到的相同,但在forEach-loop
它們是新排序的,但索引仍然相同。
思路:從for循環中取出索引,得到forEach-loop對應的索引加1,得到原始索引。
示例:我的數組中的索引 1 的值為 3,在 for 循環中的索引仍為 1,但在 forEach 循環中的索引為 0。到達那里時,值為 4 的下一個元素(索引 1)的原始索引為3.
最后一步很簡單。 任何人都可以幫助在沒有找到的情況下從 for 索引到 forEach 索引獲取缺失的鏈接嗎?
我將數組迭代 3 次(array_flip、for、for)並對它排序 1 次(ksort)。 我不知道如何計算復雜度......也許,將循環計數為O(N)
並將 ksort 計數為O(N*log(N))
。 所以最終的復雜度是O(N*log(N))
。 我不能讓它變小:)
$arr = [7, 3, 5, 4];
$flip = array_flip($arr); // prepare for sort
ksort($flip); // sort
// put results into place
$keys = array_keys($flip);
for ($i = 0; $i < count($flip) - 1; $i++) {
$flip[$keys[$i]] = $flip[$keys[$i + 1]];
}
$flip[$keys[count($keys) - 1]] = -1;
// finalize results
$result = [];
for ($i = 0; $i < count($arr); $i++) {
array_push($result, $flip[$arr[$i]]);
}
print_r($result);
外部測試鏈接: 點擊
這是一個不翻轉數組的版本,因此可以處理任何類型的數組數據。 它使用一個單一的回路和asort
所以是O(n*log(n))
一旦數據被排序, key
函數用於確定循環中下一個較大值的key; 當循環結束時,最終的“下一個”值設置為 -1(因為沒有更大的值)。 此時輸出具有正確的鍵/值對,但不是按數字順序排列的(這可能足以滿足您的需要):
$arr = [7, 3, 5, 4];
asort($arr);
$temp = [];
$count = 1;
$key = key($arr);
while (next($arr) !== false) {
$temp[$key] = key($arr);
$key = key($arr);
$count++;
}
$temp[$key] = -1;
print_r($temp);
輸出:
Array
(
[1] => 3
[3] => 2
[2] => 0
[0] => -1
)
如果您需要對鍵進行排序(例如,如果您希望在使用foreach
循環時按順序排列條目),您可以使用另一個循環,利用上面代碼中生成的$count
變量來復制值進入一個新的有序數組:
$result = [];
for ($i = 0; $i < $count; $i++) {
$result[] = $temp[$i];
}
print_r($result);
輸出:
Array
(
[0] => -1
[1] => 3
[2] => 0
[3] => 2
)
如果你不需要這個,你可以從第一個代碼塊中刪除$count
的計算。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.