0318 TIL

looggi·2023년 3월 18일
0

TILs

목록 보기
39/114
post-thumbnail

프로그래머스 문제 풀기

➡️ 문자열 나누기

def solution(s):
    cnt=0
    dif,same=0,1
    stack=[s[0]]
    while len(s)>1 and same+dif<len(s):
        if stack[-1]!=s[same+dif]:
            dif+=1
        else:
            same+=1
        if dif==same:
            cnt+=1
            s=s[same*2:]
            if s:
                stack.append(s[0])
            else:
                return cnt # break
            dif,same=0,1
    if len(s)>=1:
        cnt+=1
    return cnt

총 분리된 문자열 갯수, 비교대상과 같은 문자의 갯수, 다른 문자의 갯수를 정의하고
초기 스택에는 문자열의 첫번째 글자가 비교 대상으로 들어간다

while문에서
첫번째 조건은 s의 길이가 최소 2는 되어야 비교가 가능하기때문에 들어갔고
두번째 조건은 그 다음 if문에서 인덱스 에러를 방지하기 위해서 넣었다
첫번째 조건문을 만족하면 계속 s가 리셋돼서 s[same]이랑만 비교해도 되지만

같은 문자가 반복해서 나오다가 다른 문자가 나오는 경우 s[same]과 비교하면 계속 같은 문자와 비교하는 것이 되므로 s[same+dif]의 문자와 비교해야한다

same과 dif값이 같아지는 경우 문자열 분리가 일어나므로 cnt+=1을 해주고 s를 슬라이싱한 값으로 바꿔준다
이후 stack에 다시 초기값을 넣어줘아햐는데 s가 빈 문자열일 경우 인덱스에러가 발생하므로 if문으로 다시 나눠줬다. 빈 문자열이란 얘기는 더이상 비교할 게 남아있지 않은 것이므로 cnt를 그대로 리턴해준다 break 로 while 문을 탈출한다 → return/ else문이 없는 쪽이 더 빠르다 마지막 if문에서 len을 계산하지 않아도 돼서 그런듯?
dif와 same도 다시 초기화해준다

마지막으로 while문 밖에서 s의 길이가 1이상일 경우 비교대상의 문자가 더이상 없는 경우가 되므로 깍두기처리해준다

자잘하게 조건을 계속 달아줘서 코드가 좀 지저분해진 것 같다 ㅠㅠ

➡️ 문자열 나누기 다른 사람꺼

def solution(s):
    answer = 0
    same,dif=0,0
    for letter in s:
        if same==dif:
            answer+=1
            std=letter
        if letter==std:
            same+=1
        else:
            dif+=1
    return answer

진짜 너무 간단해서 화가 난다 ㅋㅋㅋ
s의 각 요소들에 대해서만 반복되기때문에 인덱스에러가 나지 않고 루프를 돌 때마다 글자가 계속 바뀌고 std는 첫번째 조건을 만족할 때만 값이 들어가기때문에 std와 letter의 인덱스를 따로 신경써줄 필요가 없다

for문의 첫번째 조건문에서 same과 dif가 모두 0으로 같을 때도 answer+=1이 되는데 이후에 s가 분리되지 않고 끝나는 경우마지막 값까지 딱 맞게 분리되는 경우 모두 마지막에는 answer+=1을 해줄 수가 없어서(루프가 끝났으니까) 상관이 없다 이 부분이 진짜 핵심인 것 같다 어떻게 마지막에 계산할 수 없는 걸 처음에 생각해서 앞에다가 써도 된다고 생각했을까??

첫번째 if문이 실행되고 난 이후에는 무조건 letter==std이므로 same을 1로 초기화해준 아이디어랑 같은 셈이다

➡️ 둘만의 암호

def solution(s, skip, index):
    ans=''
    for letter in s:
        cnt=0
        rl=[chr((ord(letter)-ord('a')+x)%26+ord('a')) for x in range(1,index+1)]
        for idx in rl:
            if idx in skip:
                cnt+=1
        print(cnt)
        ans+=chr(((ord(letter)-ord('a')+(index+cnt))%26)+ord('a'))
    return ans

처음에 문제를 봤을 땐 skip의 요소가 s의 letter에서 index만큼 건너뛰는 리스트(rl)에 포함되어있으면 그만큼 cnt를 증가시키고 cnt만큼 더 건너뛰면 되겠다고 생각했다
그런데 cnt만큼 더 건너뛴 문자가 skip에 또 포함될 경우 다시 그 문자를 검사해야하는 문제가 생긴다
그러면 하나의 문자에 대해서 수많은 배열(rl)을 만들어봐야해서 너무 효율성이 떨어진다.

아래와 같이 애초에 skip에 해당하는 문자가 빠진 알파벳리스트를 만들어서 문제를 풀었다

def solution(s, skip, index):
    ans=''
    abc=[chr(x) for x in range(ord('a'),ord('z')+1) if chr(x) not in skip]
    for letter in s:
        ans+=abc[(abc.index(letter)+index)%len(abc)]
    return ans

🥱 containment를 문제 풀 때 자주 사용하는데, 이게 생각보다 반례가 많이 발생해서 다르게 풀이하는 방법을 생각해봐야겠다

profile
looooggi

0개의 댓글