回溯算法
问题描述:
给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。
candidates 中的数字可以无限制重复被选取。
注:
所有数字(包括 target)都是整数。
解集不能包含重复的组合。
例:
输入:candidates = [2,3,6,7], target = 7,
所求解集为:
[
[7],
[2,2,3]
]
输入:candidates = [2,3,5], target = 8,
所求解集为:
[
[2,2,2,2],
[2,3,3],
[3,5]
]
解题:
class Solution {
/**
* @param Integer[] $candidates
* @param Integer $target
* @return Integer[][]
*/
public $lists = [];
function combinationSum($candidates, $target) {
if ( $target <= 0 || empty( $candidates ) )
return $this->lists;
sort($candidates); // 排序
$this->xh( $candidates, $target, [], 0 );
return $this->lists;
}
function xh( $cands, $target, $list, $index ) {
if ( $target < 0 )
return;
if ( $target == 0 ) {
$this->lists[] = $list;
return;
}
for ( $i = $index; $i < count($cands); ++$i ) {
if ( $target < $cands[$i] ) // 剪枝
break;
$list[] = $cands[$i];
$this->xh( $cands, $target - $cands[$i], $list, $i );
// 回溯
array_pop($list);
}
}
}
典型的回溯算法解题,排序数组sort($candidates); // 排序
后续进行剪枝
for ( $i = $index; $i < count($cands); ++$i ) {
if ( $target < $cands[$i] ) // 剪枝
break;
$list[] = $cands[$i];
$this->xh( $cands, $target - $cands[$i], $list, $i );
// 回溯
array_pop($list);
}
$cands为数组,$target为剩余值,$list为已组合值数组,$i回溯位子,因为元素可以重复出现,$i不用加1
题目来源:
https://leetcode-cn.com/problems/combination-sum/