#45374: Python解題報告


z2005x (Huffman)

學校 : 海洋大學
編號 : 68147
來源 : [114.24.32.137]
最後登入時間 :
2025-02-09 00:21:12
n805. 股票交易 (Stocks) -- TOI練習賽202310潛力組第1題 | From: [61.60.106.5] | 發表日期 : 2025-02-21 14:33

 

一、 程式碼功能

本程式碼旨在解決股票交易問題:給定 N 天的股票價格,以及期望的淨利潤 K。對於每一天 i,程式碼會找出如果在第 i 天買入股票,最快在哪一天賣出才能賺取至少 K 元的利潤。若在 N 天內都無法達成,則視為無解。

二、 演算法詳解

本程式碼的核心演算法是貪婪演算法結合優先佇列的應用。其運作流程如下:

  1. 初始化:

    • ans = [-1] * N: 初始化答案列表,預設所有買入日皆無解 (-1)。
    • pq = []: 建立最小堆積優先佇列 pq,用於儲存已買入但尚未賣出的股票資訊。佇列中每個元素為 (buy_price, buy_day) 元組,依 buy_price 排序。
  2. 逐日掃描 (current_day 迴圈):

    • 賣出檢查 (while 迴圈): 針對每一天 current_day,檢查優先佇列 pq 中是否有可賣出的股票。
      • 條件判斷 A[current_day] - pq[0][0] >= K: 檢查當天股價 (A[current_day]) 減去佇列中最低買入價 (pq[0][0]) 是否達到期望利潤 K
      • 若滿足條件,從 pq 中取出最低買入價的股票 (buy_price, buy_day),並更新答案列表 ans[buy_day] = current_day + 1,記錄最快賣出日current_day + 1
      • 重複執行,持續賣出 pq 中所有符合獲利條件的股票,確保找到最快賣出日。
    • 買入紀錄 (heappush): 將當天買入資訊 (A[current_day], current_day) 加入優先佇列 pq,等待未來賣出機會。
  3. 輸出結果: 遍歷 ans 列表,輸出每一天的最快賣出日。

三、 程式碼優勢

  • 時間效率: 使用優先佇列將尋找最佳賣出價的過程優化至對數時間複雜度,整體演算法時間複雜度為 O(N log N),能有效處理大規模資料。
  • 空間效率: 空間複雜度主要來自於答案列表 ans 和優先佇列 pq,皆為 O(N),空間效率良好。
  • 程式碼簡潔易懂: Python 程式碼精簡,邏輯清晰,易於理解與維護。

四、 時間複雜度分析

  • 外層迴圈 (for current_day in range(N)): 迴圈 N 次,時間複雜度 O(N)。
  • 內層迴圈 (while pq and ...): 雖然是巢狀迴圈,但每個股票只會被加入優先佇列 pq 一次,且最多被 heappop 取出一次。heappopheappush 操作的時間複雜度皆為 O(log N)。因此,內層迴圈的總時間複雜度均攤下來也是 O(N log N)。
  • 建堆與查詢 (heapq): 優先佇列的操作 heappushheappop 時間複雜度為 O(log N)。

總時間複雜度:O(N log N)

五、 空間複雜度分析

  • 答案列表 (ans): 儲存 N 個結果,空間複雜度 O(N)。
  • 優先佇列 (pq): 最差情況下,佇列可能儲存所有 N 天的買入資訊,空間複雜度 O(N)。

總空間複雜度:O(N)

六、 更精簡的程式碼

Python
from heapq import heappush, heappop

def solve():
    n, k = map(int, input().split())
    prices = list(map(int, input().split()))
    ans = [-1] * n
    pq = []

    for day in range(n):
        while pq and prices[day] - pq[0][0] >= k:
            buy_price, buy_day = heappop(pq)
            if ans[buy_day] == -1:
                ans[buy_day] = day + 1
        heappush(pq, (prices[day], day))

    print(*(ans)) # 更簡潔的輸出方式

solve()

精簡說明:

  • 函式化: 將程式碼包裝在 solve() 函式中,提高程式碼可讀性與模組化。
  • 更簡潔的變數命名: 使用 prices 代替 Aday 代替 current_day,使程式碼更簡潔。
  • 更簡潔的輸出: 使用 print(*(ans)) 語法,更簡潔地輸出答案列表,避免手動處理空格。

七、 總結

使用者提供的 Python 程式碼,運用貪婪演算法搭配優先佇列,有效率地解決了股票交易問題。其時間複雜度為 O(N log N),空間複雜度為 O(N),效能良好。精簡後的程式碼在維持演算法效率的同時,更進一步提升了程式碼的可讀性與簡潔性。此解法邏輯清晰,效率高,值得學習與應用。

希望這份更詳細的解題報告對您有所幫助!

 
ZeroJudge Forum