zoukankan      html  css  js  c++  java
  • 剑指Offer_12_矩阵中的路径(参考问题:马踏棋盘)

    题目描述

       请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。

      例如:

           a   b  c   e

           s   f   c   s

           a  d   e   e

      矩阵中包含一条字符串"bcced"的路径,但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。

        参考问题:

                  马踏棋盘   : 将马随机放在国际象棋的 8x8 [0~7][0~7]的某个方格中,马按走棋(日字走法)规则进行移动。每个格子只能走一边,走遍棋盘上全部64个方格。求出马的行走路线,并按求出的行走路线,将数字1,2,…,64依次填入一个8×8的方阵,输出之。

         

      分析:

        此题可采用回朔法。首先在格子中任选一个格子作为路径起点,然后在上下左右的位置寻找下一步,寻找到则进入下一步,若上下左右均没有下一步,则返回上一步的位置从上一步寻找新的路径。矩阵还需一个对应的bool表,来记录走过的路径。

    Java实现代码如下:

     1 import java.util.*;
     2      
     3 public class Solution {
     4      
     5     public boolean hasPath(char[] matrix, int rows, int cols, char[] str) {
     6         if(matrix==null || matrix.length==0 || str==null || str.length==0 || matrix.length!=rows*cols || rows<=0 || cols<=0 || rows*cols < str.length) {
     7             return false ;
     8         }
     9  
    10         boolean[] visited = new boolean[rows*cols] ;
    11         int[] pathLength = {0} ;
    12  
    13         for(int i=0 ; i<=rows-1 ; i++) {
    14             for(int j=0 ; j<=cols-1 ; j++) {
    15                 if(hasPathCore(matrix, rows, cols, str, i, j, visited, pathLength)) { return true ; }
    16             }
    17         }
    18  
    19         return false ;
    20     }
    21      
    22     public boolean hasPathCore(char[] matrix, int rows, int cols, char[] str, int row, int col, boolean[] visited, int[] pathLength) {
    23         boolean flag = false ;
    24  
    25         if(row>=0 && row<rows && col>=0 && col<cols && !visited[row*cols+col] && matrix[row*cols+col]==str[pathLength[0]]) {
    26             pathLength[0]++ ;
    27             visited[row*cols+col] = true ;
    28             if(pathLength[0]==str.length) { return true ; }
    29             flag = hasPathCore(matrix, rows, cols, str, row, col+1, visited, pathLength)  ||
    30                    hasPathCore(matrix, rows, cols, str, row+1, col, visited, pathLength)  ||
    31                    hasPathCore(matrix, rows, cols, str, row, col-1, visited, pathLength)  ||
    32                    hasPathCore(matrix, rows, cols, str, row-1, col, visited, pathLength) ;
    33  
    34             if(!flag) {
    35                 pathLength[0]-- ;
    36                 visited[row*cols+col] = false ;
    37             }
    38         }
    39  
    40         return flag ;
    41     }
    42      
    43 }

    C++实现如下:

     1 boolean hasPath(char[] matrix, int rows, int cols, char[] str) {
     2         int flag[] = new int[matrix.length];
     3         for (int i = 0; i < rows; i++) {
     4             for (int j = 0; j < cols; j++) {
     5                 if (helper(matrix, rows, cols, i, j, str, 0, flag))
     6                     return true;
     7             }
     8         }
     9         return false;
    10     }
    11  
    12 boolean helper(char[] matrix, int rows, int cols, int i, int j, char[] str, int k, int[] flag) {
    13         int index = i * cols + j;
    14         if (i < 0 || i >= rows || j < 0 || j >= cols || matrix[index] != str[k] || flag[index] == 1)
    15             return false;
    16         if(k == str.length - 1) return true;
    17         flag[index] = 1;
    18         if (helper(matrix, rows, cols, i - 1, j, str, k + 1, flag)
    19                 || helper(matrix, rows, cols, i + 1, j, str, k + 1, flag)
    20                 || helper(matrix, rows, cols, i, j - 1, str, k + 1, flag)
    21                 || helper(matrix, rows, cols, i, j + 1, str, k + 1, flag)) {
    22             return true;
    23         }
    24         flag[index] = 0;
    25         return false;
    26     }

                  参考问题分析: 

          与上问题相似,需要的是一个8x8的数组,起始均为0,第一步走的格子填1,第二步填2....直至64,说明棋盘遍历完成。递归实现如下。  

     1 #include<stdio.h>
     2 #include <stdlib.h>
     3 #include<conio.h>
     4 #define N 8
     5 int cnt=1;     // 记录马的位置
     6 int n=1;
     7 int chess[8][8]={0};  //棋盘
     8 int move[8][2]={
     9     {1,-2},{2,-1},
    10     {2,1},{1,2},
    11     {-1,2},{-2,1},
    12     {-2,-1},{-1,-2}
    13     };
    14 void horse(int ,int );
    15 void printhorse();
    16 
    17 int main()           //主函数
    18 {
    19     chess[0][0]=1;
    20     horse(0,0);
    21     return 0;
    22 }
    23 void horse(int x,int y)   //执行过程
    24 {
    25     int i;
    26     int a,b;
    27     for(i=0;i<N;i++)
    28     {
    29         a=x+move[i][0];
    30         b=y+move[i][1];
    31         if(a>=0&&a<N&&b>=0&&b<N&&!chess[a][b])
    32         {
    33              chess[a][b]=++cnt;
    34             if(cnt<64)
    35             {   horse(a,b);
    36 
    37             }                     // 递归
    38             else{
    39                 printhorse();
    40             //  exit(0);
    41 
    42 
    43             }
    44                 chess[a][b]=0;//修改ab的值归为0
    45                 cnt--;
    46         }
    47     }
    48 }
    49 void printhorse()          //输出马踏棋盘
    50 {
    51     int i,j;
    52     printf("输出第%d中解法:
    ",n++);
    53     for(i=0;i<N;i++)
    54     {
    55         for(j=0;j<N;j++)
    56             printf("%3d ",chess[i][j]);
    57     printf("
    ");
    58     }
    59 }
  • 相关阅读:
    JavaScript 高级
    JavaScript 归纳
    完全二叉树, 最大堆 , 堆排序
    二叉树
    Java秒杀系统方案优化 高性能高并发实战(1)
    精选 SQL 脚本
    树形结构有关的SQL
    在Sql server数据库中,关于触发器的创建、调用及删除
    SQLServer 唯一键约束和唯一索引有什么区别?
    很不错的 VBA 网址
  • 原文地址:https://www.cnblogs.com/LexMoon/p/Offer_12.html
Copyright © 2011-2022 走看看