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 }
  • 相关阅读:
    Golang Failpoint 的设计与实现
    没涉及到最值求解;观点:矩阵乘法无法表达出结果。 现实生活中事件、现象的数学表达
    多元微分学 枚举破解15位路由器密码 存储空间限制 拆分减长,求最值 数据去重
    ARP Poisoning Attack and Mitigation Techniques ARP欺骗 中间人攻击 Man-In-The-Middle (MITM) attack 嗅探 防范 Can one MAC address have two different IP addresses within the network?
    The C10K problem
    HTTP Streaming Architecture HLS 直播点播 HTTP流架构
    现代IM系统中消息推送和存储架构的实现
    现代IM系统中的消息系统架构
    长连接锁服务优化实践 C10K问题 nodejs的内部构造 limits.conf文件修改 sysctl.conf文件修改
    doubleclick cookie、动态脚本、用户画像、用户行为分析和海量数据存取 推荐词 京东 电商 信息上传 黑洞 https://blackhole.m.jd.com/getinfo
  • 原文地址:https://www.cnblogs.com/LexMoon/p/Offer_12.html
Copyright © 2011-2022 走看看