简体   繁体   中英

Golang code too slow for Hackerrank

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 (
    "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
    }
}

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.

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.

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'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.

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