일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 색연필
- 미켈란젤로
- leetcode
- Python
- 코딩테스트
- Kriss 재택
- react
- clean code
- 클린 코드
- 토익 환급
- 연필
- 파이썬
- 알고리즘
- 연필소묘
- PrivateRouter
- 코딩
- 취미
- 테스팅 자격증
- IT 자격증
- csts
- 재택근무
- 웹개발
- 코드잇
- 프로그래머스
- 다비드상
- 그림
- KSTQB
- 프로그래밍
- IT자격증
- 소묘
- Today
- Total
글모음
[프로그래머스] Python 알고리즘 스터디 - 2주차 Stack & Hash 본문
2주 차
Stack, Hash
< 1. 나머지 한 점 >
def solution(coordinates):
X_set = set()
Y_set = set()
for coordinate in coordinates:
X, Y = coordinate
if X not in X_set :
X_set.add(X)
else:
X_set.remove(X)
if Y not in Y_set :
Y_set.add(Y)
else: Y_set.remove(Y)
return list(X_set) + list(Y_set)
짝이 되지 않는 좌표가 나머지 한 점이다.
그런 좌표들을 합쳐서 return 해주면 되는 간단한 문제다.
< 2. 운송 트럭 >
def solution(max_weight, specs, names):
spec_info = {}
for spec in specs:
name, weight = spec
spec_info[name] = int(weight)
cur_weight, cnt = 0, 1
for name in names:
if cur_weight + spec_info[name] <= max_weight:
cur_weight += spec_info[name]
else:
cnt += 1
cur_weight = spec_info[name]
return cnt
< 3. 빙고 >
1) 첫 시도
def solution(board, nums):
nums = set(nums)
for row in range(len(board)):
for col in range(len(board)):
if board[row][col] in nums:
board[row][col] = 0
# 가로 : sum(board[i])
# 세로 : sum(board[i~len(board)][0])
# 대각선: sum(board[i,i])
# 대각선_2 : sum(board[len(board)-i][len(board)-i])
cnt = 0
diag_1, diag_2 = 0, 0
for i in range(len(board)):
horizontal, vertical = 0, 0
# 가로, 세로
for j in range(len(board)):
vertical += board[i][j]
horizontal += board[j][i]
# 대각선
diag_1 += board[i][i]
diag_2 += board[i][len(board)-1-i]
if not vertical : cnt += 1
if not horizontal : cnt += 1
if not diag_1 : cnt += 1
if not diag_2 : cnt += 1
return cnt
빙고 문제는 풀리긴 풀리는데 깔끔하게 짜기가 어려웠다.
2) 리뷰받은 뒤 수정
def solution(board, nums):
N = len(board)
nums = set(nums)
answer = 0
for i in range(N):
for j in range(N):
if board[i][j] in nums:
board[i][j] = 0
answer += len([i for i in board if sum(i) == 0])
answer += len([i for i in zip(*board) if sum(i) == 0])
answer += int(sum(board[i][i] for i in range(N)) == 0)
answer += int(sum(board[N - 1 - i][i] for i in range(N)) == 0)
return answer
column을 간단하게 출력하려면 numpy 라이브러리를 써야만 되는 줄 알았는데
zip(*배열 이름) <= 이런 식으로 하면 라이브러리를 쓰지 않고도 가져올 수 있다는 걸 새로 알았다.
< 4. 방문 길이 >
1. 나의 코드
def solution(ways):
move = {'U' : [0, 1], 'D' : [0, -1], 'R' : [1, 0], 'L' : [-1, 0]}
cur_pos = (0, 0)
visited_paths = set()
limit = list(range(-5, 5+1))
for way in ways:
x, y = move[way]
new_pos = (cur_pos[0] + x, cur_pos[1] + y)
# 좌표 범위에 있는지 체크
if new_pos[0] not in limit or new_pos[1] not in limit: continue
# 이미 왔었던 좌표인지 체크
if new_pos not in visited_paths:
visited_paths.add((*cur_pos, *new_pos))
visited_paths.add((*new_pos, *cur_pos))
cur_pos = new_pos
return len(visited_paths) // 2
2. 피드백받은 부분
0 <= new_pos[0] < n
x, y좌표의 범위 체크를 할 때 이런 식 말고, limit라는 배열을 만들어서 하는 게 더 깔끔해 보여서 배열에서 In을 통해 검색으로 range 체크를 했는데 배열보다는 0 <= x < n 이런 식으로 하는 게 효율성이 더 좋다는 이야기를 들었다.
< 5. 짝지어 제거하기 >
1. 코드 리뷰 전
from collections import deque
def solution(strings):
if len(set(list(strings))) == 1: return 0
stack = deque([])
for letter in strings:
if not stack or letter != stack[-1]: stack.append(letter)
elif letter == stack[-1]: stack.pop()
return int(len(stack) == False)
2. 코드 리뷰
정답을 return 하는 마지막 부분에서 피드백을 받았다.
약간의 버릇으로 False는 0이나 마찬가지라는 생각으로 문제 풀 때나 코드 짤 때 int랑 바로 비교하고 그랬는데 주의해야겠다.
3. 수정한 코드
from collections import deque
def solution(strings):
if len(set(list(strings))) == 1: return 0
stack = deque([])
for letter in strings:
if not stack or letter != stack[-1]: stack.append(letter)
elif letter == stack[-1]: stack.pop()
return int(len(stack) == 0)
False(Bool) 형과 비교하는걸 0과 비교하는 걸로 바꿔줬다.
python에서는 바로 비교하는 게 상관없지만 다른 언어를 사용할 때는 예외가 있을 수도 있으니까 앞으로는 신경 써야겠다.
< 6. 사전 순 부분 문자열 >
1. 수정 전
def solution(strings):
ans = []
for letter in strings:
while ans and ord(ans[-1]) < ord(letter):
ans.pop()
ans.append(letter)
return ''.join(ans)
2. 피드백 수정 후
def solution(strings):
ans = []
for letter in strings:
while ans and ans[-1] < letter:
ans.pop()
ans.append(letter)
return ''.join(ans)
Python에서는 문자열끼리 비교할 때 굳이 ord를 사용해 형 변환하지 않아도 비교가 되기 때문에 ord는 생략해도 된다는 피드백을 받았다.
< 후기 >
2주 차는 Stack과 Hash 알고리즘 문제를 풀었다.
Stack 문제는 많이 익숙하지만 Hash 같은 경우는 생소했는데, 스터디 참여 전 스터디 커리큘럼을 봤을 때 Hash 문제는 다른 알고리즘에 비해서 많이 풀어보지 않았기 때문에 혹시라도 막힐까 봐 미리 공부를 많이 해뒀다.
정리하자면 Hash는 O(1) 시간 복잡도 만에 검색이 가능한 빠른 성능 덕분에 데이터 베이스나 네트워크 라우터에서도 유용하게 쓰인다.
알고리즘 문제를 풀 때는 특별한 건 없다.
파이썬으로 설명하자면, 특별히 따로 구현하는 건 아니고 Dictionary나 Set을 사용해 검색할 내용을 담는다.(방문한 좌표 확인, 데이터 유무, 일치 확인 등등..) O(1) 시간 안에 탐색이 가능하기 때문에 효율성이 중요한 문제에서 사용한다.
같은 문제를 list로도 풀 수 있지만 list의 검색(in)은 O(N)이기 때문에 Hash의 O(1)과 비교하면 시간이 많이 걸린다. 데이터가 작은 경우엔 괜찮겠지만, 큰 경우라면 시간이 엄청나게 차이 난다.
Hash는 미리 공부한 거에 비해서 특별한 건 없어서 좀 허무하긴 했다 ㅋㅋ
알고리즘 코드 짤 때 list에서 in으로 검색을 많이 했는데, 효율성을 위해 list보다는 set이나 dictionary를 사용해야겠다.
'알고리즘 > 프로그래머스' 카테고리의 다른 글
[프로그래머스] Python 알고리즘 스터디 - 4주차 Sorting & Dynamic Programming (0) | 2022.05.30 |
---|---|
[프로그래머스] Python 알고리즘 스터디 - 3주차 Searching (0) | 2022.05.30 |
[프로그래머스] Python 알고리즘 스터디 - 1주차 Queue & Heap (0) | 2022.05.30 |
[프로그래머스] 코딩 테스트 알고리즘 스터디(Python) 참여 후기 (9기) (0) | 2022.05.29 |
[프로그래머스] 폰켓몬 [ Python, level1 ] (0) | 2021.07.21 |