今天刷到一个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 ",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 ",i, startRow, startCol); if (flag[startRow][startCol] == 0 && land[startRow][startCol] == 0) { printf("flag2=%d ",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 ", 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(" "); }
//测试代码 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; }