ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • #이진탐색 #행렬이라면?
    Data miner 2019. 10. 2. 13:17
    728x90

    Q. 각 행과 열이 오름차순으로 정렬된 상태인 M*N 행렬이 주어졌을 때, 특정한 원소를 찾는 메서드를 구하여라. 

    - 각 행과 열이 정렬된 상태이기 때문에, 선형탐색보다는 이진 탐색을 하는 것이 더 바람직하다. 다만, 이진 탐색을 어떤 범위로 할 것인지가 중요하다.

    - 만약, 1) 행마다의 이진 탐색을 적용하는 각 행을 탐색하는 데에는 O(logN)의 시간이 걸리며, 총 M개의 행의 경우 O(M log N)의 시간이 걸린다.  

    - 그렇다면 다른 방법은 없을까? 먼저 행렬을 살펴보자. 행렬에 있는 값들과 특정값을 비교할 때, '정렬된' 행렬에서 어떤 공통된 규칙이 있을까?

    (브레인스토밍 단계에서)

    i) 어떤 열의 시작점 원소값이 x보다 크다면 x는 그 열 왼쪽에 존재한다.

    ii) 어떤 열의 마지막 원소값이 x보다 작다면, x는 해당 열 오른쪽에 있다. 

    iii) 어떤 행의 시작점 원소값이 x보다 크다면, x는 해당 행 위에 있다.

    iv) 어떤 행의 마지막 원소값이 x보다 작다면, x는 해당 행 아래에 있다.

    이진탐색 문제를 적용하기 위해서 생각을 확장해 나가면, 위의 그림의 아이디어를 떠올릴 수 있다.

    즉, 각각 네모난 영역에서의 왼쪽 상단의 값과 오른쪽 하단의 값은 각각 네모난 영역에서의 최솟값최대값을 뜻한다. 

    def sorted_matrix_search(mat, item):
    
      if len(mat) == 0: #행의 크기가 0이면 찾고자 하는 값이 없다. 
    
        return None
    #범위를 탐색하기 위해서, 행-열로 표시
      return sorted_matrix_search_bounds(mat, item, 0, len(mat), 0, len(mat[0])) 
      
      def sorted_matrix_search_bounds(mat, item, x1, x2, y1, y2):
    
      if x1 == x2 or y1 == y2:
    
        return None
    
      row, col = (x1 + x2)//2, (y1 + y2)//2 #각 행과 열에 대한 중간값으로 설정
      middle = mat[row][col] #중간값
    
      if middle == item:
        return (row, col)
    
      if middle > item: #연두색 구획 안에 찾고자 하는 값이 있을 수 있다. 
        #그 구획을 다시 나눈다 #row to row+1 은 해당 행렬에서 탐색
        
        found = sorted_matrix_search_bounds(mat, item, x1, row, y1, col) or sorted_matrix_search_bounds(mat, item, x1, row, col, col+1,) or sorted_matrix_search_bounds(mat, item, row, row+1, y1, col )
               
    
        if found:
            return found
    
      else: #middle보다 찾고자 하는 값이 더 크므로
    	#진초록 구획에서 찾는 방법
        found = sorted_matrix_search_bounds(mat, item, row+1, x2, col+1, y2) or sorted_matrix_search_bounds(mat, item, row+1, x2, col, col+1) or sorted_matrix_search_bounds(mat, item, row, row+1, col+1, y2)
                
                
    
        if found:
    
          return found
    
      return sorted_matrix_search_bounds(mat, item, row+1, x2, y1, col) or sorted_matrix_search_bounds(mat, item,  x1, row, col+1, y2)
             
    

     

    if found 구문에서, found에 어떤 자료형이 들어 있으면, None 이 아니므로 그 값을 반환하게 된다. 

    found = 여러 값들의 후보로 'or'를 사용해 표기할 수 있다는 점

    'Data miner' 카테고리의 다른 글

    [python] [pandas] 객체에 함수 적용하기. apply  (0) 2020.04.03
    [python] [pandas] groupby  (0) 2020.04.01
    [선형탐색/이진탐색] 탐색 기법 비교  (0) 2019.09.30
    #정렬 #문자열정렬 #튜플활용  (0) 2019.09.26
    #재귀  (0) 2019.09.24
Designed by Tistory.