我遇到了一个问题,我想查找长度为n(每个n位数字可以为0,1,... 9)的十进制字符串的数目,这些数字的“游程”至少为{{ 1}}。 “游程”是连续的递增/递减的数字序列,可以使mod 10上溢/下溢。例如,“ 345600”,“ 901285”,“ 098723”的游程长度均为4,但是“ 123890”的游程长度只有两个3.
我的想法是遍历每个length >= k
个可能的候选人。我知道,对于每个候选人,您都需要检查10^n
个数字的n-k+1
个“块”,以查看它们是“递增”还是“递减”。
k
我在想出一个功能来检查“递增模块10”时遇到了麻烦。当前,此函数很容易返回False。也许我错过了一个我还没有学到的标准技巧,或者有一种简单的递归方法可以做到这一点?感谢您的指导。
这是我第一次在StackOverflow上提问。请让我知道我以后如何能提出更好的问题。
答案 0 :(得分:0)
当(a-b + 10)%10等于1时,数字a,b按递增顺序排列;如果等于9,则数字按a递减顺序排列。其他任何值表示它们不按顺序排列。
您可以创建一个成对的字典,该字典将告诉两个连续的字符是递增(1)还是递减(9)运行的一部分。然后处理字符串中的每对字符以将它们转换为运行指示器。如果找到长度为N-1的连续“ 1”或“ 9”指示符,则说明您至少有一个长度为N的游程:
def hasRun(string,count):
match = {(str(n),str((n+d)%10)):str(d) for d in [1,9] for n in range(10) }
runs = "".join( match.get(pair,".") for pair in zip(string,string[1:]) )
return "1"*(count-1) in runs or "9"*(count-1) in runs
解决此问题的另一种方法是在字符串中搜索长度N的20个可能的游程(10个递增,其10个倒数):
def hasRun(string,count):
for i in range(10):
run = "".join(str((d+i)%10) for d in range(count))
if run in string or run[::-1] in string: return True
return False
最后,如果您需要一种程序方法,可以这样做:
def hasRun(string,count):
runType = 0
runCount = 0
match = {(str(n),str((n+d)%10)):d for d in [1,9] for n in range(10) }
for a,b in zip(string,string[1:]):
delta = match.get((a,b),0)
runCount = 2 if delta != runType else runCount + 1
if delta != 0 and runCount == count:
return True
runType = delta
return False
注意:此过程方法运行时间为O(n)。当它在字符串的开头找到所请求长度的游程时,它通常比其他两个执行得更快。这是因为它立即停止迭代并且不处理字符串的其余部分。