[Swift]LeetCode40. 组合总和 II | Combination Sum II
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公众号:山青咏芝(shanqingyongzhi)
➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/)
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址:https://www.cnblogs.com/strengthen/p/9901355.html
➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
Given a collection of candidate numbers (candidates
) and a target number (target
), find all unique combinations in candidates
where the candidate numbers sums to target
.
Each number in candidates
may only be used once in the combination.
Note:
- All numbers (including
target
) will be positive integers. - The solution set must not contain duplicate combinations.
Example 1:
Input: candidates =[10,1,2,7,6,1,5]
, target =8
, A solution set is: [ [1, 7], [1, 2, 5], [2, 6], [1, 1, 6] ]
Example 2:
Input: candidates = [2,5,2,1,2], target = 5, A solution set is: [ [1,2,2], [5] ]
给定一个数组 candidates
和一个目标数 target
,找出 candidates
中所有可以使数字和为 target
的组合。
candidates
中的每个数字在每个组合中只能使用一次。
说明:
- 所有数字(包括目标数)都是正整数。
- 解集不能包含重复的组合。
示例 1:
输入: candidates =[10,1,2,7,6,1,5]
, target =8
, 所求解集为: [ [1, 7], [1, 2, 5], [2, 6], [1, 1, 6] ]
示例 2:
输入: candidates = [2,5,2,1,2], target = 5, 所求解集为: [ [1,2,2], [5] ]
16ma
1 class Solution { 2 var result = [[Int]]() 3 func combinationSum2(_ candidates: [Int], _ target: Int) -> [[Int]] { 4 var tempCandidates = candidates 5 tempCandidates.sort{$0<$1} 6 combinationSum(tempCandidates, target, 0, [Int]()) 7 return result 8 } 9 10 func combinationSum(_ candidates: [Int], _ target: Int, _ currentInex: Int, _ usdedNums: [Int]) { 11 if target <= 0 { 12 if target == 0 { 13 result.append(usdedNums) 14 } 15 return 16 } 17 18 var previousNum = 0 19 for i in currentInex..<candidates.count { 20 let currentValue = candidates[i] 21 if currentValue > target || previousNum == currentValue { 22 continue 23 } 24 var usdedNumsCopy = usdedNums 25 usdedNumsCopy.append(currentValue) 26 combinationSum(candidates, target-currentValue, i + 1, usdedNumsCopy) 27 previousNum = currentValue 28 } 29 } 30 }
20ms
1 class Solution { 2 func combinationSum2(_ candidates: [Int], _ target: Int) -> [[Int]] { 3 var sortNums = candidates.sorted() 4 var tmp = [Int]() // current set for testing 5 var rlt = [[Int]]() // the result set 6 backtrack(&sortNums, &tmp, 0, target, &rlt) 7 return rlt 8 } 9 // subtrack a num from candidates to find the combination: 10 func backtrack(_ nums: inout [Int], _ tmp: inout [Int], _ start:Int, _ tg:Int, _ rlt:inout[[Int]]) { 11 if tg==0 { // find one and put into result; 12 rlt.append(tmp) 13 return 14 } 15 if start >= nums.count || nums[start] > tg { return } // go on condictions 16 for i in start...nums.count-1 { 17 if tg < nums[i] { return } 18 if i != start && nums[i]==nums[i-1] { continue } // skip the same num been used 19 tmp.append(nums[i]) 20 backtrack(&nums, &tmp, i+1, tg-nums[i], &rlt) 21 tmp.removeLast() 22 } 23 } 24 }
20ms
1 class Solution { 2 func combinationSum2(_ candidates: [Int], _ target: Int) -> [[Int]] { 3 var results: [[Int]] = [] 4 5 // sort input first for removing dups 6 let sortedCandidates = candidates.sorted() 7 8 dfs(sortedCandidates, 0, [], target, &results) 9 return results 10 } 11 12 // 1. 递归的定义 13 private func dfs(_ nums: [Int], _ startIndex: Int, _ combinations: [Int], _ target: Int, _ results: inout [[Int]]) { 14 15 // 3. 递归的出口 16 if target == 0 { 17 results.append(combinations) 18 return 19 } 20 21 22 for i in startIndex ..< nums.count { 23 24 let number = nums[i] 25 26 // skip dups 27 if i != startIndex, number == nums[i - 1] { 28 continue 29 } 30 31 if target < number { 32 // since it's sorted array, we can just return from here 33 break 34 } 35 36 // 2. 拆分 37 var mutableCombinations = combinations 38 mutableCombinations.append(number) 39 40 // here we need to increment to i + 1, because each candidate can only used once in combination 41 dfs(nums, i + 1, mutableCombinations, target - number, &results) 42 } 43 44 } 45 46 func combinatio1nSum2(_ candidates: [Int], _ target: Int) -> [[Int]] { 47 48 var result: [[Int]] = [] 49 let sorted = candidates.sorted() 50 combinationSum2H(sorted, target, 0, [], &result) 51 return result 52 } 53 54 55 func combinationSum2H(_ candidates: [Int], _ target: Int, _ start: Int, _ current: [Int], _ result: inout [[Int]]) { 56 if target == 0 { 57 result.append(current) 58 return 59 } 60 61 if start >= candidates.count { 62 return 63 } 64 65 66 for i in start..<candidates.count { 67 let item = candidates[i] 68 if i > start && item == candidates[i-1] { 69 continue 70 } 71 combinationSum2H(candidates, target - item, i+1, current + [item], &result) 72 } 73 } 74 }
24ms
1 class Solution { 2 func combinationSum2(_ candidates: [Int], _ target: Int) -> [[Int]] { 3 var result = [[Int]]() 4 var out = [Int]() 5 var candidates = candidates.sorted() 6 combinationSumDFS(candidates, target, 0, &out, &result) 7 return result 8 } 9 10 func combinationSumDFS(_ candidates: [Int], _ target: Int, _ start: Int, _ out: inout [Int], _ res: inout [[Int]]) { 11 if target == 0 { 12 res.append(out) 13 } else { 14 for i in start..<candidates.count { 15 if i > start && candidates[i] == candidates[i - 1] { 16 continue 17 } 18 guard target - candidates[i] >= 0 else { 19 break 20 } 21 out.append(candidates[i]) 22 combinationSumDFS(candidates, target - candidates[i], i + 1, &out, &res) 23 out.remove(at: out.count - 1) 24 25 } 26 } 27 } 28 }
28ms
1 class Solution { 2 func combinationSum2(_ candidates: [Int], _ target: Int) -> [[Int]] { 3 var result: [[Int]] = [] 4 var currentRes: [Int] = [] 5 recursionHelper(candidates.sorted(), target, 0, ¤tRes, &result) 6 return result 7 } 8 9 func recursionHelper(_ candidates: [Int], _ target: Int, _ index: Int, 10 _ currentRes: inout [Int], _ result: inout [[Int]]) { 11 if target == 0 { 12 result.append(currentRes) 13 return 14 } 15 if index >= candidates.count { 16 return 17 } 18 19 for idx in index..<candidates.count where target >= candidates[idx] { 20 if idx > index && candidates[idx - 1] == candidates[idx] { 21 continue 22 } 23 currentRes.append(candidates[idx]) 24 recursionHelper(candidates, target - candidates[idx], idx + 1, ¤tRes, &result) 25 currentRes.removeLast() 26 } 27 } 28 }
32ms
1 class Solution { 2 func combinationSum2(_ candidates: [Int], _ target: Int) -> [[Int]] { 3 var array = candidates.sorted() 4 var result = [[Int]]() 5 6 func helper(start: Int, temp: [Int], sum: Int) { 7 if sum == target { 8 result.append(temp) 9 return 10 } 11 if start >= array.count || sum > target { 12 return 13 } 14 for i in start ..< array.count { 15 if sum + array[i] > target { return } 16 if i != start && array[i] == array[i - 1] { continue } 17 var temp = temp 18 temp.append(array[i]) 19 helper(start: i + 1, temp: temp, sum: sum + array[i]) 20 } 21 } 22 helper(start: 0, temp: [Int](), sum: 0) 23 return result 24 } 25 }
36ms
1 class Solution { 2 func combinationSum2(_ candidates: [Int], _ target: Int) -> [[Int]] { 3 var result: [[Int]] = [] 4 var visited: [Bool] = Array(repeating: false, count: candidates.count) 5 var currentRes: [Int] = [] 6 recursionHelper(candidates.sorted(), target, 0, ¤tRes, &visited, &result) 7 return result 8 } 9 10 func recursionHelper(_ candidates: [Int], _ target: Int, _ index: Int, 11 _ currentRes: inout [Int], _ visited: inout [Bool], _ result: inout [[Int]]) { 12 if target == 0 { 13 result.append(currentRes) 14 return 15 } 16 if index >= candidates.count { 17 return 18 } 19 20 for idx in index..<candidates.count where !visited[idx] && target >= candidates[idx] { 21 if idx > 0 && candidates[idx - 1] == candidates[idx] && !visited[idx - 1] { 22 continue 23 } 24 currentRes.append(candidates[idx]) 25 visited[idx] = true 26 recursionHelper(candidates, target - candidates[idx], idx + 1, ¤tRes, &visited, &result) 27 currentRes.removeLast() 28 visited[idx] = false 29 } 30 } 31 }
40ms
1 class Solution { 2 3 func combinationSum2(_ candidates: [Int], _ target: Int) -> [[Int]] { 4 guard !candidates.isEmpty else { return [] } 5 guard target > 0 else { return [[]] } 6 7 var results = [[Int]]() 8 var tempPath = [Int]() 9 let sortedCandidates = candidates.sorted() 10 combinationSum(candidates: sortedCandidates, target: target, candidateIndex: -1, results: &results, path: &tempPath) 11 return results 12 } 13 14 func combinationSum(candidates: [Int], target: Int, candidateIndex: Int, results: inout [[Int]], path: inout [Int]) { 15 16 if target < 0 { return } 17 if target == 0 { 18 results.append(path) 19 return 20 } 21 22 for i in (candidateIndex+1..<candidates.count) { 23 if candidates[i] > target { continue} 24 if i > candidateIndex+1, candidates[i] == candidates[i-1] { 25 continue 26 } 27 path.append(candidates[i]) 28 combinationSum(candidates: candidates, target: target - candidates[i], 29 candidateIndex: i, results: &results, path: &path) 30 path.removeLast() 31 32 } 33 } 34 }