Adott egy 2D bináris mátrix együtt [][] ahol egyes cellák akadályok (jelölése0), a többi szabad cella (jelölése1) az Ön feladata, hogy megkeresse a forráscellából a lehető leghosszabb útvonal hosszát (xs ys) egy célcellába (xd yd) .
- Csak a szomszédos cellákba léphet (balról le jobbra).
- Az átlós mozgás nem megengedett.
- Egy útvonalon egyszer meglátogatott cella nem látogatható újra ugyanazon az útvonalon.
- Ha lehetetlen elérni a célt, vissza
-1.
Példák:
Bemenet: xs = 0 ys = 0 xd = 1 yd = 7
with[][] = [ [1 1 1 1 1 1 1 1 1 1]
[1 1 0 1 1 0 1 1 0 1]
[1 1 1 1 1 1 1 1 1 1] ]
Kimenet: 24
Magyarázat:
Bemenet: xs = 0 ys = 3 xd = 2 yd = 2
with[][] =[ [1 0 0 1 0]
[0 0 0 1 0]
[0 1 1 0 0] ]
Kimenet: -1
Magyarázat:
Láthatjuk, hogy ez lehetetlen
elérje a (03) cellát (22).
Tartalomjegyzék
- [Megközelítés] Visszalépés használata a látogatott mátrixszal
- [Optimalizált megközelítés] Extra hely használata nélkül
[Megközelítés] Visszalépés használata a látogatott mátrixszal
CPPAz ötlet az, hogy használjuk Visszalépés . A mátrix forráscellájából indulva haladunk előre mind a négy megengedett irányban, és rekurzív módon ellenőrizzük, hogy ezek a megoldáshoz vezetnek-e vagy sem. Ha a cél megtalálható, frissítjük a leghosszabb út értékét, ha pedig a fenti megoldások egyike sem működik, függvényünkből false értéket adunk vissza.
#include #include #include #include using namespace std; // Function to find the longest path using backtracking int dfs(vector<vector<int>> &mat vector<vector<bool>> &visited int i int j int x int y) { int m = mat.size(); int n = mat[0].size(); // If destination is reached if (i == x && j == y) { return 0; } // If cell is invalid blocked or already visited if (i < 0 || i >= m || j < 0 || j >= n || mat[i][j] == 0 || visited[i][j]) { return -1; } // Mark current cell as visited visited[i][j] = true; int maxPath = -1; // Four possible moves: up down left right int row[] = {-1 1 0 0}; int col[] = {0 0 -1 1}; for (int k = 0; k < 4; k++) { int ni = i + row[k]; int nj = j + col[k]; int pathLength = dfs(mat visited ni nj x y); // If a valid path is found from this direction if (pathLength != -1) { maxPath = max(maxPath 1 + pathLength); } } // Backtrack - unmark current cell visited[i][j] = false; return maxPath; } int findLongestPath(vector<vector<int>> &mat int xs int ys int xd int yd) { int m = mat.size(); int n = mat[0].size(); // Check if source or destination is blocked if (mat[xs][ys] == 0 || mat[xd][yd] == 0) { return -1; } vector<vector<bool>> visited(m vector<bool>(n false)); return dfs(mat visited xs ys xd yd); } int main() { vector<vector<int>> mat = { {1 1 1 1 1 1 1 1 1 1} {1 1 0 1 1 0 1 1 0 1} {1 1 1 1 1 1 1 1 1 1} }; int xs = 0 ys = 0; int xd = 1 yd = 7; int result = findLongestPath(mat xs ys xd yd); if (result != -1) cout << result << endl; else cout << -1 << endl; return 0; }
Java import java.util.Arrays; public class GFG { // Function to find the longest path using backtracking public static int dfs(int[][] mat boolean[][] visited int i int j int x int y) { int m = mat.length; int n = mat[0].length; // If destination is reached if (i == x && j == y) { return 0; } // If cell is invalid blocked or already visited if (i < 0 || i >= m || j < 0 || j >= n || mat[i][j] == 0 || visited[i][j]) { return -1; // Invalid path } // Mark current cell as visited visited[i][j] = true; int maxPath = -1; // Four possible moves: up down left right int[] row = {-1 1 0 0}; int[] col = {0 0 -1 1}; for (int k = 0; k < 4; k++) { int ni = i + row[k]; int nj = j + col[k]; int pathLength = dfs(mat visited ni nj x y); // If a valid path is found from this direction if (pathLength != -1) { maxPath = Math.max(maxPath 1 + pathLength); } } // Backtrack - unmark current cell visited[i][j] = false; return maxPath; } public static int findLongestPath(int[][] mat int xs int ys int xd int yd) { int m = mat.length; int n = mat[0].length; // Check if source or destination is blocked if (mat[xs][ys] == 0 || mat[xd][yd] == 0) { return -1; } boolean[][] visited = new boolean[m][n]; return dfs(mat visited xs ys xd yd); } public static void main(String[] args) { int[][] mat = { {1 1 1 1 1 1 1 1 1 1} {1 1 0 1 1 0 1 1 0 1} {1 1 1 1 1 1 1 1 1 1} }; int xs = 0 ys = 0; int xd = 1 yd = 7; int result = findLongestPath(mat xs ys xd yd); if (result != -1) System.out.println(result); else System.out.println(-1); } }
Python # Function to find the longest path using backtracking def dfs(mat visited i j x y): m = len(mat) n = len(mat[0]) # If destination is reached if i == x and j == y: return 0 # If cell is invalid blocked or already visited if i < 0 or i >= m or j < 0 or j >= n or mat[i][j] == 0 or visited[i][j]: return -1 # Invalid path # Mark current cell as visited visited[i][j] = True maxPath = -1 # Four possible moves: up down left right row = [-1 1 0 0] col = [0 0 -1 1] for k in range(4): ni = i + row[k] nj = j + col[k] pathLength = dfs(mat visited ni nj x y) # If a valid path is found from this direction if pathLength != -1: maxPath = max(maxPath 1 + pathLength) # Backtrack - unmark current cell visited[i][j] = False return maxPath def findLongestPath(mat xs ys xd yd): m = len(mat) n = len(mat[0]) # Check if source or destination is blocked if mat[xs][ys] == 0 or mat[xd][yd] == 0: return -1 visited = [[False for _ in range(n)] for _ in range(m)] return dfs(mat visited xs ys xd yd) def main(): mat = [ [1 1 1 1 1 1 1 1 1 1] [1 1 0 1 1 0 1 1 0 1] [1 1 1 1 1 1 1 1 1 1] ] xs ys = 0 0 xd yd = 1 7 result = findLongestPath(mat xs ys xd yd) if result != -1: print(result) else: print(-1) if __name__ == '__main__': main()
C# using System; class GFG { // Function to find the longest path using backtracking static int dfs(int[] mat bool[] visited int i int j int x int y) { int m = mat.GetLength(0); int n = mat.GetLength(1); // If destination is reached if (i == x && j == y) { return 0; } // If cell is invalid blocked or already visited if (i < 0 || i >= m || j < 0 || j >= n || mat[i j] == 0 || visited[i j]) { return -1; // Invalid path } // Mark current cell as visited visited[i j] = true; int maxPath = -1; // Four possible moves: up down left right int[] row = {-1 1 0 0}; int[] col = {0 0 -1 1}; for (int k = 0; k < 4; k++) { int ni = i + row[k]; int nj = j + col[k]; int pathLength = dfs(mat visited ni nj x y); // If a valid path is found from this direction if (pathLength != -1) { maxPath = Math.Max(maxPath 1 + pathLength); } } // Backtrack - unmark current cell visited[i j] = false; return maxPath; } static int FindLongestPath(int[] mat int xs int ys int xd int yd) { int m = mat.GetLength(0); int n = mat.GetLength(1); // Check if source or destination is blocked if (mat[xs ys] == 0 || mat[xd yd] == 0) { return -1; } bool[] visited = new bool[m n]; return dfs(mat visited xs ys xd yd); } static void Main() { int[] mat = { {1 1 1 1 1 1 1 1 1 1} {1 1 0 1 1 0 1 1 0 1} {1 1 1 1 1 1 1 1 1 1} }; int xs = 0 ys = 0; int xd = 1 yd = 7; int result = FindLongestPath(mat xs ys xd yd); if (result != -1) Console.WriteLine(result); else Console.WriteLine(-1); } }
JavaScript // Function to find the longest path using backtracking function dfs(mat visited i j x y) { const m = mat.length; const n = mat[0].length; // If destination is reached if (i === x && j === y) { return 0; } // If cell is invalid blocked or already visited if (i < 0 || i >= m || j < 0 || j >= n || mat[i][j] === 0 || visited[i][j]) { return -1; } // Mark current cell as visited visited[i][j] = true; let maxPath = -1; // Four possible moves: up down left right const row = [-1 1 0 0]; const col = [0 0 -1 1]; for (let k = 0; k < 4; k++) { const ni = i + row[k]; const nj = j + col[k]; const pathLength = dfs(mat visited ni nj x y); // If a valid path is found from this direction if (pathLength !== -1) { maxPath = Math.max(maxPath 1 + pathLength); } } // Backtrack - unmark current cell visited[i][j] = false; return maxPath; } function findLongestPath(mat xs ys xd yd) { const m = mat.length; const n = mat[0].length; // Check if source or destination is blocked if (mat[xs][ys] === 0 || mat[xd][yd] === 0) { return -1; } const visited = Array(m).fill().map(() => Array(n).fill(false)); return dfs(mat visited xs ys xd yd); } const mat = [ [1 1 1 1 1 1 1 1 1 1] [1 1 0 1 1 0 1 1 0 1] [1 1 1 1 1 1 1 1 1 1] ]; const xs = 0 ys = 0; const xd = 1 yd = 7; const result = findLongestPath(mat xs ys xd yd); if (result !== -1) console.log(result); else console.log(-1);
Kimenet
24
Időbeli összetettség: O(4^(m*n)) Az m x n mátrix minden egyes cellájára az algoritmus négy lehetséges irányt tár fel (balról jobbra fel le), ami exponenciális számú útvonalhoz vezet. A legrosszabb esetben minden lehetséges utat feltérképez, ami 4^(m*n) időbonyolultságot eredményez.
Kiegészítő tér: O(m*n) Az algoritmus egy m x n látogatott mátrixot használ a meglátogatott cellák nyomon követésére és egy rekurziós verem segítségével, amely a legrosszabb esetben m * n mélységig nőhet (pl. az összes cellát lefedő útvonal feltárásakor). Így a segédtér O(m*n).
[Optimalizált megközelítés] Extra hely használata nélkül
Külön látogatott mátrix fenntartása helyett megtehetjük használja újra a bemeneti mátrixot megjelölni a meglátogatott cellákat a bejárás során. Ez extra helyet takarít meg, és továbbra is biztosítja, hogy ne keressük fel újra ugyanazt a cellát az útvonalon.
Az alábbiakban bemutatjuk a lépésről lépésre történő megközelítést:
- Kezdje a forráscellától
(xs ys). - Minden lépésnél fedezze fel mind a négy lehetséges irányt (jobbra le balra fel).
- Minden érvényes lépésnél:
- Ellenőrizze a határokat, és győződjön meg arról, hogy a cellának van értéke
1(szabad cella). - Jelölje meg a cellát látogatottként úgy, hogy ideiglenesen erre állítja be
0. - Visszatérés a következő cellába, és növelje az útvonal hosszát.
- Ellenőrizze a határokat, és győződjön meg arról, hogy a cellának van értéke
- Ha a célcella
(xd yd)elérte, hasonlítsa össze az aktuális úthosszt az eddigi maximummal, és frissítse a választ. - Visszalépés: visszaállítja a cella eredeti értékét (
1), mielőtt visszatérne, hogy más utak is felfedezhessék azt. - Folytassa a felfedezést, amíg minden lehetséges utat meg nem látogat.
- Adja vissza a maximális útvonalhosszt. Ha a cél elérhetetlen, térjen vissza
-1
#include #include #include #include using namespace std; // Function to find the longest path using backtracking without extra space int dfs(vector<vector<int>> &mat int i int j int x int y) { int m = mat.size(); int n = mat[0].size(); // If destination is reached if (i == x && j == y) { return 0; } // If cell is invalid or blocked (0 means blocked or visited) if (i < 0 || i >= m || j < 0 || j >= n || mat[i][j] == 0) { return -1; } // Mark current cell as visited by temporarily setting it to 0 mat[i][j] = 0; int maxPath = -1; // Four possible moves: up down left right int row[] = {-1 1 0 0}; int col[] = {0 0 -1 1}; for (int k = 0; k < 4; k++) { int ni = i + row[k]; int nj = j + col[k]; int pathLength = dfs(mat ni nj x y); // If a valid path is found from this direction if (pathLength != -1) { maxPath = max(maxPath 1 + pathLength); } } // Backtrack - restore the cell's original value (1) mat[i][j] = 1; return maxPath; } int findLongestPath(vector<vector<int>> &mat int xs int ys int xd int yd) { int m = mat.size(); int n = mat[0].size(); // Check if source or destination is blocked if (mat[xs][ys] == 0 || mat[xd][yd] == 0) { return -1; } return dfs(mat xs ys xd yd); } int main() { vector<vector<int>> mat = { {1 1 1 1 1 1 1 1 1 1} {1 1 0 1 1 0 1 1 0 1} {1 1 1 1 1 1 1 1 1 1} }; int xs = 0 ys = 0; int xd = 1 yd = 7; int result = findLongestPath(mat xs ys xd yd); if (result != -1) cout << result << endl; else cout << -1 << endl; return 0; }
Java public class GFG { // Function to find the longest path using backtracking without extra space public static int dfs(int[][] mat int i int j int x int y) { int m = mat.length; int n = mat[0].length; // If destination is reached if (i == x && j == y) { return 0; } // If cell is invalid or blocked (0 means blocked or visited) if (i < 0 || i >= m || j < 0 || j >= n || mat[i][j] == 0) { return -1; } // Mark current cell as visited by temporarily setting it to 0 mat[i][j] = 0; int maxPath = -1; // Four possible moves: up down left right int[] row = {-1 1 0 0}; int[] col = {0 0 -1 1}; for (int k = 0; k < 4; k++) { int ni = i + row[k]; int nj = j + col[k]; int pathLength = dfs(mat ni nj x y); // If a valid path is found from this direction if (pathLength != -1) { maxPath = Math.max(maxPath 1 + pathLength); } } // Backtrack - restore the cell's original value (1) mat[i][j] = 1; return maxPath; } public static int findLongestPath(int[][] mat int xs int ys int xd int yd) { int m = mat.length; int n = mat[0].length; // Check if source or destination is blocked if (mat[xs][ys] == 0 || mat[xd][yd] == 0) { return -1; } return dfs(mat xs ys xd yd); } public static void main(String[] args) { int[][] mat = { {1 1 1 1 1 1 1 1 1 1} {1 1 0 1 1 0 1 1 0 1} {1 1 1 1 1 1 1 1 1 1} }; int xs = 0 ys = 0; int xd = 1 yd = 7; int result = findLongestPath(mat xs ys xd yd); if (result != -1) System.out.println(result); else System.out.println(-1); } }
Python # Function to find the longest path using backtracking without extra space def dfs(mat i j x y): m = len(mat) n = len(mat[0]) # If destination is reached if i == x and j == y: return 0 # If cell is invalid or blocked (0 means blocked or visited) if i < 0 or i >= m or j < 0 or j >= n or mat[i][j] == 0: return -1 # Mark current cell as visited by temporarily setting it to 0 mat[i][j] = 0 maxPath = -1 # Four possible moves: up down left right row = [-1 1 0 0] col = [0 0 -1 1] for k in range(4): ni = i + row[k] nj = j + col[k] pathLength = dfs(mat ni nj x y) # If a valid path is found from this direction if pathLength != -1: maxPath = max(maxPath 1 + pathLength) # Backtrack - restore the cell's original value (1) mat[i][j] = 1 return maxPath def findLongestPath(mat xs ys xd yd): m = len(mat) n = len(mat[0]) # Check if source or destination is blocked if mat[xs][ys] == 0 or mat[xd][yd] == 0: return -1 return dfs(mat xs ys xd yd) def main(): mat = [ [1 1 1 1 1 1 1 1 1 1] [1 1 0 1 1 0 1 1 0 1] [1 1 1 1 1 1 1 1 1 1] ] xs ys = 0 0 xd yd = 1 7 result = findLongestPath(mat xs ys xd yd) if result != -1: print(result) else: print(-1) if __name__ == '__main__': main()
C# using System; class GFG { // Function to find the longest path using backtracking without extra space static int dfs(int[] mat int i int j int x int y) { int m = mat.GetLength(0); int n = mat.GetLength(1); // If destination is reached if (i == x && j == y) { return 0; } // If cell is invalid or blocked (0 means blocked or visited) if (i < 0 || i >= m || j < 0 || j >= n || mat[i j] == 0) { return -1; } // Mark current cell as visited by temporarily setting it to 0 mat[i j] = 0; int maxPath = -1; // Four possible moves: up down left right int[] row = {-1 1 0 0}; int[] col = {0 0 -1 1}; for (int k = 0; k < 4; k++) { int ni = i + row[k]; int nj = j + col[k]; int pathLength = dfs(mat ni nj x y); // If a valid path is found from this direction if (pathLength != -1) { maxPath = Math.Max(maxPath 1 + pathLength); } } // Backtrack - restore the cell's original value (1) mat[i j] = 1; return maxPath; } static int FindLongestPath(int[] mat int xs int ys int xd int yd) { // Check if source or destination is blocked if (mat[xs ys] == 0 || mat[xd yd] == 0) { return -1; } return dfs(mat xs ys xd yd); } static void Main() { int[] mat = { {1 1 1 1 1 1 1 1 1 1} {1 1 0 1 1 0 1 1 0 1} {1 1 1 1 1 1 1 1 1 1} }; int xs = 0 ys = 0; int xd = 1 yd = 7; int result = FindLongestPath(mat xs ys xd yd); if (result != -1) Console.WriteLine(result); else Console.WriteLine(-1); } }
JavaScript // Function to find the longest path using backtracking without extra space function dfs(mat i j x y) { const m = mat.length; const n = mat[0].length; // If destination is reached if (i === x && j === y) { return 0; } // If cell is invalid or blocked (0 means blocked or visited) if (i < 0 || i >= m || j < 0 || j >= n || mat[i][j] === 0) { return -1; } // Mark current cell as visited by temporarily setting it to 0 mat[i][j] = 0; let maxPath = -1; // Four possible moves: up down left right const row = [-1 1 0 0]; const col = [0 0 -1 1]; for (let k = 0; k < 4; k++) { const ni = i + row[k]; const nj = j + col[k]; const pathLength = dfs(mat ni nj x y); // If a valid path is found from this direction if (pathLength !== -1) { maxPath = Math.max(maxPath 1 + pathLength); } } // Backtrack - restore the cell's original value (1) mat[i][j] = 1; return maxPath; } function findLongestPath(mat xs ys xd yd) { const m = mat.length; const n = mat[0].length; // Check if source or destination is blocked if (mat[xs][ys] === 0 || mat[xd][yd] === 0) { return -1; } return dfs(mat xs ys xd yd); } const mat = [ [1 1 1 1 1 1 1 1 1 1] [1 1 0 1 1 0 1 1 0 1] [1 1 1 1 1 1 1 1 1 1] ]; const xs = 0 ys = 0; const xd = 1 yd = 7; const result = findLongestPath(mat xs ys xd yd); if (result !== -1) console.log(result); else console.log(-1);
Kimenet
24
Időbeli összetettség: O(4^(m*n))Az algoritmus cellánként legfeljebb négy irányt vizsgál az m x n mátrixban, ami exponenciális számú utat eredményez. A helyben történő módosítás nem befolyásolja a feltárt utak számát, így az időbonyolultság 4^(m*n) marad.
Kiegészítő tér: O(m*n) Míg a meglátogatott mátrix a bemeneti mátrix helyben történő módosításával megszűnik, a rekurziós verem továbbra is O(m*n) helyet igényel, mivel a maximális rekurziós mélység a legrosszabb esetben m * n lehet (pl. egy olyan útvonal, amely a rács összes celláját meglátogatja, többnyire 1 másodperccel).