【Leetcode】python - [1520] Maximum Number of Non-Overlapping Substrings 個人解法筆記

整理 LeetCode #1520 的個人解法筆記:解題思路、Time/Space Complexity 與邊界條件。

題目出處

1520. Maximum Number of Non-Overlapping Substrings

難度

hard

題目分類

Hash Table, String, Greedy, Sorting

2026-09-18 一刷

個人範例程式碼 - 一刷 (2026/09/18)

class Solution:
    def maxNumOfSubstrings(self, s: str) -> list[str]:
        first, last = {}, {}

        # fill up the first and last
        for i, c in enumerate(s):
            if c not in first:
                first[c] = i
            last[c] = i # edge: if only one, start = end

        intervals = []
        # traverse first (parse all letters start idx)
        for c, start in first.items(): 
            # fix the start letter, then extend the length to valid
            current_end = last[c]
            idx = start
            valid = True

            # extend the substring and check the condition
            while idx < current_end:
                idx += 1 
                current_c = s[idx]

                # if start before the front, not valid
                if first[current_c] < start:
                    valid = False
                    break
                
                # if end behind the current_end, extend the current_end
                current_end = max(current_end, last[current_c])

            if valid:
                # update ans
                intervals.append((start, current_end))

        res = []
        intervals.sort(key = lambda x: x[1]) # sort by end (greedy)
        prev_end = -1
        for start, end in intervals:
            if start > prev_end:
                prev_end = end
                res.append(s[start:end+1]) # + 1 for last letter 

        return res

算法說明

intervals 的進階題目,主要會分成三大步驟:

  1. 維護好每一個單字的 start, end 位置
  2. 處理合法的 substrings (intervals)
  3. 最後,所有紀錄好合法的 substrings,使用 greedy 的方式進行區間重疊處理找到最終答案。

1. 整理好每一個字母的 start, end 位置

只要某字母出現過,該字母所有出現位置都要包含在 substring 內,
我們先把完整字串整個掃過一次,把每一個文字 start, end 位置都紀錄好。

2. 處理合法的 substrings (intervals):

剛剛只有找到每一個字母的頭尾,現在要處理的是合法區間,也就是題目條件 (只要出現單一文字,那就需要包含全部文字)
包含兩種情況

  1. 新文字起點出現當前區間左側,此區間不可能成立。(可以繼續處理下一組開頭)
  2. 新文字終點出現在此區間之後,區間終點可以往後延伸,並繼續判斷。

3. 最終區間答案處理

這裡我們使用 greedy 的方式進行區間重疊處理找到最終答案。
具體來說,我們先把所有合法區間的 end 位置排序好 (sort),然後開始掃。

  1. 因為 end 已經排序好,理想情況是毫無重疊,那這樣 start 也自然都會在前。
  2. 當真的發生重疊的情況,那也會因為 end 先出現的關係,後出現的 end (數字會更大),有重疊的部分會被排除。
    透過判斷有無 start > prev_end 。 (比上一個區間的尾巴更右側) 才可以加入新答案。

Time Complexity

O(n * 26) = O(n) # 英文字母 26 個

Space Complexity

O(26) = O(1) # 英文字母 26 個

Boundary conditions

  1. 留意字串切片邊界 s[start:end+1] # 需多一個才能包含最後值
Licensed under CC BY-NC-SA 4.0
最後更新 Sep 19, 2026
使用 Hugo 建立
主題 StackJimmy 設計