DFS나 BFS를 풀 때 그래프를 만들어 풀면 수월한 문제들이 있다

예를 들어 ( 프로그래머스 여행경로 문제  )

 

코딩테스트 연습 - 여행경로

[["ICN", "SFO"], ["ICN", "ATL"], ["SFO", "ATL"], ["ATL", "ICN"], ["ATL","SFO"]] ["ICN", "ATL", "ICN", "SFO", "ATL", "SFO"]

programmers.co.kr

  • 항공권 정보가 담긴 2차원 배열 tickets가 매개변수로 주어질 때
  • tickets의 각 행 [a, b]는 a 공항에서 b 공항으로 가는 항공권이 있다는 의미이다
[["ICN", "SFO"], 
["ICN", "ATL"], 
["SFO", "ATL"], 
["ATL", "ICN"], 
["ATL","SFO"]]

 

이를 딕셔너리를 사용하여 그래프를 만들면

  • 첫 번째 방법
routes = {}
for key, value in tickets:
	if key in routes:
		routes[key].append(value)
	else:
		routes[key] = [value]

>>> {'ICN': ['SFO', 'ATL'], 'SFO': ['ATL'], 'ATL': ['ICN', 'SFO']}

 

  • defaultdict()를 활용한 이보다 간편한 두 번째 방법 -> 키가 있는지 확인할 필요가 없다
from collections import defaultdict

routes = defaultdict(list)
for key, value in tickets:
	routes[key].append(value)
   
>>> defaultdict(<class 'list'>, {'ICN': ['SFO', 'ATL'], 'SFO': ['ATL'], 'ATL': ['ICN', 'SFO']})

 

 

+ defaultdict() 활용법

  • defaultdict()는 인자로 주어진 객체의 기본값을 딕셔너리 값의 초기값으로 지정할 수 있다.
  • 숫자, 리스트, 셋 등으로 초기화 할 수 있다.
  • 외부 함수이기 때문에 import 해야 됨 -> from collections import defaultdict
  1. 숫자로 초기화 -> 값을 지정하지 않으면 0으로 초기화 ex) 알파벳 횟수 계산
  2. 리스트로 초기화 -> 값을 지정하지 않으면 빈 리스트로 초기화 ex) 그래프 경로, 같은 성을 가진 이름끼리 취합하기 
  3. 셋으로 초기화 -> 값을 지정하지 않으면 빈 리스트로 초기화
# 1번 숫자로 초기화

from collections import defaultdict
int_dict = defaultdict(int)
int_dict
>>> defaultdict(<class 'int'>, {}) # 디폴트값이 int인 딕셔너리

# 값 지정 안하면 0으로 초기화
int_dict['key1']
>>> 0
int_dict
>>> defaultdict(<class 'int'>, {'key1': 0}) 

# 값 지정하면 그 값으로 지정
int_dict['key2'] = 'test'
int_dict
>>> defaultdict(<class 'int'>, {'key1': 0, 'key2': 'test'}) 
# 리스트로 초기화

from collections import defaultdict
list_dict = defaultdict(list)
list_dict
>>> defaultdict(<class 'list'>, {}) # 디폴트값이 list인 딕셔너리

list_dict['key1'] # 값을 지정하지 않으면 빈 리스트로 초기화
>>> []

list_dict['key2'] = 'test' # 값을 지정하면 해당값으로 초기화
list_dict
>>> defaultdict(<class 'list'>, {'key1': [], 'key2': 'test'}) 

( 참고 : 유사 딕셔너리 defaultdict() 활용법 )

반응형

오랜만에 가족 외식으로 양고기를 먹으러 도봉산 양고기를 방문했습니다!

부모님은 양고기를 처음 드셔 보셔서 걱정했는데

잡내도 안나고 맛있어서 두 분 다 좋아하셨어요 👍

( 아빠는 친구분들이랑 또 와야겠다고 저한테 가게 이름을 다시 물어보셨어요ㅋㅋㅋ )

 

주차공간은 협소한편입니다

역에서 얼마 멀지 않으니 걸어오시는 걸 추천드려요

 

들어가는 길이 이뻐요..♥

 

실내와 실외에 모두 테이블이 있어요

저희는 날이 좋아서 실외에서 먹었어요👍

 

여기는 예약석이었는데 이뻐서 다음에는 예약해서 저기서 먹어봐야지 했습니당

 

삼각갈비 3인분, 갈비살 1인분, 메밀막국수 3인분을 시켰습니다

막국수 너무 맛있어요👍 꼭 고기랑 같이 드셔 보세요

( 그런데 홀직원분들이 너무 적으셔서 주문하기가 힘들어요....ㅠㅠ

저까지 정신없는 느낌...

주문도 2번이나 잘못 들어가서 수시로 주문 잘 들어갔는지 확인했습니닼ㅋㅋㅋ )

 

 

기본 상차림으로 미나리 겉절이가 나왔는데 

저희 가족은 미나리 덕후라 잘 먹었습니다ㅋㅋ

삼각갈비와 갈비살

 

갈비살은 잘게 자른 뒤 마늘과 함께 계속 뒤집어주면서 익혀주는 게 중요하다고 해요!!

같이 구운 마늘도 대존맛..

약간 돌돌 돌아가는 양꼬치집 기계가 된 느낌적인 늑끰....

갈비살

 

삼각갈비

 

막국수.. 존맛.... 2인분 시켰는데

다 먹고 하나 더 시켜 먹었어요 👍

( 여기도 미나리가 들어있넹 )

 

나가는데 강아지들이 너무 꿀잠을 자고 있었어요

개팔자가 상팔자....

ㅋㅋㅋㅋㅋㅋㅋㅋ

 

세상에서 젤 귀여운 시고르자브종.....

 

도봉산 양고기 위치

 

네이버 지도

도봉산양고기

map.naver.com

 

반응형

노원 롯데백화점 1층에 쉑쉑버거가 입점했다는 소식을 듣고 먹으러 가봤습니다!

( 강남에 쉑쉑 1호점이 생겼다고 해서 가본 게 엊그제 같은데.. 노원이 15번째라네요.. ㄷㄷ)

점심시간에 가서 웨이팅이 길면 어쩌나 걱정했는데 

생각보다 사람이 없었어요👍

 

 

 

 

 

 

메뉴는 아래와 같습니다

저는 쉑버거 더블, 스모크쉑, 프라이, 바닐라 쉐이크, 커피 쉐이크를 시켰어요

 

 

 

매장은 거리두기 때문에 조금 좁긴한대

야외 테이블이 많아서 자리잡기에 어려움은 없었습니다!

 

 

 

캐찹과 머스터드 마요네즈 등을 가져가는 셀프코너가 있습니다

( 머스터드는 찐 머스터드입니다... 허니 머스터드가 아니에요ㅠㅠ )

※ 마요네즈가 왜 있지 하시는 분들이 계신데

마요네즈 프라이나 버거에 올려먹으면 존맛입니다... 꼭 드셔 보세요 츄륩....❤

 

쉑버거 더블 10.9

 

 

개인적으로 스모크쉑은 조금 짯어요..ㅠ

기본이 젤 맛있는 듯...

 

스모크쉑 싱글 8.9

 

 

맛은 있었지만... 버거라고 하기는 너무 가격이 사악한 편입니닿ㅎㅎㅎ

그래도 한 번쯤은 먹어볼 만할 거 같아요👍

 

노원 쉑쉑버거 위치

쉐이크쉑 노원점 : 네이버

방문자리뷰 3 · ★4.67 · 매일 10:30 - 22:00, 4/2(금) GRAND OPEN

m.place.naver.com

 

반응형

프로그래머스 - 깊이/너비 우선 탐색(DFS/BFS)

# 단어 변환 (Level 3)

  • Point. 그래프 문제인 이유 : 한 개의 알파벳만 달라 다음에 올 수 있는 단어를 방문하여 target값을 찾는다
  • 방문한(pop)한 원소 temp가 방문할 수 있는 값은 temp와 한 개의 알파벳만 다른 words 원소 값이다.
from collections import deque
def solution(begin, target, words):
    answer = 0 # 변환할 수 없는 경우 0 return
    queue = deque()

    for i in words: # 한 개의 알파벳만 다를 경우
        count = 0
        for j in range(len(begin)):
            if begin[j] != i[j]:
                count+=1
        if count == 1:
            queue.append([i,0]) 
            words.remove(i)
    
    while queue: 
        temp, idx = queue.popleft() 
        idx += 1
        if temp == target: # 변환이 가능한 경우 몇단계인지 저장
            answer = idx
        else:
            for i in words:
                count = 0
                for j in range(len(begin)):
                    if temp[j] != i[j]:
                        count+=1
                if count == 1:
                    queue.append([i,idx])
                    words.remove(i)
                    
    return answer

 

# 문자열을 정수로 바꾸기 

def solution(s):
    return int(s)

 

# 자릿수 더하기

  • Point. 문자열로 변환해 한자리씩 들고온 후, 다시 정수형으로 변환해 더해준다
def solution(n):
    answer = 0
    for i in str(n):
        answer+=int(i)

    return answer

 

# 정수 내림차순으로 배치하기

  • Tip. 리스트 합쳐서 하나의 문자열로 바꾸는 함수 : '구분자'.join(리스트) 
def solution(n):
    answer = ""
    n_list = list(str(n))
    n_list.sort(reverse=True)
    
    for i in n_list:
        answer+=i
    return int(answer)

    # return int("".join(n_list))
반응형

프로그래머스 - 깊이/너비 우선 탐색(DFS/BFS)

# 타겟 넘버 (Level2) : 2021.04.07 - [알고리즘] - 20210407_코테공부

# 네트워크 (Level 3) : 2021.02.17 - [알고리즘] - 20210217_코테공부

# 단어 변환 (Level 3) : 2021.04.08 - [알고리즘] - 20210408_코테공부

# 여행경로 (Level 3) : 2021.04.12 - [알고리즘] - [ 프로그래머스 / 파이썬 ] 여행경로 - DFS/BFS

 


 

백준

# 17406 배열 돌리기 4 (골드4) : 2021.02.04 - [알고리즘] - 20210204_코테공부

# 12100 2048(Easy) (골드2) : 2021.01.29 - [알고리즘] - 20210129_코테공부

# 16768 Mooyo Mooyo (골드4) : 2021.01.28 - [알고리즘] - 20210128_코테공부

# 1021 유기농 배추 (실버2) : 2021.01.12 - [알고리즘] - 20210112_코테공부

#

 

+ DFS/BFS Tip.

반응형

문자열 빈출 함수

  • 문자 개수 세기 : 문자열.count('s')
  • 특정 문자 찾기 : 문자열.find('s')
    • 없으면 -1 리턴
  • (접두어)특정 문자로 시작하는지 여부 : 문자열.startswith('ho') ( 참고자료 )
  • (접미어)특정 문자로 끝나는지 여부 : 문자열.endswith('h')
    • 문자열 대신 문자열로 이루어진 tuple을 넣을 수도 있다. (※리스트 안됨)
  • 위치 알려주기2 : 문자열.index('s')
    • 주의 : 없으면 오류 뜸
  • 리스트를 문자열로 합치기 : '구분자'.join(리스트)
  • 문자열 쪼개 리스트 만들기 : 문자열.split()
    • 파라미터를 안쓰면 띄어쓰기, 엔터를 구분하여 나눈다
  • 문자열 치환 : 문자열.replace('a','b') # a를 b로 바꾼다
a = 'hobby'

# 문자열에서 특정 문자의 개수를 리턴
s1 = a.count('b')
print(s1)
>>> 2

# 위치 찾기1
s2 = a.find('b')
print(s2)
>>> 2
s3 = a.find('k')
print(s3)
>>> -1

# 특정 문자로 시작하는지 여부 
ss1 = a.startswith('ho')
print(ss1)
>>> True

# 특정 문자로 시작하는 여부 (여러개)
url = "https://www.naver.com"
url_check = ("http","https")
url.startswith(url)
>>> True

# 특정 문자로 끝나는지 여부
ss2 = a.endswith('h')
print(ss2)
>>> False

# 위치 찾기2
s4 = a.index('b')
print(s4)
>>> 2
a.index('k')
>>> 오류

# 리스트 문자로 합치기
b = ['a', 'b', 'c', 'd', '1', '2', '3']
s5 = "".join(b)
print(s5)
>>> abcd123
s6 = "-".join(b)
print(s6)
>>> a-b-c-d-1-2-3

# 문자열 쪼개기
c = "a b c d e f g"
s7 = s.split()
print(s7)
>>> ['a','b','c','d','e','f','g']
d = "aa.bb.cc.dd.ee.ff.gg"
s8 = s.split('.')
print(s8)
>>> ['aa','bb','cc','dd','ee','ff','gg']

 

+ 리스트 원소 추가, 삭제

  • 원소 추가 : 리스트.append(값)
  • 특정 위치에 원소 추가 : 리스트.insert(인덱스, 값)
  • 여러 원소 추가하기 : 리스트.extend(추가할 리스트)
  • 특정 위치의 원소 삭제 : del 리스트[인덱스]
  • 원소 값 삭제 : 리스트.remove(값)
a = [1, 2, 3]

# 원소 추가
a.append(6)
>>> [1, 2, 3, 6]

# 특정 위치에 원소 추가
a.insert(1, 5)
>>> [1, 5, 2, 3, 6]

# 여러 원소 추가하기
a.extend([4,5,6])
>>> [1, 5, 2, 3, 6, 4, 5, 6]

# 특정 위치의 원소 삭제
del a[1]
>>> [1, 2, 3, 6, 4, 5, 6]

# 원소 값 삭제
a.remove(3)
>>> [1, 2, 6, 4, 5, 6]

 

문자열 정렬

  • 리스트로 변환 후 sort, sorted를 사용하여 정렬한다.
    • list 본체 정렬 : 문자열.sort() # reverse = True 시 내림차순 정렬
    • list 정렬된 결과 반환 : sorted(문자열)
    • list 뒤집기 : 문자열.reverse()
    • 관련 문제 : 문자열 내림차순으로 배치하기  2021.04.07 - [알고리즘] - 20210407_코테공부
 

20210407_코테공부

프로그래머스 - 깊이/너비 우선 탐색(DFS/BFS) # 타겟 넘버 (Level 2) Point. 타겟 넘버가 그래프 문제인 이유 -> 다음 인덱스에 해당하는 numbers 원소를 더하거나 빼 값을 방문한다. 방문한(pop)한 원소 temp

jungeun960.tistory.com

s = "Zbcdefg"
s = list(s)
print(s)
>>> ['Z', 'b', 'c', 'd', 'e', 'f', 'g']

s.sort(reverse = True)
print(s)
>>> ['g', 'f', 'e', 'd', 'c', 'b', 'Z']

a = [1, 10, 5, 7, 6]
a.sort()
a
>>> [1, 5, 6, 7, 10]

y = sorted(a)
y
>>> [1, 5, 6, 7, 10]

a.reverse()
a
>>> [6, 7, 5, 10, 1]

+ 문자열의 길이를 기준으로 정렬 : 문자열.sort(key=lamba x:len(x))

+ 문자열의 n번째 수 기준으로 정렬 : 문자열.sort(key=lambda x:x[n])

+ 다중 조건 정렬 : 문자열.sort(key=lambda x: (x[0],x[1])) // x[0] 기준으로 정렬하고 x[1] 기준으로 정렬

a = [(4,0), (4,3), (4,2), (3,2), (2,1), (1,0)]


# 인자 없이 sorted()를 사용하면 리스트 아이템의 각 요소 순서대로 정렬
# 첫 번째 요소가 같으면 두 번째 요소로 비교
b = sorted(a)
print(b)    
>>> [(1, 0), (2, 1), (3, 2), (4, 0), (4, 2), (4, 3)]


# key인자에 lambda 함수를 넘겨주면 반환값을 가지고 비교해 정렬
# 이 때, key로 전달되지 않은 요소에 대해선 정렬하지 않음
c = sorted(a, key=lambda x : x[0])
print(c)    
>>> [(1, 0), (2, 1), (3, 2), (4, 0), (4, 3), (4, 2)]
d = sorted(a, key=lambda x : x[1])
print(d)    
>>> [(4, 0), (1, 0), (2, 1), (4, 2), (3, 2), (4, 3)]


# 정렬 기준으로 다중 조건을 넘겨줄 수도 있다
# 첫 번째 인자를 기준으로 오름차순 정렬을 먼저 한다.
# 그 결과를 가지고 두 번째 인자를 기준으로 내림차순 정렬(-를 붙이면 내림차순 정렬)
e = sorted(a, key = lambda x : (x[0], -x[1]))
print(e)    
>>> [(1, 0), (2, 1), (3, 2), (4, 3), (4, 2), (4, 0)]
 

20210302_코테공부

프로그래머스 # 가운데 글자 가져오기 def solution(s): answer = '' if len(s)%2 == 1: answer = s[len(s)//2] else: answer = s[len(s)//2-1 : len(s)//2+1 ] return answer # 같은 숫자는 싫어 def solution(ar..

jungeun960.tistory.com

 

대소문자 관리 함수 (upper, lower, isupper, islower)

  • 주어진 문자열의 모든 알파벳을 소문자로 바꾸는 함수 : 문자열.lower()
  • 주어진 문자열의 모든 알파벳을 대문자로 바꾸는 함수 : 문자열.upper()
  • 주어진 문자열의 맨 첫 글자를 대문자로 바꾸는 함수 : 문자열.capitalize()
  • 주어지 문자열에서 알파벳 외의 문자(숫자, 특수문자, 띄어쓰기 등)로 나누어져 있는 첫 글자를 모두 대문자로 바꾸는 함수 : 문자열.title()
  • 소문자 확인 : 문자열.islower() -> True / False로 리턴
  • 대문자 확인 : 문자열.isupper() -> True / False로 리턴

※ capitalize()와 title() 차이 주의!

+ 알파벳/숫자인지 확인하기  -> True / False로 리턴

  • 알파벳인지 확인하기 : 문자열.isalpha()
  • 숫자인지 확인하기 : 문자열.isdigit()
  • 알파벳 또는 숫자인지 확인하기 : 문자열.isalnum() -> 특수문자 있는지 확인
  • ※ 문자열에 공백이 포함되어 있으면 False를 리턴합니다

+ 소문자 / 대문자

  • 'abcdefghijklmnopqrstuvwxyz'
  • 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
a = 'hobby'

# 소문자로 바꾸기
s5 = a.lower()
print(s5)
>>> hobby

C = 'a2b3c4'
# 대문자로 바꾸기
C.upper()
>>> 'A2B3C4'

# 주어진 문자열의 맨 첫 글자를 대문자로 바꾸는 함수
C.capitalize()
>>> 'A2b3c4'

# 주어지 문자열에서 알파벳 외의 문자(숫자, 특수문자, 띄어쓰기 등)로 
# 나누어져 있는 첫 글자를 모두 대문자로 바꾸는 함수 : 문자열.title()
C.title()
>>> 'A2B3B4'

# 소문자 확인
a.islower()
>>> True

# 대문자 확인
a.isupper()
>>> False
# 알파벳인지 확인하기
Ex1 = 'ABC'
print(Ex1.isalpha())
>>> True
Ex2 = "100Appia"
print(Ex2.isalpha())
>>> False

# 숫자인지 확인하기
Ex1 = '123456'
print(Ex1.isdigit())
>>> True
Ex2 = "R4R3"
print(Ex2.isdigit())
>>> False
 

# 알파벳 혹은 숫자인지 확인하기
Ex1 = 'Hello3'
print(Ex1.isalnum())
>>> True
Ex2 = "1.Where" 
print(Ex2.isalnum())
>>> False
반응형

프로그래머스 - 깊이/너비 우선 탐색(DFS/BFS)

# 타겟 넘버 (Level 2) 

  • Point. 타겟 넘버가 그래프 문제인 이유 -> 다음 인덱스에 해당하는 numbers 원소를 더하거나 빼 값을 방문한다.
  • 방문한(pop)한 원소 temp가 방문할 수 있는 값은 temp 다음 인덱스에 위치한 numbers원소를 +또는 - 한 값이다.
from collections import deque
def solution(numbers, target):
    answer = 0
    queue = deque()
    n = len(numbers)
    queue.append([numbers[0],0])
    queue.append([-1*numbers[0],0]) 
    #print(queue)
    while queue: # queue가 빌때가지 반복
        temp, idx = queue.popleft() 
        idx += 1
        if idx < n:
            queue.append([temp+numbers[idx], idx])
            queue.append([temp-numbers[idx], idx])
            #print(queue)
        else:
            #print(temp)
            #print(queue)
            if temp == target:
                answer += 1
                #print("count up")
        
    return answer

queue 생성 과정
pop한 temp가 마지막 원소이고 값이 target과 같다면 answer +=1
queue값이 비어야 끝

※ 참고 포스팅 : 프로그래머스 level2 타겟넘버(BFS/DFS)

 


 

# 문자열 내 p와 y의 개수 

  • 문자열 소문자로 바꾸는 함수 : lower()
  • 문자열의 특정 문자 개수 세는 함수 : count()
def solution(s):
    if s.lower().count('p') == s.lower().count('y'):
        return True
    else :
        return False

 

# 문자열 내림차순으로 배치하기

  • 문자열 리스트로 저장 후 정렬하기 sort 소문자 -> 대문자 순으로 정렬해줌
def solution(s):
    answer = ''
    s = list(s)
    s.sort(reverse = True)

    for i in s:
        answer += i
    return answer

 

# 문자열 다루기 기본 

  • 숫자인지 판별하는 함수 : isdigit()
def solution(s):
    if s.isdigit() and (len(s) == 4 or len(s) == 6):
        return True
    else:
        return False

 

# 2016년 

  • datetime 모듈을 사용하여 날짜의 요일을 받아온다 
  • 날짜 생성하기 : datetime(년, 월, 일, 시, 분, 초, 밀리 초)
  • 요일 반환 (0:월, 1:화, 2:수, 3:목, 4:금, 5:토, 6:일) : weekday()
import datetime as dt
def solution(a, b):
    answer = ''
    week_list = ['MON','TUE','WED','THU','FRI','SAT','SUN']
    x = dt.datetime(2016, a, b,1,1,1)
    answer = week_list[x.weekday()]

    return answer

 

+ 다른 사람 풀이

def getDayName(a,b):
    months = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
    days = ['FRI', 'SAT', 'SUN', 'MON', 'TUE', 'WED', 'THU']
    return days[(sum(months[:a-1])+b-1)%7]
반응형

'알고리즘 > programmers' 카테고리의 다른 글

[ 프로그래머스 / 파이썬 ] 여행경로 - DFS/BFS  (0) 2021.04.12
20210408_코테공부  (0) 2021.04.08
[ 프로그래머스 / 파이썬 ] 주식가격  (0) 2021.03.31
20210319_코테공부  (0) 2021.03.19
20210316_코테공부  (0) 2021.03.16

 

철길 산책을 하다가 길가다 본 와플집이 생각나서 방문해 봤습니다

( 저녁 7시쯤 가면 매번 재료 소진으로 닫혀있는 걸 봐서 낮에 가봤어요! )

벚꽃이 이쁘게 핀 공릉 철길

 

길가다가 멈춰서게 만드는 비쥬얼.... 츄룹

 

 

 

가격은 저렴한 편인것 같아요

저는 초코, 크림치즈, 딸기, 블루베리 와플을 먹어봤는데 다 맛있었어요.. 츄륩

 

테이블은 3~4개 정도 있습니다

저는 집에 가서 먹으려고 포장을 했는데 4개를 사면 뽀짝한 박스에 담아주십니다

그 이하면 종이 봉지에 담아주세요

( 집 가서 맛있게 먹으려면 에어 프라이기 170도에 1 분해서 먹으면 맛있다고 알려주셨어요!!

바로 드실 분은 데워주십니다 )

 

영스테이 위치 :  http://naver.me/xlWv6gQk

 

영스테이 : 네이버

방문자리뷰 102 · ★4.65 · 매일 12:00 - 21:00, 매주 화요일 휴무입니다. (준비된 제품 모두 소진 시 조기마감합니다)

m.place.naver.com

 

반응형

+ Recent posts