리트코드 240번
왼쪽에서 오른쪽 위에서 아래로 오름차순 정렬된 행렬에서 target값 찾기
class Solution:
def searchMatrix(self, matrix, target: int) -> bool:
m, n = len(matrix), len(matrix[0])
first_m, first_n = 0, 0
last_m, last_n = m - 1, n - 1
while first_m <= last_m and first_n <= last_n:
mid_m, mid_n = first_m + (last_m - first_m) // 2, first_n + (last_n - first_n) // 2
if matrix[mid_m][mid_n] == target:
return True
elif matrix[mid_m][mid_n] > target:
if mid_m - 1 < 0 :
last_m, last_n = mid_m, mid_n - 1
elif mid_n -1 < 0 :
last_m, last_n = mid_m - 1, mid_n
elif matrix[mid_m - 1][mid_n] > matrix[mid_m][mid_n - 1]:
last_m, last_n = mid_m - 1, mid_n
else:
last_m, last_n = mid_m, mid_n - 1
else:
if mid_m + 1 > last_m:
first_m, first_n = mid_m, mid_n + 1
elif mid_n + 1 > last_n:
first_m, first_n = mid_m + 1, mid_n
elif matrix[mid_m + 1][mid_n] < matrix[mid_m][mid_n + 1]:
first_m, first_n = mid_m + 1, mid_n
else:
first_m, first_n = mid_m, mid_n + 1
return False
제대로된 풀이 중 하나는 오른쪽위나 왼쪽 아래에서부터 시작해서 작거나 크면 col , row값을 조정하면서 내려가는 것입니다.
여기서는 오른쪽 위에서 시작하도록 하겠습니다
class Solution:
def searchMatrix(self, matrix, target: int) -> bool:
row, col = 0, len(matrix[0]) - 1
while row < len(matrix) and col > -1:
if matrix[row][col] == target :
return True
elif matrix[row][col] > target:
col = col - 1
else:
row = row + 1
return False
그림처럼 15에서 출발해서 target보다 작으면 아래로 target보다 크면 왼쪽으로 이동하면서 구하고 만약 범위를 벗어나면 False을 반환하는 방식입니다
이게 위와 다르게 되는 이유는 target이 20이라면 15보다 크기때문에 밑으로 내려갈때 15로부터 왼쪽은 모두 제외되고 따라서 이런식으로 하다보면 왼쪽과 아래쪽만 고려해주면되고 오른쪽과 위쪽은 지나온 곳이기 때문에 이미 따져졌다고 볼 수 있기 때문입니다
결국 이문제는 기준을 어디로 잡느냐가 중요한문제...
이진탐색을 쓴건 아니므로 복잡도는 O(m+n)이 나오게 됩니다
이번에는 그냥 각 행마다 이진탐색 적용을 해서 찾는 방법입니다
class Solution:
def searchMatrix(self, matrix, target: int) -> bool:
rows = len(matrix)
for row in range(rows):
first, last = 0, len(matrix[0])-1
while first <= last:
mid = first + (last - first) // 2
if matrix[row][mid] == target:
return True
elif matrix[row][mid] > target:
last = mid - 1
else:
first = mid + 1
return False
복잡도는 최악일 경우 O(nlogm)이지만 중간에 찾는다면 나쁘지 않은 것 같아 시도해봤고 실제로 위에 코드와 비슷하게 나왔습니다