岛周长算法太慢

时间:2017-05-25 05:42:12

标签: python algorithm

我正在处理来自LeetCode的岛屿周边问题,虽然我有一个可行的解决方案,但它只通过5817/5833测试用例。我认为这是成功的,但显然它没有足够的效率来处理非常大的岛屿#34;如果我不知道什么'它会唠叨我。导致性能问题。对于那些不熟悉岛屿周边的人来说,#34;问题,这里是LeetCode页面的链接。

Island Perimeter Problem

我一直在解决Python中的问题,让我自己熟悉这种语言,并希望自己教一些新的技巧,所以这可能只是我做得不够有效,有人可以帮助我做得更好。任何人都可以在效率方面看到下面算法的任何明显问题吗?

def islandPerimeter(self, grid):
    """
    :type grid: List[List[int]]
    :rtype: int
    """
    start = self.locateIsland(grid)
    return self.islandHelp(grid, start)

def islandHelp(self, grid, start):
    # get the perimeter of this position
    p = self.getPerimeter(grid, start)
    # mark this position as visited so we don't count it repeatedly
    grid[start[0]][start[1]] = 2
    # offsets to current positions to find land to the sides
    sides = [[-1, 0], [0, 1], [1, 0], [0, -1]]
    for side in sides:
        newPos = [(start[0] + side[0]), (start[1] + side[1])]
        if ((newPos[0] in range(len(grid))) and
        (newPos[1] in range(len(grid[newPos[0]]))) and
        (grid[newPos[0]][newPos[1]] == 1)):
               # recursively find perimeter of connected land
               p += self.islandHelp(grid, newPos)
    return p

def getPerimeter(self, grid, pos):
    p = 0
    # offsets to find the neighboring positions
    sides = [[-1, 0], [0, 1], [1, 0], [0, -1]]
    for side in sides:
        if (((pos[0] + side[0]) in range(len(grid))) and
            ((pos[1] + side[1]) in range(len(grid[pos[0] + side[0]])))):
            if (grid[pos[0] + side[0]][pos[1] + side[1]] == 0):
                # in bounds of grid, but not a land mass, add to perimeter
                p += 1
        else:
            # out of bounds means edge of grid, add to perimeter
            p += 1
    return p

def locateIsland(self, grid):
    # iterate through the grid to find a 1 and use that as start position
    for r in range(len(grid)):
        for c in range(len(grid[r])):
            if (grid[r][c] == 1):
                return (r, c)
    return (-1, -1)

2 个答案:

答案 0 :(得分:1)

当你做这样的检查时:

(pos[0] + side[0]) in range(len(grid))

以下事情正在发生:

  • Python创建一个包含整数[0,1,2,3,...]
  • 的大小为len(grid)的列表
  • Python获取您的数字(在本例中为pos [0] + side [0]),并且为列表中的每个整数,将其与该整数进行比较以查看它是否相同

如果您只想知道数字是否小于网格的长度,那么效率不高!您可以用

替换该行

(pos[0] + side[0]) >= 0 and (pos[0] + side[0]) < len(grid)

在更短的时间内获得相同的效果。我做了这个改变,并检查它完成后它通过所有情况。

答案 1 :(得分:0)

我尝试了以下解决方案:

class Solution:
    def islandPerimeter(self, grid: List[List[int]]) -> int:
        
        # Find no of rows in grid
        row = len(grid) 
    
    # Initialize perimeter
    perimeter = 0
    
    # Check if grid is empty
    if (row == 0):
        return perimeter
    
    # Find no. of columns
    col = len(grid[0])
    
    
    # Loop through the matrix
    for i in range(row):
        for j in range(col):
            if(grid[i][j]==1):
                perimeter += self.getSideCount(grid,i+1,j,row,col) # Bottom Node
                perimeter += self.getSideCount(grid,i-1,j,row,col) # Top Node
                perimeter += self.getSideCount(grid,i,j+1,row,col) # Right Node
                perimeter += self.getSideCount(grid,i,j-1,row,col) # Left Node
    
    return perimeter


def getSideCount(self, grid: List[List[int]], i: int, j:int, row:int, col:int) -> int:
    # Check border conditions and if 
    if i<0 or j<0 or j>=col or i>=row or grid[i][j] == 0:
        return 1
    
    return 0