LeetCode | 384. Shuffle an Array

송치헌·2021년 7월 21일
0

Algorithm | LeetCode

목록 보기
10/15

문제

Given an integer array nums, design an algorithm to randomly shuffle the array. All permutations of the array should be equally likely as a result of the shuffling.

Implement the Solution class:

Solution(int[] nums) Initializes the object with the integer array nums.
int[] reset() Resets the array to its original configuration and returns it.
int[] shuffle() Returns a random shuffling of the array.

Example 1:

Input
["Solution", "shuffle", "reset", "shuffle"]
[[[1, 2, 3]], [], [], []]
Output
[null, [3, 1, 2], [1, 2, 3], [1, 3, 2]]

Explanation
Solution solution = new Solution([1, 2, 3]);
solution.shuffle();    // Shuffle the array [1,2,3] and return its result.
                       // Any permutation of [1,2,3] must be equally likely to be returned.
                       // Example: return [3, 1, 2]
solution.reset();      // Resets the array back to its original configuration [1,2,3]. Return [1, 2, 3]
solution.shuffle();    // Returns the random shuffling of array [1,2,3]. Example: return [1, 3, 2]

Constraints:

  • 1 <= nums.length <= 200
  • 106<=-10^6 <= nums[i] <=106<= 10^6
  • All the elements of nums are unique.
  • At most 51045 * 10^4 calls in total will be made to reset and shuffle.

Python 풀이

class Solution:

    def __init__(self, nums: List[int]):
        self.nums = nums

    def reset(self) -> List[int]:
        """
        Resets the array to its original configuration and return it.
        """
        return self.nums

    def shuffle(self) -> List[int]:
        """
        Returns a random shuffling of the array.
        """
        rnd = list(self.nums)
        random.shuffle(rnd)
        return rnd


# Your Solution object will be instantiated and called as such:
# obj = Solution(nums)
# param_1 = obj.reset()
# param_2 = obj.shuffle()

문제 설명

정수형 리스트가 input으로 주어진다.

그리고 메서드 2개가 있는데 1개는 원래 주어진 리스트로 되돌리는 reset(), 나머지 1개는 리스트를 랜덤으로 섞는 shuffle()이다.

각 메서드를 호출했을 때 제대로 동작하도록 빈칸을 채워넣는 문제이다.

코드 설명

__init__은 변수의 초기값을 선언하는 부분이다. 입력으로 들어오는 리스트를 클래스의 변수로 초기화해준다.

reset()은 처음 초기화한 값으로 되돌리는 메서드이다. 그냥 __init__에 초기화 시켜준 변수(self.nums)를 리턴해주면 된다.

shuffle()은 리스트를 랜덤하게 섞는 메서드이다. 여기에서 새로운 지식을 알게 되었는데 C언어와는 다르게 rnd = numsrndnums를 할당해주고 rnd를 섞어주면 nums도 섞이게 된다. 이 부분에 대해 WeCode 팀원에게 도움을 요청했는데 rnd가 새로운 리스트를 생성하는 것이 아니라, 이미 만들어진 nums라는 리스트를 참조하는 것이므로 같은 주소값을 갖게 된다고 하셨다. 정리하자면,

>>> a = [1,2,3,4]
>>> b = a
>>> id(a)
139727928641280
>>> id(b)
139727928641280

이런 식으로 한 주소에 두개의 변수가 공존하는 식이라서 b값을 변경하면 a값도 변경된다.

참고로 여기서 nums의 무결성이 보장되어야 하는 이유는 reset()에서의 리턴되는 값이 처음에 선언한 nums가 되어야 하므로 shuffle()에서 nums값까지 바뀌면 안된다.

따라서 이 부분은 rnd = list(nums)를 해주거나 rnd = nums[:]로 리스트를 복사하여 rnd에게 주면 된다.

즉, nums가 살고있는 집을 rnd에게 주는 것이 아니라 nums의 집과 똑같이 생긴 다른 집을 분양해 주는 것이라고 보면 된다.

profile
https://oraange.tistory.com/ 여기에도 많이 놀러와 주세요

0개의 댓글