backtracking 回溯法题目总结

最近在Leetcode上做了几道关于回溯法的算法题。

虽说回溯的思想很简单,按深度优先算法,遍历解空间树,逐步探索。发现探索到某一步时,不符合描述,则退回到上一步(即回溯),重新选择分支。但实际操作起来,却是有些难度。。


1. 组合问题 Combinations

Given two integers n and k, return all possible combinations of k numbers out of 1 ... n.

For example,
If n = 4 and k = 2, a solution is:

[
  [2,4],
  [3,4],
  [2,3],
  [1,2],
  [1,3],
  [1,4],
]
即从n个数中选出k个数进行组合。

public void backtrack(int n, int k, int r, List<Integer> itemList,
			List<List<Integer>> resultList) {
		if (k == itemList.size()) {
			resultList.add(new ArrayList<Integer>(itemList));
			return;
		}
		for (int i = r; i <= n; i++) {
			itemList.add(i);
			backtrack(n, k, i + 1, itemList, resultList);
			itemList.remove(itemList.size() - 1);

		}
	}
思路如下:

   如果当前的itemList中的个数满足要求(即等于k),则将该itemList加入到结果集resultList中

   否则 从r开始到n遍历,依次探索,直到满足要求。

   将当前节点删除,返回上一节点,继续遍历。


2. word search

Given a 2D board and a word, find if the word exists in the grid.

The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once.

For example,
Given board =

[
  ["ABCE"],
  ["SFCS"],
  ["ADEE"]
]
word  =  "ABCCED" , -> returns  true ,
word  =  "SEE" , -> returns  true ,

word = "ABCB", -> returns false.


	public boolean exist(char[][] board, String word) {
		if (board.length == 0 || word.length() == 0)
			return false;
		for (int i = 0; i < board.length; i++) {
			for (int j = 0; j < board[0].length; j++) {
				boolean flag = backtrack(board, word, i, j, -1);
				if (flag)
					return true;
			}
		}
		return false;
	}

	public boolean backtrack(char[][] board, String word, int i, int j,
			int currentLength) {
		boolean flag = false;
		if (++currentLength + 1 == word.length()
				&& board[i][j] == word.charAt(currentLength))
			return true;
		if (board[i][j] != word.charAt(currentLength))
			return false;

		char tmp = board[i][j];
		board[i][j] = ' ';

		if (!flag && i + 1 < board.length)
			flag = backtrack(board, word, i + 1, j, currentLength);
		if (!flag && i > 0)
			flag = backtrack(board, word, i - 1, j, currentLength);
		if (!flag && j + 1 < board[0].length)
			flag = backtrack(board, word, i, j + 1, currentLength);
		if (!flag && j > 0)
			flag = backtrack(board, word, i, j - 1, currentLength);
		board[i][j] = tmp;

		return flag;
	}

主函数 exist 两层嵌套循环,获取根节点,即每个节点都可能作为出发的根节点

递归函数 backtrack 与回溯法基本思想一致

先判断是否满足要求,若满足,则直接返回

如果当前已不满足要求,则也直接返回

否则(即当前解为部分解),继续向下探索,直至满足条件。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值