[TIL 210609] 파이썬 Set 교집합, Zip 함수 활용하기(Leetcode #1380)

송진수·2021년 6월 10일

Q)

m*n 행렬의 형태를 취하는 리스트 matrix에서 같은 행에서 가장 작으면서 같은 열에서 가장 큰 수를 lucky number라고 한다. 입력된 matrix에서 순서와 상관없이 모든 lucky number를 리스트의 형태로 출력하라.

input example : matrix = [[3,7,8],[9,11,13],[15,16,17]]
output = [15]

풀이과정)

각 행에서 최소값을 구하고, 그 값을 각 열에 해당하는 리스트에서 최대값을 찾아 일치 여부를 확인, 일치할 경우 값을 결과 리스트에 추가하기로 했다.

res = []
for i in range(m):
    row = matrix[i]
    for j in range(n):
        col = [num[j] for a,num in enumerate(matrix)]
        if min(row) == max(col):
            res.append(min(row))

밑의 답안을 보기 전에는 zip 함수를 활용할 줄 몰라 matrix를 enumerate하여 같은 인덱스를 가진 숫자들을 묶어 열 리스트로 만들었다.

또, set 자료형에서 & 연산자를 활용한다면 교집합도 쉽게 구현했을 텐데, 머리로는 생각이 났지만 방법을 몰라 결국 min(row)값을 max(col)값과 일일이 대조하는 과정을 거쳤다.

One-liner Solution)

class Solution:
    def luckyNumbers(self, matrix: List[List[int]]) -> List[int]:
        return list({min(row) for row in matrix} & {max(col) for col in zip(*matrix)})

zip(*matrix)에서 '*'는 언패킹 연산자로, 튜플이나 리스트에서 활용한다.

즉, zip(*matrix) == zip([3,7,8],[9,11,13],[15,16,17])


이 경우 zip함수는 입력받은 iterable 객채들을 지퍼 올리듯 묶어 튜플로 반환한다.

-> (3,9,15),(7,11,16),(8,13,17) == 각 열에 해당하는 데이터


여기서 각 iterable들의 min(row), max(col)를 중괄호 {}로 묶으면, min(row), max(col)을 원소로 하는 집합을 만들 수 있다.

즉, {3,9,15} 와 {15,16,17}이 만들어진다.


집합 자료형은 합집합, 교집합, 차집합 등의 연산이 가능하므로, & 연산자를 통한 교집합을 구하면 -> {15}

최종적으로 {15}를 리스트로 변환하는 list() 함수로 return 값을 출력한다. -> [15]

profile
보초

0개의 댓글