제이드Jade 2022. 2. 13. 17:04

1. 전화번호부 목록

https://programmers.co.kr/learn/courses/30/lessons/42577

더보기
def solution(phone_book):
    p_set=set()
    len_s=set()
    phone_book.sort(key=len)
    
    for phone in phone_book:
        for l in len_s:
            if phone[:l] in p_set:
                return False
        
        p_set.add(phone)
        len_s.add(len(phone))
    
    return True

#난 set을 이용해 풀었지만, 문자열의 startswith를 쓰는 방법과 문자열의 한글자씩 늘려가며 해쉬에 있는지 확인하는 방법도 있다

 

 

2. 멀쩡한 사각형

https://programmers.co.kr/learn/courses/30/lessons/62048

더보기
def gcd(a,b):
    if a>b:
        a,b=b,a
    
    if a==0:
        return b
    
    return gcd(a,b%a)

def solution(w,h): 
    wh_gcd=gcd(w,h)
    answer=w*h-((w//wh_gcd+h//wh_gcd)-1)*wh_gcd     # 분배해서 -w+h+gcd 해줘도 됨
    
    return answer

# 참고 풀이 https://leedakyeong.tistory.com/entry/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%A8%B8%EC%8A%A4-%EB%A9%80%EC%A9%A1%ED%95%9C-%EC%82%AC%EA%B0%81%ED%98%95-in-python
# 잘 보면 대각선이 지나가는 길마다 작은 블럭들이 반복적으로 생김, 이 것은 w,h의 최대공약수 만큼 있다.
# 핵심은, 전체크기에서 가로+세로만큼 지나가므로 이걸 빼주고 각 블럭마다 중복되어 빼지는 것이 있으므로 블럭 개수를 더한다.
# 결국 w*h-(w+h)+gcd(w,h)

 

 

3. 다음 큰 숫자

https://programmers.co.kr/learn/courses/30/lessons/12911

더보기
def solution(n):
    count_1=bin(n).count('1')
    i=n+1
    while bin(i).count('1')!=count_1:
        i+=1

    return i
    
 # 당연히 브루트포스는 시간복잡도에서 걸릴줄 알고 시도조차 안했는데 이게 되다니.. 허무

 

 

 

4. 큰 수 만들기

https://programmers.co.kr/learn/courses/30/lessons/42883

더보기

#스택을 이용해서 O(n)으로 만들어보자

def solution(number, k):
    stack=[]
    for i,n in enumerate(number):
        while k>0 and stack and stack[-1]<n:
            stack.pop()
            k-=1
        if k==0:
            stack.extend(number[i:])
            break
        stack.append(n)

    return ''.join(stack[:-k]) if k else ''.join(stack) 


#내 처음 풀이 -> 길이가 채워질때까지 max를 매번 구함(시간초과)
# def solution(number, k):
#     begin,end=0,k+1
#     answer=""

#     while len(answer)<len(number)-k and end-begin>1:
#         idx,val=max(enumerate(number[begin:end]),key=lambda x:x[1])
#         answer+=val
#         begin+=idx+1
#         end+=1
#     if len(answer)<len(number)-k:
#         answer+=number[begin:]
    
#     return answer

    #수가 내림차순으로 되어있으면 pop할 기회가 없어 k가 0이상인 상태에서 빠져나오게 된다.
    #이럴땐 뒤에 원소 k개를 뺀다.

 

 

5. 2개 이하로 다른 비트

https://programmers.co.kr/learn/courses/30/lessons/77885#

더보기
def solution(numbers):
    answer=[]
    for n in numbers:		#일부 테케에서 n을 int형으로 바꿔줘야 런타임 오류가 안나게 바뀜;
        bin_n=list('0'+bin(int(n))[2:])		
        #0이 없는 경우를 대비해 맨 첫비트에 0을 붙여주고 비트를 수월하게 변경하기 위해 리스트로 변환
        idx0=''.join(bin_n).rfind('0')		#rfind는 문자에서 오른쪽부터 찾아줌
        if idx0==len(bin_n)-1: #제일 마지막으로 나오는 0이 맨끝(=짝수)
            answer.append(n+1)
        else:
            bin_n[idx0],bin_n[idx0+1]='1','0'
            answer.append(int(''.join(bin_n),2))
        
    return answer

 

 

6. 피로도

https://programmers.co.kr/learn/courses/30/lessons/87946#

더보기
def solution(k, dungeons):
    answer=[]
    
    def dfs(dungeons,cur,count):
        answer.append(count)
        for i,(need,use) in enumerate(dungeons):
            if need<=cur:
                dfs(dungeons[:i]+dungeons[i+1:],cur-use,count+1)
        
    dfs(dungeons,k,0)
    return max(answer)

# 순열로 모든 경우의 수의 순서로 구해보고 싶다 => dfs 사용!! (반복문+재귀)
# 중첩함수는 바깥의 변수를 마음껏 쓸수는 있지만 재할당 할 수는 없다. => 리스트로 함..
# (첫번째 방법)dfs에서 간 표시를 하고 돌아와서 복구하는 식 -> (2번째 방법)해당 원소를 뺀 리스트를 넘겨줌