This article is meant for For BEGINNERS who get confused while applying DFS on 2d Matrix and where to apply the base conditions. SInce there are various versions of DFS being used on leetcode let me break down these versions .
DFS(){
//Base Case
if boundary of Matrix is crossed
return
Process the current coordinate
//Recursive calls for Neighbours
DFS( right );
DFS( down );
DFS( left );
DFS( up );
} DFS(){
Process the current coordinate
Base Case for going right
DFS( right );
Base Case for going down
DFS( down );
Base Case for going left
DFS( left );
Base Case for going up
DFS( up );
} So people got tired of variation 2 as no one wants to write several base cases and recursive calls again and again
In some problems regarding 2d matrix we can move in all 8 directions which led to 8 recursive calls
So people came up with a direction vector approach to move in all directions
int dir[4][2]={{0,1},{1,0},{-1,0},{0,-1}};
By practice you can directly write the direction vector intuitively too but for beginners its important to understand why are we doing this.

You can further extend this concept for all neighbours too
int dir[4][2]={{0,1},{1,0},{-1,0},{0,-1}}
DFS(){
Process the current Coordinate
for(int i=0;i<4;i++){
//nx and ny are just the neighbours coordinates
int nx = dir[i][0]+current_x_coordinate
int ny = dir[i][1]+current y coordinate
BaseCase check on nx and ny we just calculated
DFS(nx, ny )
}
} Lets Solve the problem 200. Number of Islands with all these variations for a better understanding
class Solution {
public:
void dfs(vector<vector<char>>& grid, int i, int j) {
if (i < 0 || j < 0 || i >= grid.size() || j >= grid[0].size() ||
grid[i][j] != '1')
return;
grid[i][j] = '2';
dfs(grid, i + 1, j);
dfs(grid, i - 1, j);
dfs(grid, i, j + 1);
dfs(grid, i, j - 1);
}
int numIslands(vector<vector<char>>& grid) {
int m = grid.size();
int n = grid[0].size();
int count = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (grid[i][j] == '1') {
dfs(grid, i, j);
count++;
}
}
}
return count;
}
};class Solution {
public:
void dfs(int i,int j,vector<vector<char>>& grid){
grid[i][j]=0;
int n=grid.size();
int m=grid[0].size();
if(i-1 >= 0 && grid[i-1][j] == '1')
dfs(i-1,j,grid);
if(i+1 < n && grid[i+1][j] == '1')
dfs(i+1,j,grid);
if(j-1 >= 0 && grid[i][j-1] == '1')
dfs(i,j-1,grid);
if(j+1 < m && grid[i][j+1] == '1')
dfs(i,j+1,grid);
}
int numIslands(vector<vector<char>>& grid) {
int n=grid.size();
int m=grid[0].size();
int ans=0;
for(int i=0 ; i<n ; i++){
for(int j=0 ; j<m ; j++){
if(grid[i][j] == '1'){
ans++;
dfs(i,j,grid);
}
}
}
return ans;
}
};class Solution {
public:
int dirs[4][2] = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}};
void dfs(vector<vector<char>>& grid, int r, int c) {
grid[r][c] = '0';
for (int k = 0; k < 4; k++) {
int rowdash = r + dirs[k][0];
int coldash = c + dirs[k][1];
if (rowdash >= 0 && coldash >= 0 && rowdash < grid.size() &&
coldash < grid[0].size() && grid[rowdash][coldash] == '1')
dfs(grid, rowdash, coldash);
}
}
int numIslands(vector<vector<char>>& grid) {
int count = 0;
for (int i = 0; i < grid.size(); i++) {
for (int j = 0; j < grid[0].size(); j++) {
if (grid[i][j] == '1') {
dfs(grid, i, j);
count++;
}
}
}
return count;
}
};