简体   繁体   中英

Counting number of binary substrings of length 3+ with one unique element

Essentially, I'm given two lines of input. The first line is an integer length of the substring presented in the second line of input, consisting of only Gs and Hs, similar to 0s and 1s.

N = int(input())
chars = list(input())
lonely = 0
for i in range(3, N + 1):
  for j in range(N - i + 1):
      if ((chars[j:j + i].count('G') == 1) or (chars[j:j + i].count('H') == 1)):
          lonely += 1
print(lonely)

An example input is:

5
GHGHG

for which the answer is 3 : the answer is the number of the original string's substrings of length 3 or greater that only have one G or one H (this G or H is 'lonely'), and for the above sample, the substrings that meet this criterion are chars[0:3] , chars[1:4] , and chars[2:5] . While I think this is technically correct, there are no constraints on N so I am timing out for test cases where N = 5000 and such (I have a time limit of 4 seconds per test case).

How do I work around this?

Thank you!

This should be faster:

chars = "GHGHG"

count = 0
for letter in "GH":                        # count for G, then H
    prev = 0                               # length of previous non-letter
    for s in map(len,chars.split(letter)): # get in-betweens
        s = min(2,s)                       # look at no more than 2 each side 
        count += max(0,s+prev-1)           # before+after >= 2
        prev = s
        
print(count) # 3

If you split the string on the letter "G", you will get the Hs in between individual Gs. If the total of Hs on each side of a G is >= 2 then you have a substring with a single G in it. You only need to look at maximum 2 Hs before and after.

with the before and after counts limited to 2, there are only 9 possibilities:

  • "G" -> 0 before, 0 after --> no substring
  • "GH" -> 0 before, 1 after --> no substring
  • "GHH" -> 0 before, 2 after --> 1 substring
  • "HG" -> 1 before, 0 after --> no substring
  • "HGH" -> 1 before, 1 after --> 1 substring
  • "HGHH" -> 1 before, 2 after --> 2 substrings (HGH & GHH)
  • "HHG" -> 2 before, 0 after --> 1 substring
  • "HHGH" -> 2 before, 1 after --> 2 substrings (HHG & HGH)
  • "HHGHH" -> 2 before, 2 after --> 3 substrings (HHG, HGH, GHH)

You can get the lonely "H" count the same way (ie splitting on H).

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