组合总和 II
给定一个候选人编号的集合 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的每个数字在每个组合中只能使用 一次 。
注意:解集不能包含重复的组合。
方法一、回溯
由于题目要求解集不能包含重复的组合,因此和39.组合总和解法不同。
怎么去重呢?
优化剪枝方法:
Swfit
class Solution {var freq = [(Int, Int)]()//记录数字出现的频率,元组表示(Int,Int),第一个参数为数字,第二个参数为次数var ans:[[Int]] = [[Int]]()var sequence = [Int]()func combinationSum2(_ candidates: [Int], _ target: Int) -> [[Int]] {let candi = candidates.sorted()for val in candi {if freq.isEmpty || val != freq.last!.0 {freq.append((val, 1))}else {let cnt = freq.last!.1 + 1let _ = freq.popLast()freq.append((val, cnt))}}dfs(0, target)return ans}func dfs(_ pos: Int, _ rest: Int) {if rest == 0 {ans.append(sequence)return}if pos == freq.count || rest < freq[pos].0 {return}dfs(pos+1, rest)let most = min(rest/freq[pos].0, freq[pos].1)if most == 0 {return}for i in 1...most {sequence.append(freq[pos].0)dfs(pos+1, rest-i*freq[pos].0)}for _ in 1...most {let _ = sequence.removeLast()}}
}
OC
#import "Number40.h"@interface Number40 ()@property (nonatomic, strong) NSMutableArray <NSArray *>*freq;
@property (nonatomic, strong) NSMutableArray *sequece;
@property (nonatomic, strong) NSMutableArray <NSArray *>*ans;@end@implementation Number40- (instancetype)init {self = [super init];if (self) {_freq = [NSMutableArray array];_sequece = [NSMutableArray array];_ans = [NSMutableArray array];}return self;
}- (NSArray *)combinationSum:(NSArray *)candidates target:(NSInteger)target {candidates = [candidates sortedArrayUsingComparator:^NSComparisonResult(NSNumber * obj1, NSNumber *obj2) {return [obj1 compare:obj2];}];//记录每个数据出现的次数for (NSNumber *num in candidates) {NSInteger inte = [num integerValue];if (_freq.count == 0 || [_freq.lastObject[0] integerValue] != inte) {[_freq addObject:@[num, @1]];}else {NSInteger cnt = [_freq.lastObject[1] integerValue] + 1;[_freq removeLastObject];[_freq addObject:@[num, @(cnt)]];}}[self dfs:0 rest:target];return self.ans;
}- (void)dfs:(NSInteger)pos rest:(NSInteger)rest {if (rest == 0) {[self.ans addObject:self.sequece];return;}if (pos == self.freq.count || rest < [self.freq[pos].firstObject integerValue]) {return;}[self dfs:pos+1 rest:rest];NSInteger most = MIN(rest/[self.freq[pos].firstObject integerValue], [self.freq[pos].lastObject integerValue]);for (NSInteger i = 1; i<=most; i++) {[self.sequece addObject:self.freq[pos].firstObject];[self dfs:pos+1 rest:rest-i*[self.freq[pos].firstObject integerValue]];}for (NSInteger i = 1; i<=most; i++) {[self.sequece removeLastObject];}
}@end