코딩 공부/Leetcode

[Python] 2381. Shifting Letters II

일하는 공학도 2025. 1. 9. 16:51
728x90

난이도 : Medium

 

  1. s라는 문자가 있고
  2. shifts 속의 하위 리스트를 기반으로 알파벳을 변경하는 조건은 하위 리스트 [a, b, 0 or 1]
    1. a부터 b까지의 범위 내에 있는 알파벳 설정
    2. 하위 리스트의 3번째 요소에 '0'이 나오면 1씩 뒤로, '1'이 나오면 1씩 앞으로 간다.
  3. shifts의 연산을 전부 다 거친 결과를 return

이에 따른 처음 고안한 코드는 다음과 같다.

class Solution(object):
    def shiftingLetters(self, s, shifts):
        """
        :type s: str
        :type shifts: List[List[int]]
        :rtype: str
        """
        let = list(s)
        n = len(let)
        ch = [ord(x) for x in let]
        tem = [0 for i in range(n)]

        for i, val in enumerate(shifts):
            if val[2] == 0:
                for j in range(val[0],val[1]+1):
                    tem[j] = tem[j] -1
            else:
                for j in range(val[0],val[1]+1):
                    tem[j] = tem[j] +1
        
        ans=[]
        cha = [ch[i]+tem[i] for i in range(n)]
        for num in cha:
            if num < 97:
                num += 26
                ans.append(chr(num))
            elif num > 122:
                num -=26
                ans.append(chr(num))
            else:
                ans.append(chr(num))
        return "".join(ans)
  1. 문자 s를 리스트로 만든 뒤 ord(x)로 숫자 형태로 변경
  2. shifts 내 하위 리스트의 계산을 전부 정리하여, 최종적으로 어떻게 바뀌어야 할지에 대한 리스트 tem을 제작
  3. a부터 z까지의 범위에서 벗어나는 경우는 26씩 더하거나 빼서, 알파벳 범위에 있도록 계산
  4. chr(x)로 알파벳으로 변경 후 리스트를 하나의 단어로 return

으로 생각을 했으나..

이런 굉장한 input에는 runtime error가 뜨기 시작했다.. OMG

 

그래서 2차로 최대한 다음과 같이 간소화를 시켰다.

class Solution(object):
    def shiftingLetters(self, s, shifts):
        """
        :type s: str
        :type shifts: List[List[int]]
        :rtype: str
        """
        n = list(s)
        s = [0]*len(n)

        for start, end, action in shifts:
            for i in range(start, end+1):
                if action == 0:
                    s[i] -= 1
                else:
                    s[i] += 1
        
        for i in range(len(n)):
            n[i] = chr((ord(n[i])-ord('a')+s[i])%26+ord('a'))
        return "".join(n)

 

  1. shifts의 하위 리스트를 start, end, action 등으로 직접 불러오기
  2. 리스트 s로 위치변화 리스트 제작
  3. 아스키코드로 바로 바꾸는 계산법

결과는 Time limit 초과,

 

결국 solution을 참고했다...

class Solution(object):
    def shiftingLetters(self, s, shifts):
        """
        :type s: str
        :type shifts: List[List[int]]
        :rtype: str
        """
        n = len(s)
        let = [0]*n

        # Process each shift operation
        for start, end, action in shifts:
            if action == 1:  # If direction is forward (1)
                let[start] += 1  # Increment at the start index
                if end + 1 < n:
                    let[end + 1] -= 1  # Decrement at the end+1 index
            else:  # If direction is backward (0)
                let[start] -= 1  # Decrement at the start index
                if end + 1 < n:
                    let[end + 1] += 1  # Increment at the end+1 index

        result = list(s)
        num = 0

        # Apply the shifts to the string
        for i in range(n):
            num = (num + let[i]) % 26  # Update cumulative shifts, keeping within the alphabet range
            if num < 0:
                num += 26  # Ensure non-negative shifts

            shifted_char = chr((ord(s[i]) - ord("a") + num) % 26 + ord("a"))
            result[i] = shifted_char

        return "".join(result)

내부에 for 문 대신에 if를 이중으로 사용하여 time limit을 줄일 수 있었나보다.

쉽지않은 문제였다..

728x90