矩阵中的路径-剑指Offer

矩阵中的路径

题目描述

请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。 例如 a b c e s f c s a d e e 矩阵中包含一条字符串"bcced"的路径,但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。

思路

  1. 这个题目涉及到回溯算法,我们可以用一个栈来存储矩阵中的元素,当遍历到某个元素无法再进行下去的时候,我们就弹栈再继续从周围元素寻找匹配点
  2. 我们可以将矩阵做一下处理,使其每次匹配时每个位置的元素都可以和周围的元素做比较:
    • #,#,#,#,#,#
    • #,a,b,c,e,#
    • #,s,f,c,s,#
    • #,a,d,e,e,#
    • #,#,#,#,#,#
  3. 因为每次走的路径不能重复,所以我们需要再生成一个大小相等的矩阵用来记录这个位置是否走过
  4. 栈中存储的是每个元素的位置信息

代码

import java.util.Stack;
public class Solution {
    public boolean hasPath(char[] matrix, int rows, int cols, char[] str)
    {
    	if (matrix == null || str == null || (matrix.length == 0 && str.length != 0)) {
			return false;
		}
		if (str.length == 0) {
			return true;
		}
		char[][] data = new char[rows + 2][cols + 2];
		for (int i = 0; i < rows + 2; i++) {
			for (int j = 0; j < cols + 2; j++) {
				if (i == 0 || i == (rows + 1) || j == 0 || j == (cols + 1)) {
					data[i][j] = '#';
				} else {
					data[i][j] = matrix[(i - 1) * cols + j - 1];
				}
			}
		}
		boolean[][] flag = new boolean[rows + 2][cols + 2];
		for (int i = 0; i < rows + 2; i++) {
			for (int j = 0; j < cols + 2; j++) {
				flag[i][j] = true;
			}
		}
		int point = 0;
		Stack stack = new Stack();
		
		for (int i = 1; i < rows + 1; i++) {
			for (int j = 1; j < cols + 1; j++) {
				if (data[i][j] == str[point]) {
					int[] position = {i, j};
					flag[i][j] = false;
					stack.push(position);
					point++;
				}
				while (!stack.isEmpty() && point < str.length) {
					int[] temp = (int[]) stack.peek();
					int row = temp[0];
					int col = temp[1];
					if (data[row - 1][col] == str[point] && flag[row - 1][col] == true) {
						int[] position = {row - 1, col};
						flag[position[0]][position[1]] = false;
						stack.push(position);
						point++;
					} else if (data[row][col + 1] == str[point] && flag[row][col + 1] == true) {
						int[] position = {row, col + 1};
						flag[position[0]][position[1]] = false;
						stack.push(position);
						point++;
					} else if (data[row + 1][col] == str[point] && flag[row + 1][col] == true) {
						int[] position = {row + 1, col};
						flag[position[0]][position[1]] = false;
						stack.push(position);
						point++;
					} else if (data[row][col - 1] == str[point] && flag[row][col - 1] == true) {
						int[] position = {row, col - 1};
						flag[position[0]][position[1]] = false;
						stack.push(position);
						point++;
					} else {
						stack.pop();
						point--;
					}
				}
				if (point == str.length) {
					return true;
				}
				for (int m = 0; m < rows + 2; m++) {
					for (int n = 0; n < cols + 2; n++) {
						flag[m][n] = true;
					}
				}
			}
		}
		return false;
    }


}
posted @ 2016-08-05 20:31  RosenDing  阅读(396)  评论(0编辑  收藏  举报