关于常见矩阵路径计算问题(iOS版本)

关于常见矩阵路径计算问题(iOS版本)

729dcafcfc039245b8f04f668c94a4c27c1e25e2.jpg

常见类型介绍:

  1. /*●问题描述:

给出一个矩阵,其中0表示通路,1表示墙壁,这样就形成了一个迷宫,要求编写算法求出其中一条路径。
●递归思路:

编写一个走迷宫函数,传入二位数组的下标,先假设该点位于最终路径上(将0置为2)再探测周围四个点是否可以走通(是否为0),如果可以走通则将该点四周能走通的点作为函数参数传入函数进入递归。若四周均不能走通(都不为0时)则将该点置回0表示该点不是最终路径上的点。
  在此思路中递归进入时表示了枚举路径,当发现此条路径走到某处再不能走通时就将路径该点置回0并且递归退出(回溯)寻找下一条可走通路径。
*/

/*
0 1 1 0
0 0 0 0
0 0 0 1
1 0 0 0
*/
规则中可以上下左右方向前进,求左上角到右下角的最小步数:
核心在于递归回溯判断,下面贴出代码

int mazeChat(int maze[][5],int i,int j){
    
    int end = 0;
    
    maze[i][j] = 2;
    
    //如果到终点直接置为1
    if (i == END_I && j == END_J) {
        end = 1;
    }
    
    //不是终点则按照右下左上判断
    
    if (end !=1 && j+1<=END_J && maze[i][j+1] == 0) {
        if (mazeChat(maze, i, j+1) == 1) {
            return 1;
        }
    }
    
    if (end !=1 && i+1<=END_I && maze[i+1][j] == 0) {
        if (mazeChat(maze, i+1, j)==1) {
            return 1;
        }
    }
    
    if (end !=1 && j-1>=START_J && maze[i][j-1] == 0) {
        if (mazeChat(maze, i, j-1) == 1) {
            return 1;
        }
    }
    
    if (end !=1 && i-1>=START_I && maze[i-1][j] == 0) {
        if (mazeChat(maze, i-1, j)==1) {
            return 1;
        }
    }

    
    //四周都没有路
    if (end !=1) {
        maze[i][j] = 0;
    }
    

    return end;
    
}

方法调用:

if (mazeChat(maze, 0, 0) == 0) {
        printf("没有通道");
        return;
    }else{
        printf("有通道\n");
    }

路径会在后面的打印中根据我们预先设定的值去判断:
附上地址:demo

2.最短路径和计算:
【问题描述】: 给出一个矩阵,从左上角开始走,只能向右或者向下,所有数字累加就是路径和,求出其中最小路径。
{1,3,5,9},
{8,1,3,4},
{5,0,6,1},
{8,8,4,0}

先说一共有多少种走法:因为只能向右或者向下,所以数学方向考虑只有向右3次向下三次即可,所以简单的C6-3 即可

//走法
int uniquePaths(int m, int n)
{
    int N = n + m - 2;
    int K = n - 1;
    double res = 1.0;
    for (int i = 1; i <= n - 1; i++)
    {
        res = res * (N - K + i) / i;
    }
    return (int)res;
}

关于这个问题:
/*
【问题描述】: 给出一个矩阵,从左上角开始走,只能向右或者向下,所有数字累加就是路径和,求出其中最小路径。

思路:只允许向右或者向下走 所以开始计算时当前s[i][j]只可能从s[i-1][j]+data[i][j]或者s[i][j-1]+data[i][j]计算得到
也就是s[i][j] = min(s[i-1][j],s[i][j-1])+ data[i][j] 即需要比较s[i-1][j],s[i][j-1])

因为第一行没有s[i-1][j]元素,只有s[i][j-1]元素。
第一列没有s[i][j-1]元素,只有s[i-1][j]元素。
需要特殊处理

*/
我们通过比较每一个位置左边和上边大小而重新对该位置的值进行求和赋值即可得到一个全新的矩阵,取矩阵最后一个值即是我们需要的路径最短之和:
重新赋值矩阵方法:

//获取行数和列数
    int rows = ROWS;
    int cols = COLS;
    //第一列
    for (int i = 1; i < rows; i++)
    {
        data[i][0] = data[i - 1][0] + data[i][0];
    }
    //第一行
    for (int i = 1; i < cols; i++)
    {
        data[0][i] = data[0][i - 1] + data[0][i];
    }
    //非第一行和第一列的元素
    for (int i = 1; i < rows; i++)
    {
        for (int j = 1; j < cols; j++)
        {
            if (data[i][j-1] > data[i-1][j]) {
                
                data[i][j] = data[i - 1][j] + data[i][j];
            }else{
                data[i][j] = data[i][j - 1] + data[i][j];
            }
        }
    }

//返回最短路径值
    return data[rows - 1][cols - 1];

拿到最小路径和的同时也可以通过得到的新矩阵去正推或者逆推得到路径下标的走法(这种重新赋值矩阵的方法优点在于只需要遍历一次即可拿到所有想要的结果,时间和空间复杂度低。缺点在于过程中存在的零时变量太多,所以之后得到新矩阵后才去获得路径下标);
两种推算路径下标方法:

printf("最优路径坐标:\n");
    int rowt = 3;
    int colt = 3;
    for (int i = 0; i  < 7; i++) {
        printf("(%d,%d)\n",rowt,colt);
        if(data[rowt-1][colt] < data[rowt][colt-1]){
            rowt--;
        }
        else{
            colt--;
        }
    }
    
    int g = 0;
    int k = 0;
    for (int j = 0; j<7; j++) {
        printf("{%d,%d}",g,k);
        if (data[g][k+1] < data[g+1][k]) {
            k++;
        }else{
            g++;
        }
        
    }

附上地址:demo

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,117评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,963评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,897评论 0 240
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,805评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,208评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,535评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,797评论 2 311
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,493评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,215评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,477评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,988评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,325评论 2 252
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,971评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,807评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,544评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,455评论 2 266

推荐阅读更多精彩内容