【问题标题】:Golang code too slow for HackerrankGolang 代码对于 Hackerrank 来说太慢了
【发布时间】:2015-09-18 13:20:24
【问题描述】:

我一直在尝试解决这个 Hackerrank 挑战:Link

这是你必须做的:

你有一个大矩阵:

1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 0 1 1

还有一个小矩阵:

1 1 1
1 1 1
1 1 0

你必须找出小矩阵是否存在于大矩阵中。

最多有 5 个测试用例,每个矩阵的最大尺寸为 1000x1000,我需要在 4 秒内解决这个问题。

我的代码对尽可能大的输入超时,我想可能是我扫描矩阵的方式太慢了。

这是我的代码:

package main

import (
    "fmt"
    "strconv"
    "strings"
)

func main() {
    var t, rL, cL, rS, cS, temp int
    var s string
    var sl []string
    var mxL, mxS [][]int
    var found bool
    fmt.Scanf("%d", &t)
    for ; t > 0; t-- {
        // Start scanning input
        // Scanning large matrix
        fmt.Scanf("%d%d", &rL, &cL)
        mxL = make([][]int, rL)
        for i := range mxL {
            mxL[i] = make([]int, cL)
        }
        for i := 0; i < rL; i++ {
            fmt.Scanf("%s", &s)
            sl = strings.Split(s, "")
            for j, v := range sl {
                temp, _ = strconv.Atoi(v)
                mxL[i][j] = temp
            }
        }
        // Scanning small matrix
        fmt.Scanf("%d%d", &rS, &cS)
        mxS = make([][]int, rS)
        for i := range mxS {
            mxS[i] = make([]int, cS)
        }
        for i := 0; i < rS; i++ {
            fmt.Scanf("%s", &s)
            sl = strings.Split(s, "")
            for j, v := range sl {
                temp, _ = strconv.Atoi(v)
                mxS[i][j] = temp
            }
        }
        // Stop scanning input
        // Start searching for small matrix in large matrix
        found = true
        for iL := 0; iL <= rL-rS; iL++ {
            for jL := 0; jL <= cL-cS; jL++ {
                found = true
                if mxL[iL][jL] == mxS[0][0] {
                    for iS := 0; iS < rS; iS++ {
                        for jS := 1; jS < cS; jS++ {
                            if mxS[iS][jS] != mxL[iS+iL][jS+jL] {
                                found = false
                                break
                            }
                        }
                        if !found {
                            break
                        }
                    }
                    if found {
                        break
                    }
                } else {
                    found = false
                }
            }
            if found {
                fmt.Println("YES")
                break
            }
        }
        if !found {
            fmt.Println("NO")
        }
        // Stop searching for small matrix in large matrix
    }
}

我正在使用一片整数切片来存储输入。

mxL 是大矩阵,mxS 是小矩阵。

rLcL代表大矩阵的行和列。

rScS代表小矩阵的行列。

【问题讨论】:

  • My code works but timeouts for the largest possible input,所以它不起作用。因为时间限制是问题的一部分:My code works but it predicts tonight's weather tomorrow 不是有效代码。
  • 感谢您的建设性反馈,我已经编辑了我的文字。
  • 也许您需要一种不同的算法,而不仅仅是简单的逐个元素比较?
  • 我确信这里有一个关于变量命名的案例研究,以使代码清晰。但除此之外 - 蛮力方法通常是解决问题的效率最低的方法 - 一个明显的此类优化是首先读取小矩阵,然后 当您处理大矩阵时,您可以快速丢弃任何不包含小矩阵第一行的内容。 (如果你发现了,那么你需要保留接下来的几行)
  • 我投票结束这个问题,因为它属于codereview.stackexchange.com

标签: algorithm performance go


【解决方案1】:

好吧,我会向您指出一个想法,然后您可以尝试实施它。因此,创建一个与您的大数组一样大的新二维数组。称之为 sumArray。现在让这个 sumArray 中的每个单元格表示当前单元格是最左下角单元格的总和。现在您要做的是仅检查与您的小数组具有相同总和的单元格,而不是检查数组中的每个元素。

如果这些是你的输入

1 1 1 1 1 1     
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 1 1 1
1 1 1 0 1 1

1 1 1
1 1 1
1 1 0

首先对你的小数组求和 --> 8

现在让我告诉你你的 sum 数组是什么样子的

-1 -1 -1 -1 -1 -1     -1 means that we can't sum at this point because
-1 -1 -1 -1 -1 -1      the dimensions are just smaller than your small array
-1 -1  9  9  9  9      each other cell represent the sum of your original 
 9  9  9  9  9  9      matrix values.
 9  9  9  8  9  9

现在,如果你只扫描这个数组,你会发现你会将搜索空间从每个可能的位置减少到只有你的总和相等的位置。这并不能保证数组处于此位置,您仍然需要添加验证步骤,但会减少您的搜索空间。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-26
    • 2011-10-17
    • 2020-08-08
    • 2016-05-15
    • 1970-01-01
    • 1970-01-01
    • 2020-10-03
    • 2013-10-19
    相关资源
    最近更新 更多