回溯算法入门级详解 + 练习
题型一:排列、组合、子集相关问题
46.全排列
题目链接
public List< List< Integer> > permute ( int [ ] nums) {
List< List< Integer> > ans = new ArrayList < > ( ) ;
int len = nums. length;
if ( len <= 0 ) return ans;
boolean [ ] used = new boolean [ len] ;
Deque< Integer> combina = new ArrayDeque < > ( ) ;
dfsPermute ( nums, used, len, ans, combina) ;
return ans;
}
private void dfsPermute ( int [ ] nums, boolean [ ] used, int len, List< List< Integer> > ans, Deque< Integer> combina) {
if ( combina. size ( ) == len) {
ans. add ( new ArrayList < > ( combina) ) ;
return ;
}
for ( int i = 0 ; i < len; i++ ) {
if ( ! used[ i] ) {
combina. addLast ( nums[ i] ) ;
used[ i] = true ;
dfsPermute ( nums, used, len, ans, combina) ;
used[ i] = false ;
combina. removeLast ( ) ;
}
}
}
47.全排列Ⅱ
题目链接
public List< List< Integer> > permuteUnique ( int [ ] nums) {
List< List< Integer> > ans = new ArrayList < > ( ) ;
int len = nums. length;
if ( len <= 0 ) return ans;
Deque< Integer> combina = new ArrayDeque < > ( ) ;
boolean [ ] used = new boolean [ len] ;
Arrays. sort ( nums) ;
dfsPermuteUnique ( nums, len, ans, combina, used) ;
return ans;
}
private void dfsPermuteUnique ( int [ ] nums, int len, List< List< Integer> > ans, Deque< Integer> combina, boolean [ ] used) {
if ( combina. size ( ) == len) {
ans. add ( new ArrayList < > ( combina) ) ;
return ;
}
for ( int i = 0 ; i < len; i++ ) {
if ( used[ i] ) continue ;
if ( i> 0 && nums[ i] == nums[ i- 1 ] && ! used[ i- 1 ] ) continue ;
combina. addLast ( nums[ i] ) ;
used[ i] = true ;
dfsPermuteUnique ( nums, len, ans, combina, used) ;
used[ i] = false ;
combina. removeLast ( ) ;
}
}
39.组合总和
题目链接
public List< List< Integer> > combinationSum ( int [ ] candidates, int target) {
List< List< Integer> > ans = new ArrayList < > ( ) ;
int len = candidates. length;
if ( len <= 0 ) return ans;
Arrays. sort ( candidates) ;
Deque< Integer> combina = new ArrayDeque < > ( ) ;
dfsCombinationSum ( candidates, target, len, ans, combina, 0 ) ;
return ans;
}
private void dfsCombinationSum ( int [ ] candidates, int target, int len, List< List< Integer> > ans, Deque< Integer> combina, int begin) {
if ( target == 0 ) {
ans. add ( new ArrayList < > ( combina) ) ;
return ;
}
for ( int i = begin; i < len; i++ ) {
if ( target - candidates[ i] < 0 ) {
break ;
}
combina. addLast ( candidates[ i] ) ;
dfsCombinationSum ( candidates, target - candidates[ i] , len, ans, combina, i) ;
combina. removeLast ( ) ;
}
}
40.组合总和Ⅱ
题目链接
public List< List< Integer> > combinationSum2 ( int [ ] candidates, int target) {
List< List< Integer> > ans = new ArrayList < > ( ) ;
int len = candidates. length;
if ( len <= 0 ) return ans;
Deque< Integer> combina = new ArrayDeque < > ( ) ;
Arrays. sort ( candidates) ;
dfsCombinationSum2 ( candidates, target, 0 , ans, combina, len) ;
return ans;
}
private void dfsCombinationSum2 ( int [ ] candidates, int target, int begin, List< List< Integer> > ans, Deque< Integer> combina, int len) {
if ( target == 0 ) {
ans. add ( new ArrayList < > ( combina) ) ;
return ;
}
for ( int i = begin; i < len; i++ ) {
if ( target - candidates[ i] < 0 ) break ;
if ( i> begin && candidates[ i] == candidates[ i- 1 ] ) continue ;
combina. addLast ( candidates[ i] ) ;
dfsCombinationSum2 ( candidates, target - candidates[ i] , i + 1 , ans, combina, len) ;
combina. removeLast ( ) ;
}
}
77.组合
题目链接
public List< List< Integer> > combine ( int n, int k) {
List< List< Integer> > ans = new ArrayList < > ( ) ;
Deque< Integer> combine = new ArrayDeque < > ( ) ;
dfsCombine ( 1 , n, k, ans, combine) ;
return ans;
}
private void dfsCombine ( int begin , int n, int k, List< List< Integer> > ans, Deque< Integer> combine) {
if ( combine. size ( ) == k) {
ans. add ( new ArrayList < > ( combine) ) ;
return ;
}
for ( int i = begin; i <= n- ( k- combine. size ( ) ) + 1 ; i++ ) {
combine. addLast ( i) ;
dfsCombine ( i+ 1 , n, k, ans, combine) ;
combine. removeLast ( ) ;
}
}
78.子集
题目链接
public List< List< Integer> > subsets ( int [ ] nums) {
List< List< Integer> > ans = new ArrayList < > ( ) ;
int len = nums. length;
if ( len <= 0 ) return ans;
Deque< Integer> sub = new ArrayDeque < > ( ) ;
dfsSubsets ( nums, 0 , len, ans, sub) ;
return ans;
}
private void dfsSubsets ( int [ ] nums, int index, int len, List< List< Integer> > ans, Deque< Integer> sub) {
ans. add ( new ArrayList < > ( sub) ) ;
for ( int i = index; i < len; i++ ) {
sub. addLast ( nums[ i] ) ;
dfsSubsets ( nums, i+ 1 , len, ans, sub) ;
sub. removeLast ( ) ;
}
}
90子集Ⅱ
60.第k个排列
93.复原IP地址