您的位置:首页 > 其它

深度搜素——搜索嵌套

2015-10-19 14:27 357 查看
搜索问题,扩展节点的时候会iterate一个link集合,一般就是一个for 循环,但有的时候,这个集合并不能直接得到,而是另一个搜索问题,比如n个数分k组问题的一种解法是:问题分成k个步骤,每个步骤确定一个组,具体一个组可分的方案的candidate集合就不是直接可以用for来iterate的,而是另一个搜索问题——子集问题。这就引出一个重点,iterate不光可以额用for,也可以用搜索,搜索本来就是在枚举,只不过枚举出一个解不是print输出,而是用来作为外层搜索的一个扩展节点,另外一点,搜索的结果体现在哪?side
effect,搜索一般是通过side effect体现状态、结果的。

def group(A, k):
groups, n, used = [[] for _ in xrange(k)], len(A), set()

def grouping(t, start):
if t == k:
if len(used) == n: print groups
return
if start == n: return
if start in used: grouping(t, start + 1)
else:
groups[t].append(A[start])
used.add(start)

def select(i, startIndex):
grouping(t + 1, start + 1)
for j in xrange(startIndex, n):
if j in used: continue
used.add(j)
groups[t].append(A[j])
select(i + 1, j + 1)
used.remove(j)
groups[t].pop()

select(start + 1, start + 1)
groups[t].pop()
used.remove(start)
grouping(0, 0)

还有一个例子:leetcode 282 expression add operators,给一串数字加操作符凑一个给定的值。问题的划分:每一步取若干数字作为一个数,参与计算,下一步取剩下的,取完为止。每一步按取几个数字作为数又分多种情况,同时确定了一个数之后按进行什么运算分又有4种情况。这里扩展节点是一个双重循环,先枚举取几个数字作为操作数,再枚举4种运算。

vector<string> addOperators(string num, int target) {
vector<string> ans;
function<void(int, long long, long long, string)> dfs = [&](int i, long long eval, long long pre, string s)->void {
if (i == num.size())  {
if (target == eval) ans.push_back(s);
}
else {
for (int j = i; j < num.size(); ++j) {
if (num[i] == '0' && j > i) break;
string cur = num.substr(i, j - i + 1);
long long value = stol(cur);
if (i == 0) {
dfs(j + 1, value, value, cur);
}
else {
dfs(j + 1, eval + value, value, s + "+" + cur);
dfs(j + 1, eval - value, -value, s + "-" + cur);
dfs(j + 1, eval - pre + value * pre, value * pre, s + "*" + cur);
}
}
}
};
dfs(0, 0, 0, "");
return ans;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: