운동하는 개발자/알고리즘, 코딩테스트
HackerRank [String] Bear and Steady Gene /알고리즘 해커랭크[미해결]
우용현
2021. 5. 8. 19:55
728x90
문제 주소 : www.hackerrank.com/challenges/bear-and-steady-gene/problem
난이도 : Medium
성공률 : 63.58%
(210505) [미해결] 7개 예제 타임아웃
문제 : 4의 배수의 길이를 가진 문자열을 준다
그 문자는 A, C, T, G로만 구성되어있다
substring을 수정하여 A, C, T, G가 모두 같은 개수가 나오게 해야 한다
최소한으로 수정해야하는 substring 길이 값을 리턴하라
풀이
1) ACTG 문자 중 초과된 문자와 각각의 수, 합산한 수(변환해야 하는 최소 개수)를 체크
2) 변환해야 하는 최소개수길이만큼 substring을 한 칸씩 이동하며 분리시켜봄
3) 분리시킨 substring에 변환해야하는 문자들이 모두 포함하는지 체크(함수 dist_check)
4) 모든 substring이 포함하지 않는다면 최소 개수 길이+1을 한 뒤 다시 처음부터 substring을 한 칸씩 이동하며 체크해봄
4) 최종적으로 포함되었을 때 길이값을 리턴
답안
#!/bin/python3
import math
import os
import random
import re
import sys
import collections
import time
#0502 타임오버남 7개나... count하는건 꼭 필요한거같고 비교부분에서 dist를 최대한 없애야 할듯? 혹은 마지막 체크하는 이중 포문에서?
#0505 다음에 다시풀어보자 2포인트로 앞뒤 맞춰가다 하는듯..
def dist_check(over_dist, temp_substr):
# for k in over_dist:
# try:
# if over_dist[k] > temp_substr.count(k):
# return False
# except:
# return False
# else:
# return True
newdist_counter : dist = collections.Counter(temp_substr)
for k in over_dist:
if over_dist[k] > newdist_counter[k]:
return False
else:
return True
def steadyGene(gene):
start_time : time = time.time()
gene_length : int = len(gene)
move_count : int = 0
sum_count : int = 0
dist_counter : dist = collections.Counter(gene)
dist_overchar: dist = {}
for i in dist_counter: #초과된 문자의 수(전체길이/4)가 있는지 있다면 얼마나 초과됬는지 누적하기, 그게 변환시켜야 할 최소 개수이므로
if gene_length/4 < dist_counter[i]:
move_count = int(dist_counter[i] - gene_length/4)
sum_count += move_count
dist_overchar[i] = int(move_count) #초과된 애들 저장해놓기 각 문자가 얼마나 초과되었는지 저장해놓기
if sum_count == 0: #초과된게 없다면 정상!!!
return 0
temp_substr = ""
# for i in range(move_count, gene_length-1): #[변환시켜야 할 최소 개수]부터 하나씩 늘려보기 문자열 최대길이 만큼? 어짜피 최대길이 -1전엔 끝나긴함
# for j in range(0, gene_length-i): #[변환시킬 시작점] 한칸씩 옆으로 이동해보며 i길이 만큼 지워본다 남은 문자열이 초과된 문자와 그 문자의 초과된 수만큼 있으면 i리턴 끝
# temp_substr = gene[j:i+j]
# if dist_check(dist_overchar, temp_substr) == True :
# return i
for i in range(move_count, gene_length-1): #[변환시켜야 할 최소 개수]부터 하나씩 늘려보기 문자열 최대길이 만큼? 어짜피 최대길이 -1전엔 끝나긴함
for j in range(0, gene_length-i): #[변환시킬 시작점] 한칸씩 옆으로 이동해보며 i길이 만큼 지워본다 남은 문자열이 초과된 문자와 그 문자의 초과된 수만큼 있으면 i리턴 끝
temp_substr = gene[j:i+j]
if dist_check(dist_overchar, temp_substr) == True :
print("time : {}", time.time()-start_time)
return i
# print(dist_overchar)
if __name__ == '__main__':
# fptr = open(os.environ['OUTPUT_PATH'], 'w')
fptr = sys.stdout
n = int(input().strip())
gene = input()
result = steadyGene(gene)
fptr.write(str(result) + '\n')
fptr.close()
느낀점
더보기
시간을 재보니 서브스트링을 분리하며 그걸 비교할 때 시간이 상당히 걸렸다
힌트를 찾아보니 중간까지는 다른사람들과 동일한데 투포인터를 이용해서 탐욕알고리즘을 쓰면 된다는데
한 외국인의 코드를 봤는데 봐도 잘 모르겠다.. 나중에 공부좀 더 한뒤 다시 풀 예정
힌트를 찾아보니 중간까지는 다른사람들과 동일한데 투포인터를 이용해서 탐욕알고리즘을 쓰면 된다는데
한 외국인의 코드를 봤는데 봐도 잘 모르겠다.. 나중에 공부좀 더 한뒤 다시 풀 예정
더보기
정답을 하나 까봤는데 답은 맞는데 285초가 걸린다 ㅋㅋㅋㅋ 아놔
728x90