- Codekata 2번째 주.
- 1번째 주도 생각보다 녹녹치 않다고 생각했는데, 2번째 주는 갑자기 난이도가 상당히 올라갔다. 사전스터디 때 알고리즘 문제 많이 풀어둔게 어느 정도 적응하는데 도움이 된 듯.
Day1
*문제
로마자에서 숫자로 바꾸기 1~3999 사이의 로마자 s를 인자로 주면 그에 해당하는 숫자를 반환해주세요. 로마 숫자를 숫자로 표기하면 다음과 같습니다.
>Symbol Value
I 1
V 5
X 10
L 50
C 100
D 500
M 1000
>로마자를 숫자로 읽는 방법은 로마자를 왼쪽부터 차례대로 더하면 됩니다.
III = 3
XII = 12
XXVII = 27입니다.
>그런데 4를 표현할 때는 IIII가 아니라 IV 입니다.
뒤의 숫자에서 앞의 숫자를 빼주면 됩니다.
9는 IX입니다.
>I는 V와 X앞에 와서 4, 9
X는 L, C앞에 와서 40, 90
C는 D, M앞에 와서 400, 900
My Solution
def roman_to_num(s):
romanDict = {
'I' : 1,
'V' : 5,
'X' : 10,
'L' : 50,
'C' : 100,
'D' : 500,
'M' : 1000
}
sum = 0
index = 0
while index < len(s):
# print(sum, index)
if index == len(s)-1:
sum += romanDict[s[index]]
break
if s[index]=='I' and (s[index+1]=='V' or s[index+1]=='X'):
sum += romanDict[s[index+1]]-romanDict[s[index]]
index += 2
print(sum, index)
continue;
if s[index]=='X' and (s[index+1]=='L' or s[index+1]=='C'):
sum += romanDict[s[index+1]]-romanDict[s[index]]
index += 2
print(sum, index)
continue;
if s[index]=='C' and (s[index+1]=='D' or s[index+1]=='M'):
sum += romanDict[s[index+1]]-romanDict[s[index]]
index += 2
print(sum, index)
continue;
sum += romanDict[s[index]]
index += 1
return sum
- 다소 하드코딩한 느낌이 있지만, 시간이 많지 않아서 더 고민할 여유가 없었다.
- 예외가 아닌 다른 Roman 숫자를 구하는 것은 어렵지 않지만, IV나 XL과 같은 특수한 경우를 예외로 처리해야하기 때문에 문제가 어려웠다.
- 아이디어는 간단하다. IV이면 V-I=4 로 구하면 쉽다.
그리고 2칸만큼의 Index를 뛰어넘어 다른 숫자는 합을 구하면 끝.
- 직관적인 로직을 짜는 건 어렵지 않았지만, 더 잘 푸는 방법은 시간이 있으면 고민해봐야겠다.
Day 2
* 문제
숫자로 이루어진 배열인 nums를 인자로 전달합니다.
숫자중에서 과반수(majority, more than a half)가 넘은 숫자를 반환해주세요.
예를 들어,
nums = [3,2,3]
return 3
nums = [2,2,1,1,1,2,2]
return 2
>* 가정
nums 배열의 길이는 무조건 2개 이상
My Solution
def more_than_half(nums):
numSet = set(nums)
for num in numSet:
if nums.count(num) >= len(nums)/2:
return num
- count함수를 이용하면 간결하게 짤 수 있었던 문제다.
- Set 자료형을 이용해 nums 배열에서 중복을 제거한 후, 각 숫자별로 nums의 등장횟수를 Count함수로 센 후, 절반 길이보다 큰지에 대해 검사하면 깔끔하게 풀 수 있다.
Day 3
*문제
s는 여러 괄호들로 이루어진 String 인자입니다.
s가 유효한 표현인지 아닌지 true/false로 반환해주세요.
종류는 '(', ')', '[', ']', '{', '}' 으로 총 6개 있습니다. 아래의 경우 유효합니다.
한 번 괄호를 시작했으면, 같은 괄호로 끝내야 한다.
괄호 순서가 맞아야 한다.
예를 들어 아래와 같습니다.
s = "()"
return true
s = "()[]{}"
return true
s = "(]"
return false
s = "([)]"
return false
s = "{[]}"
return true
My Solution
def is_valid(string):
open = ['(', '{', '[']
close= [')', '}', ']']
open_bracket = []
close_bracket = []
if len(string) == 1:
return False
for i in range(len(string)):
if string[i] in open:
open_bracket.append(string[i])
elif string[i] in close:
close_bracket.append(string[i])
if len(open_bracket) == 0:
return False
if close.index(close_bracket[-1]) != open.index(open_bracket[-1]):
return False
else:
del open_bracket[-1]
del close_bracket[-1]
return True
- 이 문제는 Stack의 원리를 응용하면 풀 수 있는 문제였다.
- 괄호들은 열린 순서대로 닫혀야 한다. open_bracket 배열에는 여는 괄호를 넣고, close_bracket에는 닫힌 괄호가 들어오게 해서, Index를 돌리면서 짝이 맞는지 안 맞는지를 검사하면 된다. append함수로 계속 쌓이기 때문에, 나중에 제거할 때는 마지막 index들만 검사하면 된다.
- Dictionary로 검사했다면 변수를 좀 더 깔끔하게 저장할 수 있었을지도.