Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 在时间复杂度方面,有多少种方法可以从字符矩阵中以最佳方式形成字符串?_Algorithm_Data Structures_Time Complexity_Boggle - Fatal编程技术网

Algorithm 在时间复杂度方面,有多少种方法可以从字符矩阵中以最佳方式形成字符串?

Algorithm 在时间复杂度方面,有多少种方法可以从字符矩阵中以最佳方式形成字符串?,algorithm,data-structures,time-complexity,boggle,Algorithm,Data Structures,Time Complexity,Boggle,(更新) 我们需要找到从字符矩阵中形成给定字符串的方法的数量 我们可以从矩阵中的任何位置(i,j)开始构词,也可以从矩阵中每个单元格(i,j)的8个方向出发,在任何未访问的方向上构词,即 (i + 1, j) (i + 1, j + 1) (i + 1, j - 1) (i - 1, j) (i - 1, j + 1) (i - 1, j - 1) (i, j + 1) (i, j - 1) 样本测试用例: 说明: 使“适合”的方法数量如下所示: (0,0)(0,1)(0,2) (2,1)(2

(更新)

我们需要找到从字符矩阵中形成给定字符串的方法的数量

我们可以从矩阵中的任何位置(i,j)开始构词,也可以从矩阵中每个单元格(i,j)的8个方向出发,在任何未访问的方向上构词,即

(i + 1, j)
(i + 1, j + 1)
(i + 1, j - 1)
(i - 1, j)
(i - 1, j + 1)
(i - 1, j - 1)
(i, j + 1)
(i, j - 1)
样本测试用例:

说明:

使“适合”的方法数量如下所示:

(0,0)(0,1)(0,2)
(2,1)(2,0)(3,0)
(2,3)(1,3)(0,4)
(3,1)(2,0)(3,0)
(2,3)(3,4)(3,5)
(2,7)(3,6)(3,5) 
(2,3)(1,3)(0,2)
我以一种简单的方式处理解决方案,找到矩阵中每个可能的位置(I,j),通过对矩阵执行DFS搜索,开始从该单元格(I,j)生成字符串,并将从该位置(I,j)生成给定字符串的方法数添加到total_num_ways变量中

伪代码:

但事实证明,这个解决方案的时间复杂度是指数级的,因为我们要到每个可能的n*m位置,然后遍历到每个可能的k(字符串长度)长度路径以形成字符串。

我们如何提高解决方案的效率

#检查给定的(x,y)坐标是否在边界内
#矩阵的
定义单位界限(x、y、行、列):
返回x>=0和x=0和y
不是从矩阵的每个坐标展开路径,而是首先迭代矩阵,以找到与目标字符串中的第一个字母具有相同字母的所有(i,j)坐标。这需要O(n^2)个时间

然后,对于找到的包含目标字符串中第一个字母的每个(i,j)坐标,通过搜索目标字符串中的第二个字母展开路径,并仅展开与第二个字母匹配的路径。对目标字符串中的每个字母重复此操作,以递归方式从起始坐标查找所有有效路径。

建议-1:预处理矩阵和输入字符串 我们只关心矩阵的一个单元格,如果该单元格中的字符出现在输入字符串的任何位置。因此,如果输入字符串为“fit”,则我们不关心包含字母“z”的单元格

利用这一点,下面是一个建议

  • 获取输入字符串,首先将其字符放入一个集合S中。这是一个O(k)步,其中k是字符串的长度
  • 接下来,我们迭代矩阵(O(m*n)步),并:
  • 如果单元格中的字符没有出现在S中,我们将继续下一个字符
  • 如果单元格中的字符出现,我们将在名为M的>映射中添加单元格位置条目
  • 现在,对输入(不是矩阵)进行迭代,对于当前字符c出现的每个位置,得到当前单元格的右、左、上、下的未访问位置
  • 如果这些位置中的任何一个出现在矩阵中下一个字符所在的M单元格列表中,则:
  • 递归地转到输入字符串的下一个字符,直到用尽所有字符
  • 在这个解决方案中什么更好?我们得到了需要在O(1)中探索的下一个单元,因为它已经存在于地图中。因此,复杂性不再是指数级的,而是O(c),其中c是矩阵中输入字符串的总出现次数


    建议2:动态规划 DP在存在最优子结构和重叠子问题的情况下提供帮助。因此,在同一子字符串是多个解决方案的一部分的情况下,使用DP可能会有所帮助

    例:如果我们在某个地方找到了“fit”,那么如果相邻单元中有一个“f”,它就可以使用subs
    (0,0)(0,1)(0,2)
    (2,1)(2,0)(3,0)
    (2,3)(1,3)(0,4)
    (3,1)(2,0)(3,0)
    (2,3)(3,4)(3,5)
    (2,7)(3,6)(3,5) 
    (2,3)(1,3)(0,2)
    
    W = 0
    for i : 0 - n:
       for j: 0 - m:
            visited[n][m] = {false}
            W += DFS(i, j, 0, str, matrix, visited);
    
    # Checking if the given (x,y) coordinates are within the boundaries
    # of the matrix
    def in_bounds(x, y, rows, cols):
        return x >= 0 and x < rows and y >= 0 and y < cols
    
    # Finding all possible moves from the current (x,y) position
    def possible_moves(position, path_set, rows, cols):
        moves = []
        move_range = [-1,0,1]
        for i in range(len(move_range)):
            for j in range(len(move_range)):
                x = position[0] + move_range[i]
                y = position[1] + move_range[j]
                if in_bounds(x,y,rows,cols):
                    if x in path_set:
                        if y in path_set[x]:
                            continue
                    moves.append((x,y))
        return moves
    
    # Deterimine which of the possible moves lead to the next letter 
    # of the goal string
    def check_moves(goal_letter, candidates, search_space):
        moves = []
        for x, y in candidates:
            if search_space[x][y] == goal_letter:
                moves.append((x,y))
        return moves
    
    # Recursively expanding the paths of each starting coordinate
    def search(goal, path, search_space, path_set, rows, cols):
        # Base Case
        if goal == '':
            return [path]
        x = path[-1][0]
        y = path[-1][1]
        if x in path_set:
            path_set[x].add(y)
        else:
            path_set.update([(x,set([y]))])
    
        results = []
        moves = possible_moves(path[-1],path_set,rows,cols)
        moves = check_moves(goal[0],moves,search_space)
    
        for move in moves:
            result = search(goal[1:], path + [move], search_space, path_set, rows, cols)
            if result is not None:
                results += result
        return results
    
    # Finding the coordinates in the matrix where the first letter from the goal
    # string appears which is where all potential paths will begin from.
    def find_paths(goal, search_space):
        results = []
        rows, cols = len(search_space), len(search_space[0])
        # Finding starting coordinates for candidate paths
        for i in range(len(search_space)):
            for j in range(len(search_space[i])):
                if search_space[i][j] == goal[0]:
                    # Expanding path from root letter
                    results += search(goal[1:],[(i,j)],search_space,dict(),rows,cols)
        return results
    
    goal = "fit"
    matrix = [
            'fitptoke',
            'orliguek',
            'ifefunef',
            'tforitis'
            ]
    
    paths = find_paths(goal, matrix)
    for path in paths:
        print(path)
    print('# of paths:',len(paths))