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

猜你喜欢

转载自blog.csdn.net/fuyouzhiyi/article/details/129503781