回溯+图leetcode417:

> Problem: [417. 太平洋大西洋水流问题](https://leetcode.cn/problems/pacific-atlantic-water-flow/description/)

# 思路

> leetcode官方题解从大西洋和太平洋分别到节点回溯,但是有个坑给大家分享一下。

# 解题方法

> 在传参时候我用了四条边for循环传参,但是在 pacificAtlantic 函数中,在调用 dfs 函数时传递的是 pacificVisit 作为 visited 数组参数,导致 atlanticVisit 数组在 dfs 函数中无法正确更新。同样地,在第二次调用 dfs 函数时,传递 atlanticVisit 数组作为 visited 数组参数,也会导致 pacificVisit 数组未能正确更新。

尝试通过将 pacificVisit 和 atlanticVisit 数组分别传递给不同的 dfs 函数来解决。

贴一个错误代码:



package main


func pacificAtlantic(heights [][]int) [][]int {

    res := [][]int{}

    m, n := len(heights), len(heights[0])


    if m == 0 || n == 0 {

        return res

    }

    pacificVisit := make([][]bool, n)

    atlanticVisit := make([][]bool, n)


    for i := 0; i < n; i++ {

        pacificVisit[i] = make([]bool, m)

        atlanticVisit[i] = make([]bool, m)

    }


    for i := 0; i < m; i++ {

        dfs(heights, i, 0, pacificVisit)

    }

    for j := 0; j < n; j++ {

        dfs(heights, 0, j, pacificVisit)

    }

    for i := 0; i < m; i++ {

        dfs(heights, i, n-1, atlanticVisit)

    }

    for j := 0; j < n; j++ {

        dfs(heights, m-1, j, atlanticVisit)

    }


    for i := 0; i < m; i++ {

        for j := 0; j < n; j++ {

            if pacificVisit[i][j] && atlanticVisit[i][j] {

                res = append(res, []int{i, j})

            }

        }

    }

    return res

}


// 从边界点到中心节点回溯算法如果存在点加入队列

func dfs(heights [][]int, i int, j int, visited [][]bool) {

    visited[i][j] = true

    offset := [][]int{{-1, 0}, {1, 0}, {0, -1}, {0, 1}}


    for _, v := range offset {

        newi, newj := i+v[0], j+v[1]

        if newi >= 0 && newi < len(heights) && newj >= 0 && newj < len(heights[0]) && heights[i][j] <= heights[newi][newj] && !visited[newi][newj] {

            dfs(heights, newi, newj, visited)

        }

    }

# 复杂度

- 时间复杂度:

> 复杂度不谈,反正都是100


 


正确的代码:



package main


func pacificAtlantic(heights [][]int) [][]int {

    res := [][]int{}

    m, n := len(heights), len(heights[0])


    if m == 0 || n == 0 {

        return res

    }

    pacificVisit := make([][]bool, m)

    atlanticVisit := make([][]bool, m)


    for i := 0; i < m; i++ {

        pacificVisit[i] = make([]bool, n)

        atlanticVisit[i] = make([]bool, n)

    }


    for i := 0; i < m; i++ {

        dfs(heights, i, 0, pacificVisit)

        dfs(heights, i, n-1, atlanticVisit)

    }

    for j := 0; j < n; j++ {

        dfs(heights, 0, j, pacificVisit)

        dfs(heights, m-1, j, atlanticVisit)

    }


    for i := 0; i < m; i++ {

        for j := 0; j < n; j++ {

            if pacificVisit[i][j] && atlanticVisit[i][j] {

                res = append(res, []int{i, j})

            }

        }

    }

    return res

}


// 从边界点到中心节点回溯算法如果存在点加入队列

func dfs(heights [][]int, i int, j int, visited [][]bool) {

    visited[i][j] = true

    offset := [][]int{{-1, 0}, {1, 0}, {0, -1}, {0, 1}}


    for _, v := range offset {

        newi, newj := i+v[0], j+v[1]

        if newi >= 0 && newi < len(heights) && newj >= 0 && newj < len(heights[0]) && heights[i][j] <= heights[newi][newj] && !visited[newi][newj] {

            dfs(heights, newi, newj, visited)

        }

    }

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值