Skip to content

Commit 5822928

Browse files
committed
Update all solutions' changes in 2025-05-05.
1 parent ddd42d1 commit 5822928

File tree

2 files changed

+543
-0
lines changed

2 files changed

+543
-0
lines changed

en/1-1000/797-all-paths-from-source-to-target.md

Lines changed: 271 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,19 @@ Recursion is an important concept in computer science and mathematics, which ref
354354
- **Base case**: Equivalent to the termination condition. After reaching the base case, the result can be returned without recursive calls to prevent infinite loops.
355355
- **Recursive step**: The step by which the problem gradually approaches the "base case".
356356

357+
## Step by Step Solutions
358+
359+
1. Initialize an empty list `paths` to store all the valid paths found from source to target.
360+
2. Define a recursive Depth-First Search (DFS) function, say `dfs`, that takes the current `node` and the `currentPath` (a list of nodes visited so far to reach the current node) as input.
361+
3. Inside the `dfs` function:
362+
a. Create a new path list by appending the current `node` to the `currentPath`. Let's call this `newPath`.
363+
b. Check if the current `node` is the target node (`n - 1`, where `n` is the total number of nodes).
364+
i. If it is the target node, it means we've found a complete path. Add `newPath` to the main `paths` list and return from this recursive call.
365+
c. If the current `node` is not the target node, iterate through all `neighbor` nodes accessible from the current `node` (i.e., iterate through `graph[node]`).
366+
i. For each `neighbor`, make a recursive call to `dfs` with the `neighbor` as the new current node and `newPath` as the path taken to reach it (`dfs(neighbor, newPath)`).
367+
4. Start the process by calling the `dfs` function with the source node `0` and an empty initial path (`dfs(0, [])`).
368+
5. After the initial `dfs` call completes, return the `paths` list containing all discovered paths.
369+
357370
## Complexity
358371

359372
- Time complexity: `Too complex`.
@@ -586,6 +599,264 @@ end
586599
// Welcome to create a PR to complete the code of this language, thanks!
587600
```
588601

602+
## Intuition 3
603+
604+
605+
606+
## Pattern of "Depth-First Search"
607+
608+
**Depth-First Search (DFS)** is a classic graph traversal algorithm characterized by its **"go as deep as possible"** approach when exploring branches of a graph. Starting from the initial vertex, DFS follows a single path as far as possible until it reaches a vertex with no unvisited adjacent nodes, then backtracks to the nearest branching point to continue exploration. This process is implemented using **recursion** or an **explicit stack (iterative method)**, resulting in a **Last-In-First-Out (LIFO)** search order. As a result, DFS can quickly reach deep-level nodes far from the starting point in unweighted graphs.
609+
610+
**Comparison with BFS**:
611+
612+
1. **Search Order**: DFS prioritizes depth-wise exploration, while Breadth-First Search (BFS) expands layer by layer, following a **First-In-First-Out (FIFO)** queue structure.
613+
2. **Use Cases**: DFS is better suited for strongly connected components or backtracking problems (e.g., finding all paths in a maze), whereas BFS excels at finding the shortest path (in unweighted graphs) or exploring neighboring nodes (e.g., friend recommendations in social networks).
614+
615+
**Unique Aspects of DFS**:
616+
617+
- **Incompleteness**: If the graph is infinitely deep or contains cycles (without visited markers), DFS may fail to terminate, whereas BFS always finds the shortest path (in unweighted graphs).
618+
- **"One-path deep-dive"** search style makes it more flexible for backtracking, pruning, or path recording, but it may also miss near-optimal solutions.
619+
620+
In summary, DFS reveals the vertical structure of a graph through its depth-first strategy. Its inherent backtracking mechanism, combined with the natural use of a stack, makes it highly effective for path recording and state-space exploration. However, precautions must be taken to handle cycles and the potential absence of optimal solutions.
621+
622+
## Step by Step Solutions
623+
624+
1. Initialize an empty list `paths` to store all valid paths found from the source to the target.
625+
2. Create a mutable list `path` to track the current path being explored, initially containing only the source node `0`.
626+
3. Implement a recursive DFS function that explores paths using backtracking:
627+
- Base case: If the current node is the target node (`n-1`), make a copy of the current path and add it to the `paths` list.
628+
- Recursive step: For each neighbor of the current node:
629+
- Add the neighbor to the current path.
630+
- Recursively call the DFS function with this neighbor.
631+
- After the recursive call returns, remove the neighbor from the path (backtrack).
632+
4. Start the DFS from the source node `0`.
633+
5. Return the collected `paths` after the DFS completes.
634+
635+
## Complexity
636+
637+
- Time complexity: `Too complex`.
638+
- Space complexity: `Too complex`.
639+
640+
## Python
641+
642+
```python
643+
class Solution:
644+
def allPathsSourceTarget(self, graph: List[List[int]]) -> List[List[int]]:
645+
self.paths = []
646+
self.graph = graph
647+
self.path = [0] # Important
648+
649+
self.dfs(0)
650+
651+
return self.paths
652+
653+
def dfs(self, node):
654+
if node == len(self.graph) - 1:
655+
self.paths.append(self.path.copy()) # Important
656+
return
657+
658+
for neighbor in self.graph[node]:
659+
self.path.append(neighbor) # Important
660+
self.dfs(neighbor)
661+
self.path.pop() # Important
662+
663+
```
664+
665+
## Java
666+
667+
```java
668+
class Solution {
669+
private List<List<Integer>> paths = new ArrayList<>();
670+
private List<Integer> path = new ArrayList<>(List.of(0)); // Important - start with node 0
671+
private int[][] graph;
672+
673+
public List<List<Integer>> allPathsSourceTarget(int[][] graph) {
674+
this.graph = graph;
675+
676+
dfs(0);
677+
678+
return paths;
679+
}
680+
681+
private void dfs(int node) {
682+
if (node == graph.length - 1) { // Base case
683+
paths.add(new ArrayList<>(path)); // Important - make a copy
684+
return;
685+
}
686+
687+
for (int neighbor : graph[node]) { // Recursive step
688+
path.add(neighbor); // Important
689+
dfs(neighbor);
690+
path.remove(path.size() - 1); // Important - backtrack
691+
}
692+
}
693+
}
694+
```
695+
696+
## C++
697+
698+
```cpp
699+
class Solution {
700+
public:
701+
vector<vector<int>> allPathsSourceTarget(vector<vector<int>>& graph) {
702+
_graph = graph;
703+
_path = {0}; // Important - start with node 0
704+
705+
dfs(0);
706+
707+
return _paths;
708+
}
709+
710+
private:
711+
vector<vector<int>> _paths;
712+
vector<vector<int>> _graph;
713+
vector<int> _path;
714+
715+
void dfs(int node) {
716+
if (node == _graph.size() - 1) { // Base case
717+
_paths.push_back(_path); // Important - copy is made automatically
718+
return;
719+
}
720+
721+
for (int neighbor : _graph[node]) { // Recursive step
722+
_path.push_back(neighbor); // Important
723+
dfs(neighbor);
724+
_path.pop_back(); // Important - backtrack
725+
}
726+
}
727+
};
728+
729+
```
730+
731+
## JavaScript
732+
733+
```javascript
734+
/**
735+
* @param {number[][]} graph
736+
* @return {number[][]}
737+
*/
738+
var allPathsSourceTarget = function(graph) {
739+
const paths = [];
740+
const path = [0]; // Important - start with node 0
741+
742+
function dfs(node) {
743+
if (node === graph.length - 1) { // Base case
744+
paths.push([...path]); // Important - make a copy
745+
return;
746+
}
747+
748+
for (const neighbor of graph[node]) { // Recursive step
749+
path.push(neighbor); // Important
750+
dfs(neighbor);
751+
path.pop(); // Important - backtrack
752+
}
753+
}
754+
755+
dfs(0);
756+
757+
return paths;
758+
};
759+
```
760+
761+
## C#
762+
763+
```csharp
764+
public class Solution
765+
{
766+
private IList<IList<int>> paths = new List<IList<int>>();
767+
private List<int> path = new List<int> { 0 }; // Important - start with node 0
768+
private int[][] graph;
769+
770+
public IList<IList<int>> AllPathsSourceTarget(int[][] graph)
771+
{
772+
this.graph = graph;
773+
774+
Dfs(0);
775+
776+
return paths;
777+
}
778+
779+
private void Dfs(int node)
780+
{
781+
if (node == graph.Length - 1)
782+
{ // Base case
783+
paths.Add(new List<int>(path)); // Important - make a copy
784+
return;
785+
}
786+
787+
foreach (int neighbor in graph[node])
788+
{ // Recursive step
789+
path.Add(neighbor); // Important
790+
Dfs(neighbor);
791+
path.RemoveAt(path.Count - 1); // Important - backtrack
792+
}
793+
}
794+
}
795+
```
796+
797+
## Go
798+
799+
```go
800+
func allPathsSourceTarget(graph [][]int) [][]int {
801+
paths := [][]int{}
802+
path := []int{0} // Important - start with node 0
803+
804+
var dfs func(int)
805+
dfs = func(node int) {
806+
if node == len(graph) - 1 { // Base case
807+
// Important - make a deep copy of the path
808+
paths = append(paths, append([]int(nil), path...))
809+
return
810+
}
811+
812+
for _, neighbor := range graph[node] { // Recursive step
813+
path = append(path, neighbor) // Important
814+
dfs(neighbor)
815+
path = path[:len(path) - 1] // Important - backtrack
816+
}
817+
}
818+
819+
dfs(0)
820+
821+
return paths
822+
}
823+
```
824+
825+
## Ruby
826+
827+
```ruby
828+
# @param {Integer[][]} graph
829+
# @return {Integer[][]}
830+
def all_paths_source_target(graph)
831+
@paths = []
832+
@graph = graph
833+
@path = [0] # Important - start with node 0
834+
835+
dfs(0)
836+
837+
@paths
838+
end
839+
840+
def dfs(node)
841+
if node == @graph.length - 1 # Base case
842+
@paths << @path.clone # Important - make a copy
843+
return
844+
end
845+
846+
@graph[node].each do |neighbor| # Recursive step
847+
@path << neighbor # Important
848+
dfs(neighbor)
849+
@path.pop # Important - backtrack
850+
end
851+
end
852+
```
853+
854+
## Other languages
855+
856+
```java
857+
// Welcome to create a PR to complete the code of this language, thanks!
858+
```
859+
589860
Dear LeetCoders! For a better LeetCode problem-solving experience, please visit website [LeetCodePython.com](https://leetcodepython.com): Dare to claim the best practices of LeetCode solutions! Will save you a lot of time!
590861

591862
Original link: [797. All Paths From Source to Target - LeetCode Python/Java/C++/JS code](https://leetcodepython.com/en/leetcode/797-all-paths-from-source-to-target).

0 commit comments

Comments
 (0)