dfs intuition - backtracking with hashtable

this returns time limit, because

class Solution:
    def exist(self, board: List[List[str]], word: str) -> bool:
        rows = len(board)
        cols = len(board[0])
        visited = set()
    
        def dfs(row, col, word_idx=0):
            # if word_idx is equal to the length of word
            # we could assume that we find the complete word
            if word_idx == len(word):
                return True

            # if borders is passed
            # row is lower than 0 or col is lower than 0
            # or if row > len(rows) or if cols > len(cols) this will index overflow, so this is not ok
            if row < 0 or col < 0 or row >= rows or col >= cols:
                return False

            if word[word_idx] != board[row][col]:
                return False
            
            if ((row,col) in visited):
                return False

            visited.add((row,col))

            # we should choice the path that contains the right letter
            # so we need to check up ^ (row - 1, 0, word_idx + 1)
            # so we need to check down (row + 1, 0, word_idx + 1)
            # so we need to check right -> (row, col + 1, word_idx + 1)
            # so we need to check left <- (row, col - 1, word_idx + 1)
            found = (
                dfs(row - 1, col, word_idx + 1) or
                dfs(row + 1, col, word_idx + 1) or
                dfs(row, col + 1, word_idx + 1) or
                dfs(row, col - 1, word_idx + 1)
            )

            visited.remove((row,col))

            # if find return the result of the paths
            return found

        for row in range(rows):
            for col in range(cols):
                if dfs(row,col):
                    return True
        
        return False
        
        #["A","B","C","E"]
        #["S","F","E","S"]
        #["A","D","E","E"]

        #ABCB

        #["C","A","A"]
        #["A","A","A"]
        #["B","C","D"]

        #AAB

        #["A","B","C","E"]
        #["S","F","E","S"]
        #["A","D","E","E"]

        # ABCESEEEFS

this returns time limit, under the hood this is hashmap

set()

this check cost o(1), because (row, col) is the key of hash

if ((row,col) in visited):
                return False

this addition cost o(1) to be added, but o(N) when the hash should be resized

visited.add((row,col))

this remove cost(1) too,

visited.remove((row,col))