Golang代码在Hackerrank上运行太慢了。

huangapple go评论102阅读模式
英文:

Golang code too slow for Hackerrank

问题

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

你需要做以下事情:

你有一个大矩阵:

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-- {
		// 开始扫描输入
		// 扫描大矩阵
		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
			}
		}
		// 扫描小矩阵
		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
			}
		}
		// 停止扫描输入
		// 开始在大矩阵中搜索小矩阵
		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")
		}
		// 停止在大矩阵中搜索小矩阵
	}
}

我使用了一个整数切片的切片来存储输入。

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

rLcL表示大矩阵的行和列。

rScS表示小矩阵的行和列。

英文:

I've been trying to solve this Hackerrank challenge: Link

This is what you have to do:

You have one large matrix:

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

and one small matrix:

1 1 1
1 1 1
1 1 0

You have to find out if the small matrix is present in the large matrix.

There are up to 5 testcases and each matrix can be of max 1000x1000 size and I need to solve this in under 4 seconds.

My code timeouts for the largest possible input, I thought that maybe how I'm scanning the matrix is too slow.

This is my code:

package main
import (
&quot;fmt&quot;
&quot;strconv&quot;
&quot;strings&quot;
)
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(&quot;%d&quot;, &amp;t)
for ; t &gt; 0; t-- {
// Start scanning input
// Scanning large matrix
fmt.Scanf(&quot;%d%d&quot;, &amp;rL, &amp;cL)
mxL = make([][]int, rL)
for i := range mxL {
mxL[i] = make([]int, cL)
}
for i := 0; i &lt; rL; i++ {
fmt.Scanf(&quot;%s&quot;, &amp;s)
sl = strings.Split(s, &quot;&quot;)
for j, v := range sl {
temp, _ = strconv.Atoi(v)
mxL[i][j] = temp
}
}
// Scanning small matrix
fmt.Scanf(&quot;%d%d&quot;, &amp;rS, &amp;cS)
mxS = make([][]int, rS)
for i := range mxS {
mxS[i] = make([]int, cS)
}
for i := 0; i &lt; rS; i++ {
fmt.Scanf(&quot;%s&quot;, &amp;s)
sl = strings.Split(s, &quot;&quot;)
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 &lt;= rL-rS; iL++ {
for jL := 0; jL &lt;= cL-cS; jL++ {
found = true
if mxL[iL][jL] == mxS[0][0] {
for iS := 0; iS &lt; rS; iS++ {
for jS := 1; jS &lt; 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(&quot;YES&quot;)
break
}
}
if !found {
fmt.Println(&quot;NO&quot;)
}
// Stop searching for small matrix in large matrix
}
}

I'm using a slice of slices of ints to store the input.

mxL is the large matrix and mxS is the small matrix.

rL and cL stand for row and column of the large matrix.

rS and cS stand for row and column of the small matrix.

答案1

得分: 2

好的,以下是翻译好的内容:

我将给你指出一个想法,然后你可以尝试实现它。首先创建一个与你的大数组一样大的新的二维数组,称之为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

现在让我展示一下你的sumArray会是什么样子:

-1 -1 -1 -1 -1 -1     -1表示我们不能在这个位置求和,因为
-1 -1 -1 -1 -1 -1      尺寸比你的小数组还要小
-1 -1  9  9  9  9      每个单元格表示原始矩阵值的总和。
9  9  9  9  9  9
9  9  9  8  9  9

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

英文:

Well I am gonna point out an idea to you and then you can try to implement it. So create a new 2d array as large as your large array. Call it sumArray. Now let each cell in this sumArray represent the sum where the current cell is the most bottom-left cell. Now what you do is check only the cells that has the same sum as your small array instead of checking every element in the array.
<br>

So if those are your inputs

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

First sum your small array --> 8

Now let me show you how your sum array would look like

-1 -1 -1 -1 -1 -1     -1 means that we can&#39;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

Now if you scan trough this array only you can see that you will reduce your search space from every possible position to only the position where your sum is equal. This doesn't guarantee that the array are in this position you still have to add a verification step but it reduce your search space.

huangapple
  • 本文由 发表于 2015年9月18日 21:20:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/32653087.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定