-
[LeetCode | Python] 240. Search a 2D Matrix II개발/알고리즘 2025. 3. 16. 20:50
느낀점
바이너리 서치 문제는 이미 익숙하니 이를 조금 더 응용할 수 있는 문제를 찾다가 아래 문제를 찾았고, 예상했던 것보다는 더 오래 생각에 잠겨야 했던 문제 입니다. 2차원 배열이라 바이너리 서치 두 번으로 풀 수 있을 것이라고 생각했는데, 그렇게 풀지는 못했습니다. 본질적인 문제를 고민하였다면 조금 더 쉽게 접근할 수 있었을 것이라는 생각이드는 문제였습니다.
문제
https://leetcode.com/problems/search-a-2d-matrix-ii/description/
다음과 같은 특징을 가진 m x n 크기의 정수 행렬(matrix)에서 특정 값(target)을 효율적으로 찾는 알고리즘을 작성하세요.
- 각 행의 정수는 왼쪽에서 오른쪽으로 오름차순으로 정렬되어 있습니다.
- 각 열의 정수는 위에서 아래로 오름차순으로 정렬되어 있습니다.
풀이
리트코드 문제 예시 바이너리 서치를 두번 적용한다고 했을 때, 이 배열의 중심인 9에 집중해야 하는데, 몇가지 케이스를 생각했다면 쉽게 풀 수 있는 문제였다.
9를 중심으로 다음의 케이스를 생각해보자.
- 9에서 포인터가 출발한다고 할 때, 9보다 큰 10이 어디에 존재할 수 있는가
- 9에서 포인터가 출발한다고 할 때, 9보다 작은 5는 어디에 존재할 수 있는가
처음에는 9를 중심으로 4가지면이 있고 한면만 탐색하면 상당히 효율적으로 탐색할 수 있을 것 같았는데, 그건 착각이었다. 위의 케이스들을 고려해본다면 다음의 영역은 탐색을 해야만 한다.
- 9가 중앙에 있을 때, 10이 존재할 수 있는 위치는 일단은 9 아래줄에 올 수 있고, 그 이후 왼쪽면과 오른쪽 면 둘다 올 수 있다(3, 4 사분면). 또한, 9 위로는 9보다 작은 수들이기 때문에 오른쪽면에 올 수 있다 (2 사분면).
- 9가 중앙에 있을 때, 5가 존재할 수 있는 위치는 일단은 9 윗줄에 올 수 있고, 그 이후 왼쪽면과 오른쪽 면 둘다 올 수 있다(1, 2 사분면). 또한, 9 아랫줄로는 9보다 큰 수들이기 때문에 왼쪽면에만 올 수 있다 (1 사분면).
즉 처음에 생각했을 때는 네 영역에서 한 영역만 탐색할 수 있을 줄 알았는데, 반대로 한 영역만 제외하고 다 탐색해야만 한다. 그래서 코드를 다음과 같이 바꾸게 됬다. 세로줄은 반복문으로 다 돌게 하고 가로줄은 바이너리 서치를 하되, 약간의 속도의 이점을 얻기 위해 스코프를 좀 조정하는 방식으로 코드를 작성했다.
class Solution: def searchMatrix(self, matrix: List[List[int]], target: int) -> bool: sn, ln = 0, len(matrix[0])-1 cm = (sn+ln) // 2 def bs(lst, sn, ln): while sn <= ln: mn = (sn+ln) // 2 if lst[mn] == target: return True elif lst[mn] > target: ln = mn-1 elif lst[mn] < target: sn = mn+1 return False for rlst in matrix: if rlst[cm] < target: if bs(rlst, cm, ln): return True elif rlst[cm] > target: if bs(rlst, sn, cm): return True elif rlst[cm] == target: return True return False
결과
- 시간복잡도: $ O(M * Log(N)) $
- 공간복잡도: $ O(1) $
'개발 > 알고리즘' 카테고리의 다른 글
하루히 문제 (Haruhi Problem) (0) 2025.04.05 [LeetCode | Python] 55. Jump Game (0) 2025.03.23 [LeetCode | Python] 29. Divide Two Integers (0) 2025.03.22 [LeetCode | Python] 443. String Compression (0) 2025.03.18 [Loop Strategy] Peter Bro Miltersen - 100명의 죄수 문제 (0) 2023.05.29