贪婪的递归搜索

时间:2016-11-05 22:53:49

标签: java data-structures greedy

我的教授给了我们一项任务,我需要在一个网格中的一个给定点周围搜索构成一个组的所有其他点(在这个例子中,我需要找到一个" L& #34;问题中的形状)。

所以网格是10x10,我的教授给了我们一个开始的地方。我的教授给了我们一个想法,就是检查相邻的点,然后将它添加到一个集合中,如果新发现的点(将在集合中)然后以递归方式调用该方法。

private Spot findSpots(Set<Spot> spots, Set<Spot> activeSpots, Spot initial) {
    Spot newSpot = null;


    Set<Spot> activeSet = new HashSet<Spot>();
    checkAround(activeSet, new Spot(initial.i - 1, initial.j));
    checkAround(activeSet, new Spot(initial.i + 1, initial.j));
    checkAround(activeSet, new Spot(initial.i, initial.j - 1));
    checkAround(activeSet, new Spot(initial.i, initial.j + 1));


    for (Spot spot : activeSet) {
        newSpot = findSpots(spots, activeSpots, spot);
        if (grid[newSpot.i][newSpot.j] == true)
            spots.add(newSpot);
    }

    return newSpot;
 }
 private boolean checkAround(Set<Spot> spots, Spot spot) {
    if (!spots.contains(spot)) {
        spots.add(spot);
        return true;
    }
    return false;
 }

我知道我需要一个边界条件(否则我会得到stackoverflow异常),但我需要逻辑方面的帮助。

2 个答案:

答案 0 :(得分:3)

  

我知道我需要一个边界条件[...]

你自己说的。一个关键词是 boundary 。 您需要检查网格中的点是否合法, 如果没有,就停止探索。

另一个停止条件是如果已经访问该地点。

如果实施这两个停止条件, 如果在进行进一步的递归调用之前执行这些检查, 你会找到一个没有溢出堆栈的解决方案。

这样的事情:

private int countSpots(Set<Spot> visited, Spot spot) {
    if (!isValid(spot) || visited.contains(spot)) {
        return 0;
    }

    visited.add(spot);

    int count = 1;
    count += countSpots(visited, new Spot(spot.x - 1, spot.y));
    count += countSpots(visited, new Spot(spot.x + 1, spot.y));
    count += countSpots(visited, new Spot(spot.x, spot.y + 1));
    count += countSpots(visited, new Spot(spot.x, spot.y - 1));
    return count;
}

顺便说一句,您使用的算法是flood fill的变体, 请在维基百科页面中查看更多信息,提示和提示。

答案 1 :(得分:1)

我这样做的方式是:

  • 我添加了网格的边界条件
  • 我有两套,其中一套包含我去过的所有景点,另一套包含我需要的斑点
  • 如果该地点已经存在于
  • 中,则返回
  • 将斑点添加到正确的集合
  • 以递归方式呼叫所有现场