LeetCode발행일 2025. 3. 28.원본 https://blog.naver.com/jword_/223813498342 ↗

순열 알고리즘 2. 가능한 모든 순열 찾기

순열 알고리즘 2. 가능한 모든 순열 찾기 — #LeetCode #개발자의도구들 only 파이썬 목표 참고 : 여기 전략 생각하기 ❌❌❌ 실패 time limi Exceed...

#LeetCode#Naver Blog

#LeetCode #개발자의도구들

​

​

  • only 파이썬
  • 목표 참고 : 여기

전략 생각하기

LeetCode(medium 46. Permutations) 80%

text 코드 예제
                                    ⚠️ n : 1..6

✅ next permutations에서 사용한 알고리즘을 전체 적을 사용한다.
>>> 역으로 조회하여 처음으로 감소되는 구간을 찾고
    >>> pivot
>>> 그 위치로부터 가장 큰 값을 찾아서 바꿔주고
>>> pivot 이후부터 reverse() 해준다.
python 코드 예제
                                    class Solution(object):
    def permute(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        result = []

        def find_next(arr):
            n = len(arr)
            pivot = 99999

            # set pivot
            for i in range(n- 1, 0, -1):
                if arr[i-1] < arr[i]:
                    pivot = arr[i-1]

            # if pivot = 99999
            # means end !
            if pivot == 99999:
                return [-100]

            #find next value ⌚O(n)
            next_min = 999999
            target_idx = 99999
            for i in range(pivot + 1, n):
                next_min = min(next_min, arr[i])

            if target_idx == 99999:
                target_idx = n - 1

            # swap
            arr[pivot], arr[target_idx] = arr[target_idx], arr[pivot]

            # reverse idx > pivot
            start = pivot + 1
            end = n - 1
            while start <= end: ⌚O(n)
                arr[start] = arr[end]
                start += 1
                end -= 1

            return arr

        while 1:
            next_per = find_next(nums)
            result.append(next_per)
            if next_per == [-100]: ⌚ exponential ❌❌ ➡️ Factorial!
                break

        return result
  • ❌❌❌ 실패
  • time limi Exceed error
  • t: O(n) \* exponential
  • 순열은 기본적으로 exponential이긴 하다. ❌❌❌❌
  • >>> exponential이 아니라 factiorial이다
  • 거기에 다음 순열 찾는 알고리즘이 O(n)이라 비효율적 구조가 발생
text 코드 예제
                                    🤔 그냥 n!로 구현해보자.

2차시도

text 코드 예제
                                    🖊️ 논리를 수정하자

✅ DFS로 dictioanry와 arr를 넘겨주어 크기가 n이 되는 순간 return한다.

✅ 모든 순간에서 dictioanry를 참고하여 가능한 모든 후보들을 하나씩 넣는다.
python 코드 예제
                                    import copy
class Solution(object):
    def permute(self, nums):
        """
        :type nums: List[int]
        :rtype: List[List[int]]
        """
        result = []

        def dfs(comb, candidate): # []. {}
            if len(comb) == len(nums):
                result.append(comb)
                return

            for key in candidate:
                if candidate[key] == 0:
                    continue
                tmp = comb[::]
                tmp.append(key)

                c_candidate = copy.copy(candidate)
                c_candidate[key] = 0

                dfs(tmp, c_candidate)

        first_candidate = {}
        for num in nums:
            first_candidate[num] = 1

        dfs([], first_candidate)
        return result
  • 정답이다
  • t: O(n!) Beats 6.66%
  • key 값을 삭제하는게 아니라서 n!이 맞는지 긴가민가하다..
  • s: O(n \* n!) Beats 14.37%
  • 매번 복사 - > O(n)만큼 든다.'

효율성 개선 ??

text 코드 예제
                                    🤔 효율성을 개선하기 위해 어떻게 해야할까
>>> 근데 개선해도 n!이 최선이긴하고, 디테일한 부분이 개선될 가능성이 크다.
    >>> 예를들어 배열복사, dictioanry 복사 로직 등이 개선될 수 있을 것이다.

​