iT邦幫忙

2024 iThome 鐵人賽

DAY 2
0

https://ithelp.ithome.com.tw/upload/images/20241001/20169309l3i6RDXK7p.png
這題要從一個可能包含重複數字的整數陣列中,返回所有可能的「子集」(就是「冪集」),要注意的是,解集不能包含重複的子集。
想法:
這個問題的重點在怎麼處理重複元素,確保生成的子集不重複,可以用 回溯法生成所有子集。
步驟:
先把 nums 排序,這樣重複的元素就會相鄰,幫助在生成子集時重複,回溯法生成子集,用回溯法遞迴建子集,對每個數字,有兩個選擇,要麼把它加入當前子集,要麼不加(回溯法會探索每一種可能性),避免重複子集,在回溯的過程,如果當前數字跟前一個數字一樣,且前一個數字還沒被加入過,就跳過這個數字,避免產生重複的子集。

程式碼:
class Solution(object):
def subsetsWithDup(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
#結果變數,存所有子集
res = []
#把輸入的數組排序,便於後面判斷重複元素
nums.sort()

    #回溯函數,current是當前的子集,start是從哪個索引開始遞迴
    def backtrack(current, start):
        # 把當前生成的子集加入結果
        res.append(list(current))
        
        #從start索引開始,遞迴遍歷每個數字
        for i in range(start, len(nums)):
            # 如果當前數字和上一個數字同,就跳過,避免重複
            if i > start and nums[i] == nums[i - 1]:
                continue
            #選擇當前數字,把它加入子集
            current.append(nums[i])
            #繼續遞迴生成下一層子集
            backtrack(current, i + 1)
            #撤銷選擇(回溯),把剛加入的數字移除,進行下一個可能的選擇
            current.pop()
    
    #從空集開始回溯
    backtrack([], 0)
    return res

時間複雜度:由於生成的子集數量是2的n次方(其中 n 為 nums 的長度),而且每個子集可能最多包含 n 個元素,因此時間複雜度大約是O(n成2的n次方)

心得:
這類用回溯法解決的問題,幫我了解遞迴及決策樹的思考方式,回溯法讓我能通過不同的選擇路徑來解決問題,同時學會怎樣在過程中「剪枝」提高效率,另外,處理包含重複元素的集合,讓我了解排序的重要性,它可以簡化處理重複元素的邏輯。


上一篇
D16:Q80Remove Duplicates from Sorted Array II
下一篇
D18:Q96Unique Binary Search Trees
系列文
Leecode刷題28
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言