Shortest Cell Path

Algorithms practice:leetcode

Description

In a given grid of 0s and 1s, we have some starting row and column sr, sc and a target row and column tr, tc. Return the length of the shortest path from sr, sc to tr, tc that walks along 1 values only.

Each location in the path, including the start and the end, must be a 1. Each subsequent location in the path must be 4-directionally adjacent to the previous location.

It is guaranteed that grid[sr][sc] = grid[tr][tc] = 1, and the starting and target positions are different.

If the task is impossible, return -1.

Example

input:
grid = [[1, 1, 1, 1], [0, 0, 0, 1], [1, 1, 1, 1]]
sr = 0, sc = 0, tr = 2, tc = 0
output: 8
(The lines below represent this grid:)
1111
0001
1111

grid = [[1, 1, 1, 1], [0, 0, 0, 1], [1, 0, 1, 1]]
sr = 0, sc = 0, tr = 2, tc = 0
output: -1
(The lines below represent this grid:)
1111
0001
1011

Constraints

[time limit] 5000ms
[input] array.array.integer grid
1 ≤ arr.length = arr[i].length ≤ 10
[input] integer sr
[input] integer sc
[input] integer tr
[input] integer tc
All sr, sc, tr, tc are valid locations in the grid, grid[sr][sc] = grid[tr][tc] = 1, and (sr, sc) != (tr, tc).
[output] integer

code

#import <iostream>
#import <vector>
#import <unordered_set>
#include <deque>
using namespace std;

int shortestCellPath(const vector<vector<int>>& grid, int sr, int sc, int tr, int tc)
{
	// your code goes here
  // use BFS algorithm 
  vector<vector<int>> visited(grid);// value =1 is not visited
  visited[sr][sc]=0;
  deque<vector<int>> q;
  vector<int> source{sr,sc,0};
  q.push_back(source);
  int R=grid.size();
  int C=grid[0].size();
  while(!q.empty())
  {
    int size = q.size();
    for(int i=0;i<size;i++)
    {
      vector<int> curNode= q.front();
      q.pop_front();
      if(curNode[0] == tr && curNode[1] == tc)
        return curNode[2];
      vector<pair<int,int>> nextNodes;
      nextNodes.push_back(make_pair(curNode[0]-1,curNode[1]));//up
      nextNodes.push_back(make_pair(curNode[0]+1,curNode[1]));//bottom
      nextNodes.push_back(make_pair(curNode[0],curNode[1]-1));//left
      nextNodes.push_back(make_pair(curNode[0],curNode[1]+1));//right
      for(auto nextNode:nextNodes)
      {
        int r = nextNode.first;
        int c = nextNode.second;
        if(r>=0&&r<R && c>=0&&c<C && grid[r][c]==1 && visited[r][c]==1)
        {
          vector<int> nextvec{r,c,curNode[2]+1};
          q.push_back(nextvec);
          visited[r][c]=0;
        }
      }
    }
  }
  
  return -1;
}

int main() 
{
	return 0;
}

Oral process of solving problems

Solution: Breadth-First Search

Finding a shortest path is typically done with a breadth first search. Here, nodes are locations on the grid with value 1, and two nodes are neighbors if they are 4-directionally adjacent.

The breadth first search algorithm is given a source in the graph, and it explores all nodes distance 0 from the source, then all nodes distance 1, then all nodes distance 2, and so on. The algorithm records the node’s distance when it visits, and that way we can determine the shortest path in the graph to some target node.

By visiting nodes in order from distance to the source, this ensures that if we find the target word, we found it at the least possible distance and thus the answer is correct.

code2

#import <iostream>
#import <vector>

using namespace std;
bool findMinIndex(const vector<vector<int>>& dist, const vector<vector<int>>& selected, int& r, int& c)
{
    int aimR, aimC;
    int min = INT_MAX;
    for (int i = 0; i < dist.size(); i++)
    {
        for (int j = 0; j < dist[i].size(); j++)
        {
            if (selected[i][j] > 0 && min > dist[i][j])
            {
                min = dist[i][j];
                aimR = i; aimC = j;
            }
        }
    }
    if (min == INT_MAX)
    {
        return false;
    }
    if (aimR == r && aimC == c)
    {
        return false;
    }
    else
    {
        r = aimR;
        c = aimC;
        return true;
    }
};

int shortestCellPath(const vector<vector<int>>& grid, int sr, int sc, int tr, int tc)
{
	// your code goes here
  int   height = grid.size();
  int  width = grid[0].size();
  vector<vector<int>> dist(height, vector<int>(width,INT_MAX ));  // min path value
  vector<vector<int>> selected(grid); // value >0 means position can be selected

  int curRow = sr;
  int curCol = sc;
  dist[curRow][curCol] = 0;
  selected[curRow][curCol] = 0;

  for (int i = 0; i < width * height; i++)
    {
        cout << endl;
        cout << "current: " << curRow << " , " << curCol << " cur dist: " << dist[curRow][curCol] << endl;
    
        // up (curRow-1, curCol)
        if (curRow - 1 >= 0 && curRow - 1 < height && selected[curRow - 1][curCol] > 0)
        {
            dist[curRow - 1][curCol] = dist[curRow][curCol] + 1;
            cout <<"up next: " << curRow - 1<<" , " << curCol << " , " << dist[curRow - 1][curCol] << " cur dist: " << dist[curRow][curCol] << endl;
        }
        //left (curRow, curCol-1)
        if (curCol - 1 >= 0 && curCol - 1 < width && selected[curRow][curCol - 1] > 0)
        {
            dist[curRow][curCol - 1] = dist[curRow][curCol] + 1;
            cout << "left next: " << curRow << " , " << curCol - 1 << " , " << dist[curRow][curCol - 1] << " cur dist: " << dist[curRow][curCol] << endl;
        }
        //right (curRow, curCol+1)
        if (curCol + 1 < width && selected[curRow][curCol + 1] > 0)
        {
            dist[curRow][curCol + 1] = dist[curRow][curCol] + 1;
            cout << "right next: " << curRow << " , " << curCol + 1 << " , " <<dist[curRow][curCol + 1] << " cur dist: " << dist[curRow][curCol] << endl;
        }
        //below (curRow+1, curCol)
        if (curRow + 1 < height && selected[curRow + 1][curCol] > 0)
        {
            dist[curRow + 1][curCol] = dist[curRow][curCol] + 1;
            cout << "below next: " << curRow + 1 << " , " << curCol << " , " << dist[curRow + 1][curCol] << endl;
        }
        selected[curRow][curCol] = 0;
        if (!findMinIndex(dist, selected, curRow, curCol))
        {
                return -1;
        }
        else
        {
            if (curRow == tr && curCol == tc)
            {
                return dist[curRow][curCol];
            }
            cout << "find min " << curRow << " , " << curCol << endl;
        }
        //cout << curRow << " , " << curCol << " , " << dist[curRow][curCol] << endl;


    }
  return dist[tr][tc]==INT_MAX?-1:dist[tr][tc];
}

int main() 
{
	return 0;
}

words

link

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值