简体   繁体   中英

How to use a shared variable during Recursion in Python

I am implementing a backtracking based recursive solution and want to update the variable min_path based on the conditions. If I define the variable outside the recursive function, I get a reference error, what would be the best way to implement such a solution

class Solution:
def minPathSum(self, grid: List[List[int]]) -> int:
    if not grid:
        return


    R = len(grid)
    C = len(grid[0])
    min_path = None

    def backtrack(grid, i, j, current_path):

        if i >= R or j>= C:
            return
        current_path += grid[i][j]
        if i == R-1 and j == C-1:
            if not min_path:
                min_path = current_path
            else:
                min_path = min(min_path, current_path)
            print(min_path)
            return
        backtrack(grid, i, j+1, current_path)
        backtrack(grid, i+1, j, current_path)

    backtrack(grid, 0, 0,0)

    return min_path

For reference, this is the question I am trying to solve: https://leetcode.com/problems/minimum-path-sum/

Your variable min_path is scoped to the main method and isn't available to functions that are members of your class object. In order to reference it inside the backtrack method, you'll either need to

  1. Define min_path as a local variable in the backtrack method (which could cause additional issues since you're calling it recursively):
class Solution:
def minPathSum(self, grid: List[List[int]]) -> int:
    if not grid:
        return

    R = len(grid)
    C = len(grid)
    min_path_main = None

    min_path_main = backtrack(grid, 0, 0,0)

    return min_path_main

  def backtrack(grid, i, j, current_path):
    min_path = None
    if i >= R or j>= C:
        break
      current_path += grid[i][j]
      if i == R-1 and j == C-1:
        if not min_path:
            min_path = current_path
        else:
            min_path = min(min_path, current_path)
            print(min_path)
            break
    # it's possible you'll need extra logic here to manage the output. 
    output1 = backtrack(grid, i, j+1, current_path)
    output2 = backtrack(grid, i+1, j, current_path)

  return min_path
  1. Define the variable as a class variable:
class Solution:
def __init__(self):
  self.min_path = None

def minPathSum(self, grid: List[List[int]]) -> int:
    if not grid:
        return

    R = len(grid)
    C = len(grid)

    backtrack(grid, 0, 0,0)

    return self.min_path

def backtrack(grid, i, j, current_path):
    if i >= R or j>= C:
        break
      current_path += grid[i][j]
      if i == R-1 and j == C-1:
        if not self.min_path:
            self.min_path = current_path
        else:
            self.min_path = min(self.min_path, current_path)
            print(self.min_path)
            break
    backtrack(grid, i, j+1, current_path)
    backtrack(grid, i+1, j, current_path)

  return

May have to play around with it a little. I don't have input data, so I didn't run the code. But those are the ways you would implement the solutions I've offered.

Since the goal is to simply find the minimum sum, there is no need to keep track of the coordinates of the path. You can instead make recursive calls with what's left of the grid from the perspective of the step you're taking:

def min_sum(g):
    if not g or not g[0]:
        return float('inf')
    return g[0][0] + ((len(g) > 1 or len(g[0]) > 1) and min(map(min_sum, (g[1:], [*zip(*g)][1:]))))

so that:

min_sum([
  [1,3,1],
  [1,5,1],
  [4,2,1]
])

returns: 7

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM