# Leetcode 40. Combination Sum II ## 題解 ### DFS + Sorting + Binary Search 利用 sorting 和 Binary Search 先把大於 target 的數字排除掉,然後 DFS Back Tracking ```python! class Solution: def combinationSum2(self, candidates: List[int], target: int) -> List[List[int]]: def sort(left: int, right: int, nums: List[int]): if left >= right: return i = left j = right pivot = left while i < j: while nums[j] > nums[pivot] and i < j: j -= 1 while nums[i] <= nums[pivot] and i < j: i += 1 nums[i],nums[j] = nums[j],nums[i] nums[i],nums[pivot] = nums[pivot],nums[i] sort(left,i - 1,nums) sort(i + 1,right,nums) def binary_search(nums: List[int], target: int): left = 0 right = len(nums) - 1 ans = 0 while left <= right: mid = left + (right - left) // 2 if nums[mid] <= target: left = mid + 1 ans = left else: right = mid - 1 return ans sort(0,len(candidates) - 1,candidates) right_bound = binary_search(candidates, target) # 利用 Binary Search 找到大於 target 數字的邊界 candidates = candidates[:right_bound] n = len(candidates) output = [] def dfs(start:int,sums: int, ans: List[int]): if sums > target: return if sums == target: output.append(ans[:]) else: for i in range(start,n): if i > start and candidates[i] == candidates[i-1]: continue # 排除重複組合 c = candidates[i] ans.append(c) dfs(i+1,sums + c, ans) ans.pop() dfs(0,0,[]) return output ```