적어도 주에 글 하나정도는 주중에 진행한 코드카타에 대해서 정리해보기로 했다.
이미 지나간 첫번째 코드카타는 그냥 넘어가고 저번주에 진행했던 코드카타 중에서 몇개 골라봤다.
2주차 4일째 - 자주 등장한 숫자를 전달받은 인자만큼 반환하기
- 조건 1 - 첫번째 인자는 숫자로 이루어진 배열이다. 길이는 딱히 정해지지 않음
- 조건 2 - 두번째 인자는 반환할 숫자의 개수이다. 특별한 조건은 명시되지 않았다.
- 생각한 처리 로직
- 빈 딕셔너리를 생성한다.
- 배열 요소를 하나씩 읽는다.
- 딕셔너리의 키와 비교해서 배열 요소가 키로 사용되지 않는다면 새로운 키 - 값 쌍을 생성한다.
- 이미 키가 존재한다면 해당 키의 값을 1 누적한다.
- 배열의 끝까지 반복
- 딕셔너리의 값을 기준으로 해당 값의 키를 내림차순으로 리스트에 저장한다.
- 반환하도록 입력받은 두번째 인자만큼 슬라이싱해서 반환
- 로직 코딩
########################################################
# 2주차 4일째 코드카타
def top_k(nums, k):
check_dict = {}
for index in nums:
if index in check_dict:
check_dict[index] += 1
else:
check_dict[index] = 1
check_dict = dict(sorted(check_dict.items(), reverse = True, key=lambda x: x[1])) # 딕셔너리의 값을 기준으로 키값을 내림차순으로 정렬
check_list = list(check_dict.keys()) # 정렬된 딕셔너리에서 키 값만 뽑아서 리스트에 저장
if len(check_list) <= k: # 만약 입력받은 수가 체크한 결과 리스트의 길이보다 클 경우
return check_list[0 : len(check_list)] #전체 체크 리스트 반환
return check_list[0 : k] # 위의 조건문에 해당되지 않으면 주어준 숫자만큼 슬라이싱 후 반환
- 주어진 테스트 케이스에 대해서는 문제없이 통과 완료되었다.
- 느낀점
- if 조건문에 대해서 한 줄 쓰기에 익숙해지도록 자주 사용해보자.
- repl.it 자체의 로직 체크와 주어진 테스트 케이스가 조금 단순한 것 같다. 같은 문제가 다른 사이트에 있다고 들었는데, 더 다양한 테스트 케이스와 실행시간 같은 다른 요소에 대해서도 확인해보면 좋을 것 같다.
- 모델 케이스
def top_k(nums, k):
count = {}
for n in nums:
count[n] = count.get(n, 0) + 1
bucket = [[] for _ in range(len(nums)+1)]
for n, freq in count.items():
bucket[freq].append(n)
ret = []
for n_list in bucket[::-1]:
if n_list:
ret.extend(n_list)
if len(ret) == k:
return ret
- 모델 케이스를 볼 때 빈 딕셔너리에 키를 넣을 때 굳이 if 조건문을 사용할 필요는 없었던 것 같다.
- 딕셔너리를 반복문에 사용할 때 키와 값을 동시에 사용할 수 있다는 점을 다시 한번 확인했다.
- extend() 메소드에 대해서 알게 되었다.
- append() 메소드와 비슷하게 리스트 뒤에 데이터를 추가하는 메소드이지만 extend()는 iterable 한 객체의 경우 요소 하나하나를 각각 추가해준다.
- append() 메소드의 경우는 각각의 요소가 아닌 객체 전체를 하나의 요소로 추가한다.
2주차 5일째 - 숫자 배열의 각각의 값들을 높이로 사용해서 계산할 수 있는 가장 넓은 사각형의 넓이를 반환하기
- 조건 1 - 입력받는 배열은 숫자로 이루어져 있으며, 각각의 값을 높이로서 사용한다. 배열은 적어도 2개 이상의 요소로 구성됨
- 조건 2 - 배열속 요소의 사이를 가로로서 사용한다.
- 조건의 예 - 첫번째 요소와 세번째 요소를 사용한 사각형이라면 요소들 중 작은 값을 높이로, 각 요소들의 인덱스를 활용해서 2를 가로로 사용하여 넓이를 계산한다.
- 생각한 처리 로직
- 2중 for 반복문을 사용한다.
- range를 사용한다. 단, 범위는 배열의 길이보다 1 작게 지정한다. 사각형을 구성하기 위해서는 2개의 높이를 사용해야 한다.
- 외부 for 반복문의 조건을 위와 같이 적용
- 내부 for 반복문의 조건은 외부 for 반복문의 값에 1을 더한 수부터 배열의 끝까지를 범위로 정한다.
- 2중 for 반복문의 내부 for 반복문에서 두개의 요소를 사용해서 작은 값을 높이로, 내부 for 반복문의 반복횟수를 가로로 사용해서 사각형의 넓이를 구한다.
- 결과를 리스트에 추가
- 모든 경우의 수를 도출한 리스트를 내림차순으로 정렬한다.
- 결과 리스트에서 max() 메소드를 사용한 결과를 반환
- 2중 for 반복문을 사용한다.
- 로직 코딩
###############################################################
# 2주차 5일째
def get_max_area(height):
result_list = [] # 넓이를 저장할 리스트 선언
for i in range(len(height) - 1): # 배열 길이 -1 만큼 범위를 지정
target_length = 1 # 가로 길이로 사용할 반복횟수 카운트를 위한 변수
for j in range(i + 1, len(height)): # 내부 for 반복문은 외부 for 반복문의 인덱스를 기준으로 1을 더한 지점부터 끝까지를 범위로 지정
target_height = height[i] # 일단 높이로 사용할 값을 저장
if target_height > height[j]: # 다른 요소와 비교
target_height = height[j] # 작을 경우 높이로 사용
result_list.append(target_height * target_length) # 사각형 넓이를 계산 후 리스트에 추가
target_length += 1 # 반복횟수 1 누적
return max(result_list) # 리스트의 요소 중 가장 큰 값을 반환
- 주어진 테스트 케이스에 대해서는 문제없이 통과 완료되었다.
- 느낀점
- if문 한줄 쓰기를 일부러라도 사용하면서 익숙해지도록 하자.
- 2중 for 반복문을 사용해서 해결은 되었지만 작동시간면에서 손해가 많은 방법이므로 개선방법을 찾아보자.
- 모델 케이스
def get_max_area(height):
l = 0
r = len(height) -1
area = 0
while l < r:
area = max(area, min(height[l],height[r]) * (r - l))
if height[l] < height[r]:
l += 1
else:
r -= 1
return area
- 모델 케이스에 비교해볼 때 넓이 연산 결과를 전부 저장할 필요는 없어보인다.
'wecode > 기타' 카테고리의 다른 글
두번째 웹 프로젝트를 끝냈다. (0) | 2020.09.13 |
---|---|
첫번째 웹 프로젝트를 끝냈다 (0) | 2020.08.30 |
위코드 Codekata - 2 (0) | 2020.08.30 |