【问题标题】:Python implementation of Determining DNA Health algorithm from HackerRank从 HackerRank 确定 DNA 健康算法的 Python 实现
【发布时间】:2019-07-11 10:38:54
【问题描述】:

我正在尝试使用 python 解决Determining DNA Health challenge from Hackerrank。 (我必须补充一点,我对 python 3 有点陌生。还在学习这门语言)

对于测试用例 7、8 和 9,我的解决方案失败,并显示一条消息“错误答案”。

当我在本地运行以下代码时,我可以确认对于这些测试用例,我的实现产生了预期的输出。

我想知道会是什么问题。

我现在有点困惑。我的实施有问题吗?如果是这样,它为什么会为 28 个测试用例产生正确的答案,但在这 3 个测试用例上却失败了?或者它是来自 Hacker Rank 的误导性/令人困惑的结果信息,因为我碰巧知道人们从我从阅读讨论中学到的东西中发现这 3 个测试用例(7、8 和 9)有问题。

任何帮助将不胜感激。

这是我写的代码:

from bisect import bisect_left
from bisect import bisect_right
import sys
from unittest.mock import right

class TrieNode(object):

    def __init__(self):
        self.subnodes = {}
        self.isTerminal = False
        self.indexList = []
        self.healthList = []

    def addSubnode(self, aChar):
        if (self.subnodes.get(aChar)):
            return self.subnodes[aChar]
        else:
            newNode = TrieNode()
            self.subnodes[aChar] = newNode
            return newNode

    def addIndexAndValue(self, index, health):
        self.isTerminal = True
        self.indexList.append(index)
        lastHealth = 0
        healthLength = len(self.healthList)
        if (healthLength>0):
            lastHealth = self.healthList[healthLength-1]
        self.healthList.append(lastHealth + health)

    def getSubnodeFor(self, aChar):
        return self.subnodes.get(aChar)

    def getValueForIndexes(self, startIndex, endIndex):
        listSize = len(self.indexList)
        if listSize < 1:
            return 0
        elif listSize == 1:
            if startIndex <= self.indexList[0] and endIndex >= self.indexList[0]:
                return self.healthList[0]
            else:
                return 0 
        else: # listSize > 1  
            rightInd = bisect_left(self.indexList, endIndex)
            if rightInd < listSize and endIndex < self.indexList[0]:
                return 0

            big = 0

            if rightInd >= listSize:
                big = self.healthList[listSize - 1]
            else:
                if endIndex >= self.indexList[rightInd]:
                    big = self.healthList[rightInd]
                else:
                    big = self.healthList[rightInd-1]

            leftInd = bisect_left(self.indexList, startIndex)            

            small = 0
            if leftInd >= listSize:
                return 0
            else:
                if startIndex <= self.indexList[leftInd]:
                    if (leftInd > 0):
                        small = self.healthList[leftInd - 1]
                    else:
                        small = 0
                else:
                    small = self.healthList[leftInd]

            return big - small

class Trie(object):

    def __init__(self):
        self.root = TrieNode()

    def getRoot(self):
        return self.root

    def createTrie(self, genes, healths):
        for i in range(len(genes)):
            node = self.root
            for c in genes[i]:
                node = node.addSubnode(c)
            node.addIndexAndValue(i, healths[i])


def calculateHealth(trie, d, first, last):
    total = 0
    dLength = len(d)
    for i in range(0, dLength):
        node = trie.getRoot()
        for j in range(i, dLength):
            node = node.getSubnodeFor(d[j])
            if node != None:
                if node.isTerminal:
                    val = node.getValueForIndexes(first, last)
                    total = total + val
            else:
                break 
    return total


def readFromFile(aFileName):

    inputArr = None
    with open('../hackerRank/src/' + aFileName, encoding='utf-8') as aFile:
        inputArr = aFile.read().splitlines()
    return inputArr


def runFor(fileName, minimumValue, maximumValue):
    inp = readFromFile(fileName)
    n = inp[0]
    genes = inp[1].rstrip().split()
    healths = list(map(int, inp[2].rstrip().split()))
    trie = Trie()
    trie.createTrie(genes, healths)
    s = int(inp[3])
    minVal = sys.maxsize
    maxVal = -1

    for fItr in range(s):
        line = inp[fItr+4].split()
        first = int(line[0])
        last = int(line[1])
        d = line[2]

        val = calculateHealth(trie, d, first, last)

        if val < minVal:
            minVal = val

        if val > maxVal:
            maxVal = val


    print (minVal,maxVal)
    assert minimumValue == minVal
    assert maximumValue == maxVal



# TextX.txt 's are simple text files, which hold test data for regarding test case
# following the file name are real expected numbers for each relevant test case
# I got those from hacker rank
runFor('Test2.txt', 15806635, 20688978289)
runFor('Test7.txt', 0, 7353994)
runFor('Test8.txt', 0, 8652768)
runFor('Test9.txt', 0, 9920592)
runFor('Test33.txt', 11674463, 11674463)

【问题讨论】:

  • 正如他们在讨论中强调的那样,可能使用了太多内存。
  • @user58697 感谢您的回复。正如您所指出的,Hacker Rank 期望解决方案在预定义的内存大小和预定义的时间段内运行。如果任何解决方案超出了这些预期,则应该给出“因超时而终止”错误,而不是“错误答案”消息。请参考support.hackerrank.com/hc/en-us/articles/…。但我 100% 确定吗?不是真的:\这就是我问这个问题的原因。

标签: python python-3.x algorithm computer-science


【解决方案1】:

可以在以下位置找到可能有帮助的参考: https://gist.github.com/josephmisiti/940cee03c97f031188ba7eac74d03a4f

请阅读他包含的注释。

这是我一直在使用的输入。

6 a b c a a b 1 2 3 4 5 6 3 1 5 卡布 0 4 xyz 2 4 bcdybc

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-04-24
    • 2022-06-27
    • 1970-01-01
    • 1970-01-01
    • 2021-10-23
    • 2019-11-20
    • 1970-01-01
    相关资源
    最近更新 更多