问题描述
思路
最短路径题目想到的算法是BFS,通过队列实现,把当前位置压入队列,再弹出一个队列元素,把该元素可能到达的位置再压如队列,这样一层一层的找,直到找到目标位置,走过的就是最短路径。
代码
队列初始化
因为要用队列实现BFS,所以首先定义队列的函数
//创建结点
typedef struct dataType{
int x;
int y;
}DType;
struct Node{
DType val;
struct Node* next;
};
//创建队列数据结构
struct Queue{
struct Node* head;
struct Node* tail;
int size;
};
typedef struct Queue* Qpinter;
typedef struct Node* nodePr;
//创建队列
Qpinter creatQueue()
{
Qpinter tempQ = (Qpinter)malloc(sizeof(struct Queue));
if(tempQ == NULL)
return NULL;
tempQ->head = NULL;
tempQ->tail = NULL;
tempQ->size = 0;
return tempQ;
}
//插入元素
Qpinter insetQueue(Qpinter q, DType a)
{
nodePr tempN = (nodePr)malloc(sizeof(struct Node));
tempN->val = a;
tempN->next = NULL;
if(q->head == NULL)
{
q->tail = tempN;
q->head = tempN;
}
else{
q->tail->next = tempN;
}
q->tail = tempN;
q->size++;
return q;
}
//删除元素
DType deleQueue(Qpinter q)
{
DType res;
nodePr temp;
if(q->head == NULL)
exit(0);
if(q->head == q->tail)
{
res = q->head->val;
temp = q->head;
q->head = NULL;
q->tail = NULL;
}
else{
res = q->head->val;
temp = q->head;
q->head = q->head->next;
}
free(temp);
q->size--;
return res;
}
//销毁队列
void destoryQ(Qpinter q)
{
nodePr temp;
while(q->head != NULL)
{
temp = q->head;
q->head = q->head->next;
free(temp);
}
}
主程序
int shortestPathBinaryMatrix(int** grid, int gridSize, int* gridColSize){
Qpinter Q1 = creatQueue();
DType temp = {0, 0}; //可以直接按照结构体顺序初始化
//判断一些边界条件
if(grid[0][0] == 1 || grid[gridSize - 1][*gridColSize - 1] == 1)
return -1;
if(gridSize == 1 && *gridColSize == 1) return 1;
//首先压如第一个元素
int res = 1;
int mark[gridSize][*gridColSize];
insetQueue(Q1, temp);
//mark记录走过的位置,以免重复走
mark[temp.x][temp.x] = 1;
//如果队列不为空,就一直往下走,若队列为空了,说明走完了所有的路也没找到目标位置,直接返回
while(Q1->head != NULL)
{
//计算当前队列的元素个数,来确定弹出元素的次数,因为每弹出一个元素就会加入一些元素,队列长度会变
int size = Q1->size;
for(int i = 0; i < size; i++){
temp = deleQueue(Q1);
// mark[x][y] = 1; mark标记应该放在8向遍历中,不然会重复很多操作,会超时
int x = temp.x;
int y = temp.y;
//相对位置计算
int destion[8][2] = {{x-1,y-1},{x-1,y},{x-1,y+1},{x,y-1},{x,y+1},{x+1,y-1},{x+1,y},{x+1,y+1}};
for(int j = 0; j < 8; j++)
{
int x = destion[j][0];
int y = destion[j][1];
//数组越界
if(x < 0 || x >= gridSize || y < 0 || y >= *gridColSize)
continue;
//找到了
if(x == gridSize - 1 && y == *gridColSize - 1) return res + 1; //已经走过了
if(mark[x][y] == 1)
continue;
//此路不通
if(grid[x][y] == 1) continue;
temp.x = x;
temp.y = y;
mark[temp.x][temp.y] = 1; //应该在8向遍历时更新,在pop时更新会超时
insetQueue(Q1, temp);
}
}
res++;
}
return -1;
}
总结
- 时间复杂度O(n):n为元素个数
- 空间复杂度O(K):K为队列的最大长度


