簡體   English   中英

如何在 O(n) 的列表列表中找到最小正整數?

[英]How to find the minimum positive integer in a list of lists in O(n)?

我正在嘗試用 python 編寫一個程序,該程序使用一個列表,該列表包含與外部列表長度一樣多的內部列表。 例如,

L = [[-10, -9,    99,   100],
     [ -6, -3,   100,   101],
     [ -1,  0,  1000,  1010],
     [ -1, 10, 10000, 24852]]

並輸出最小的正整數。 如果所有元素都是負數或 0,它會輸出 -1 is there。上面列表的輸出將為 10。元素也總是按升序排序,因此行和列都按升序排序。 這意味着如果您查看任何行或任何列,它將分別從左到右和從上到下排序。

問題是我必須以 O(n) 效率(n 指外部列表的長度)來執行此操作,但是我提出的每個解決方案都涉及嵌套循環,因此效率變為 O(n^2)。

如何在python中以O(n)效率實現這一目標?

編輯:我編寫了以下代碼,適用於某些情況但不適用於其他情況

def min_positive(L): 
i = 0
n = len(L)
j = len(L) - 1
min_pos = L[0][j]
while ( i < n and j >= 0 ): 
    if (L[i][j] < min_pos and L[i][j] > 0): 
        min_pos = L[i][j]
    if (L[i][j] >= min_pos): 
        j = j - 1 
    i = i + 1
if min_pos <= 0:
    min_pos = -1 
return min_pos

這適用於以下列表

L = [[-10, -9,    99,   100],
 [ -6, -3,   100,   101],
 [ -1,  0,  1000,  1010],
 [ -1, 10, 10000, 24852]]

但不適用於列表

L = [[-10, -9,    99,   100],
     [ -6, -3,   100,   101],
     [ -1,  0,  1000,  1010],
     [ 1, 10, 10000, 24852]]

IE。 輸出應該是 1 但它仍然是 10 感覺就像我很接近所以任何幫助將不勝感激!

O(n) 的想法是從右上角開始,當您處於正值時向左移動,否則向下移動。 對於方形數組,這最多訪問 2*n - 1 個索引,因為該算法從不回溯。 列表訂閱是O(1) ,所以我們是線性時間復雜度和常數空間復雜度。

def min_linear(L):
    n_rows = len(L)
    n_cols = len(L[0])
    row, col = 0, n_cols - 1  # start a the top-right corner
    best = L[-1][-1]  # initialized to the maximum element
    if best <= 0:
        # no positive elements
        return -1
    while col >= 0 and row < n_rows:
        val = L[row][col]
        if val > 0:
            best = min(val, best)
            col -= 1  # move left
        else:
            row += 1  # move down
    return best

這是最壞的情況, O(M + N)解決方案,其中 M 是行數,N 是列數。

L = [[-10, -9,    99,   100],
     [ -6, -3,   100,   101],
     [ -1,  0,  1000,  1010],
     [ -1, 10, 10000, 24852]]

def get_least_positive(list_of_lists):
    minimum = float("inf")

    # start from top right
    row = 0
    column = len(list_of_lists[0]) - 1

    # follow the staicase
    while row < len(list_of_lists) and column >= 0:
        elem = list_of_lists[row][column]
        if elem > 0:
            minimum = min(minimum, elem)
            column -= 1
        else:  # found Negative, go to next row.
            row += 1

    return minimum if minimum != float('inf') else -1


print(get_least_positive(L))

我可以提供一些基本的想法:

1.從右下角開始

因為它在rowcolumn 中排序,這意味着右下角最大,如果右下角為負,則其余為負。

2.制作路徑行走解決方案

這意味着您想向下走(下降)直到遇到負數,然后再向另一個方向移動。 效用上升的優勢,你可以不用檢查中間項目就走到min pos,因為它們明顯更大。 通過這樣做,您也可以跳過負值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM