深度优先算法的一些整理与思考(一)

今天刷到一个leecode题:https://leetcode-cn.com/problems/pond-sizes-lcci/

用到了深度优先算法

 1. 深度优先搜索算法的概念:

 深度优先搜索属于图算法的一种,英文缩写为DFS(Depth First Search.)其过程简要来说是对每一个可能的分支路径深入到不能再深入为止,而且每个节点只能访问一次。如下例:

 

该图为一个无向图,假设我们从A开始进行深度优先搜索,第二点可以是B、C、D中任意一个,假设访问的是B,那么路径为A - B - E,搜索完成后直接退回B,搜索其下一个子节点,完成B之后退到A,搜索C节点,以此类推,直到找出需要的解。

        DFS适合此类题目:给定初始状态跟目标状态,要求判断从初始状态到目标状态是否有解。

        深度优先搜索(DFS)有两个重要的点:第一是当前怎么做,第二是下一步怎么做;模板如下:

  

bool check(参数)
{
    if(满足条件)
        return true ;
    return false;
}
  
void dfs(int step)
{
        判断边界
        {
            相应操作
        }
        尝试每一种可能
        {
               满足check条件
               标记
               继续下一步dfs(step+1)
               恢复初始状态(回溯的时候要用到)
        }
}

 

        文字描述的内容比较简单,网上搜索一大堆,下面结合具体的实例来理解下深度优先搜索算法的精髓

  leecode上的一个面试题:

  你有一个用于表示一片土地的整数矩阵land,该矩阵中每个点的值代表对应地点的海拔高度。若值为0则表示水域。由垂直、水平或对角连接的水域为池塘。池塘的大小是指相连接的水域的个数。编写一个方法来计算矩阵中所有池塘的大小,返回值需要从小到大排序。

  示例:

输入:
[
[0,2,1,0],
[0,1,0,1],
[1,1,0,1],
[0,1,0,1]
]
输出: [1,2,4]

代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define M 10000
int dataN[100][100];

int dfs(int **flag, int **land, int startRow, int startCol, int landSize, int landColSize)
{
    if (startRow < 0 || startCol < 0 || startRow >= landSize || startRow >= landColSize)
        return 0;
    if (flag[startRow][startCol] ==1 || land[startRow][startCol] != 0) {
        return 0;
    }
    if (dataN[startRow][startCol] != 0)
    {
        return dataN[startRow][startCol];

    }
    printf("flag=%d\n",flag[startRow][startCol]);

    //上 下 左 右 左上 左下 右上 右下
    int posX[8] = {-1, 1, 0, 0, -1, 1, -1, 1};
    int posY[8] = {0, 0, -1, 1, -1, -1, 1, 1};
    int max = 0;
    for (int i = 0; i < 8; i++) {
        int tempStartRow = startRow + posX[i];
        int tempStartCol = startCol + posY[i];
        printf("i=%d startRow = %d  startCol=%d\n",i, startRow, startCol);
        if (flag[startRow][startCol] == 0 && land[startRow][startCol] == 0) {
            printf("flag2=%d\n",flag[startRow][startCol]);
            flag[startRow][startCol] = 1;
            int ret = 1 + dfs(flag, land, tempStartRow, tempStartCol, landSize, landColSize);
            if (max < ret)
                max = ret;
            flag[startRow][startCol] = 0;
        }
    }
    land[startRow][startCol] = -1;
    dataN[startRow][startCol] = max;
    return max;
}
int compare(const void *arg1, const void *arg2)
{
    return *(int*)arg1-*(int*)arg2;
}
int* pondSizes(int** land, int landSize, int* landColSize, int* returnSize)
{
    int count = 0;
    int col = landColSize[0];
    int *data = (int *)malloc(sizeof(int) * landSize * col);
    int **flag = (int **)malloc(sizeof(int *) * landSize * col);
    for (int i = 0; i < landSize; i++) {
        flag[i] = (int *)malloc(sizeof(int) * col);
        memset(flag[i],0, col * sizeof(int));
    }

    for (int i = 0; i < landSize; i++) {
        for (int j = 0; j < col; j++) {
            if (flag[i][j] == 0 && land[i][j] == 0)  {
                printf("i=%d,j=%d\n", i,j);
                int ret = dfs(flag, land, i, j, landSize, col);
                //printf("ret=%d", ret);
                data[count++] = ret;
            }
        }
    }
    *returnSize = count;
    qsort(data, *returnSize, sizeof(int),compare);
    return data;
}


void printList(int data[],int count)
{
    for (int i = 0; i < count; i++) {
        printf("%d ", data[i]);
    }
    printf("\n");
}

//测试代码
int main() { int land[4][4] = {{0,2,1,0}, {0,1,0,1}, {1,1,0,1}, {0,1,0,1}}; int returnSize = 0; int* ptrArr[4]; for (int i = 0; i < 4; i++) { ptrArr[i] = land[i]; } int a[1] = {4}; int *p = pondSizes(ptrArr, 4,a, &returnSize); printList(p, returnSize); return 0; }

 

 

 

 

posted @ 2020-11-19 10:49  牛牛码代码  阅读(351)  评论(0编辑  收藏  举报