Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
Tags
- 알고리즘
- DFS: Connected Cell in a Grid
- 파이썬
- 구슬탈출2
- 격파르타 후기
- Interview Preparation Kit
- 프로그래머스
- 머신러닝
- 격파르타 합격후기
- Algorithm
- 매칭점수
- 야근지수
- BFS: Shortest Reach in a Graph
- [sqld]자격증합격
- 피보나치 함수
- Max Array Sum
- Common Child
- Find the nearest clone
- 백준
- 해커랭크
- Roads and Libraries
- python
- Special String Again
- Reverse Shuffle Merge
- 격파르타 장점
- 코딩테스트
- candies
- programmers
- Recursion: Davis' Staircase
- hackerrank
Archives
- Today
- Total
Archive
[Hackerrank] [Hard] Reverse Shuffle Merge 본문
https://www.hackerrank.com/challenges/reverse-shuffle-merge/problem
풀이
- 입력으로 문자열 s를 받을 때 아래 조건을 만족하는 알파벳 순으로 가장 앞선 문자열 A를 찾는 문제
- s \in merge( reverse(A) , shuffle(A) )
- merge 연산은 파라미터로 두 개의 string을 받는데, 각 string의 입력 순서만 맞으면 됨.
- merge( 'abac', 'bcbc' ) -> (a)b(b)c(ac)bc 괄호안에 있는게 'abac', 없는게 'bcbc'
- reverse 연산은 문자열을 뒤집는 것이고, shuffle 연산은 permutation을 뜻함.
- string 2개를 합쳐 입력 문자열 s가 되야하기 때문에, s의 각 문자 개수는 짝수개 -> (각 문자의 count // 2)개만큼 나눠가지게 됨.
- s = 'abbcca' -> A는 {a:1, b:1, c:1}로 구성됨.
- s \in merge( reverse(A), shuffle(A) ) => reverse(s) \in merge( A , shuffle(A) )
- count_dict으로 각 문자열 개수 정보를 저장.
- used_dict으로 정답 후보에 사용된 문자열 개수 정보를 저장
- remain_dict으로 앞으로 남은 문자열 개수 정보를 저장.
- 처음에 count_dict으로 초기화.
- input string으로 iteration마다 해당 문자열 개수 1씩 감소
- reversed(input string)을 한 번 보면서 정답에 포함할지 안할지를 stack 자료구조를 사용.
- input string의 i번째 문자가 c라고 했을 때,
- c를 정답에 포함시킬지 말지 결정. 먼저 A에는 count_dict[c]//2개만큼의 문자가 있어야 함. 이를 used_dict[c]와 비교해 조건문 만듬.
- (count_dict[c] // 2) > used_dict[c]
- 중요한건 pop의 조건인데, stack 자료구조를 사용한 result에 정답 후보 문자열이 담겨있다면
-
- result의 마지막 문자열이 현재 iteration 문자열 c보다 크고(알파벳 순)
- result의 마지막 문자열이 앞으로 남은 문자열에 있어 나중에 다시 insert를 수행할 수 있을 때만 pop을 할 수 있음.(나중에 다시 넣음)
-
- used_dict[c]에 1 추가, remain_dict[c]에 1 감소
def reverseShuffleMerge(s):
from collections import defaultdict
count_dict = defaultdict(int)
used_dict = defaultdict(int)
result = []
for c in s:
count_dict[c] += 1
remain_dict = dict(count_dict)
for c in reversed(s):
if (count_dict[c] // 2) > used_dict[c]:
while result and result[-1] > c and (used_dict[result[-1]] + remain_dict[result[-1]]) > (count_dict[result[-1]] // 2):
pop_char = result.pop()
used_dict[pop_char] -= 1
used_dict[c] += 1
result.append(c)
remain_dict[c] -= 1
return "".join(result)
'공부 > Algorithm' 카테고리의 다른 글
[Hackerrank] [Medium] Abbreviation (0) | 2020.09.01 |
---|---|
[Hackerrank] [Medium] Max Array Sum (0) | 2020.08.31 |
[Hackerrank] [Medium] Common Child (0) | 2020.08.28 |
[Hackerrank] [Medium] Special String Again (0) | 2020.08.28 |
[Hackerrank] [Medium] Sherlock and the Valid String (0) | 2020.08.27 |
Comments