From 7f109cc50580d501391f5c0693888651ea339e34 Mon Sep 17 00:00:00 2001 From: Gyunseo Lee Date: Wed, 10 Jul 2024 20:28:29 +0900 Subject: [PATCH] 2024-07-10 20:28:29 Affected files: .obsidian/workspace.json src/content/blog/leet-code-74-search-a-2d-matrix.md --- .obsidian/workspace.json | 24 +++---- .../blog/leet-code-74-search-a-2d-matrix.md | 63 +++++++++++++++++++ 2 files changed, 75 insertions(+), 12 deletions(-) create mode 100644 src/content/blog/leet-code-74-search-a-2d-matrix.md diff --git a/.obsidian/workspace.json b/.obsidian/workspace.json index ec5110bd1..ce119460e 100644 --- a/.obsidian/workspace.json +++ b/.obsidian/workspace.json @@ -13,7 +13,7 @@ "state": { "type": "markdown", "state": { - "file": "src/content/blog/boj-2660-회장뽑기.md", + "file": "src/content/blog/leet-code-1438-longest-continuous-subarray-with-absolute-diff-less-than-or-equal-to-limit.md", "mode": "source", "source": false } @@ -22,16 +22,16 @@ ] }, { - "id": "8f2f56ee0a383872", + "id": "c7e001a823d6f00b", "type": "tabs", "children": [ { - "id": "ae733d9e70e8be2f", + "id": "6f0f9243e9d7c564", "type": "leaf", "state": { "type": "markdown", "state": { - "file": "src/content/blog/boj-6593-상범-빌딩.md", + "file": "src/content/blog/leet-code-74-search-a-2d-matrix.md", "mode": "source", "source": false } @@ -103,7 +103,7 @@ "state": { "type": "backlink", "state": { - "file": "src/content/blog/boj-6593-상범-빌딩.md", + "file": "src/content/blog/leet-code-74-search-a-2d-matrix.md", "collapseAll": false, "extraContext": false, "sortOrder": "alphabetical", @@ -120,7 +120,7 @@ "state": { "type": "outgoing-link", "state": { - "file": "src/content/blog/boj-6593-상범-빌딩.md", + "file": "src/content/blog/leet-code-74-search-a-2d-matrix.md", "linksCollapsed": false, "unlinkedCollapsed": true } @@ -143,7 +143,7 @@ "state": { "type": "outline", "state": { - "file": "src/content/blog/boj-6593-상범-빌딩.md" + "file": "src/content/blog/leet-code-74-search-a-2d-matrix.md" } } } @@ -166,18 +166,19 @@ "table-editor-obsidian:Advanced Tables Toolbar": false } }, - "active": "ae733d9e70e8be2f", + "active": "6f0f9243e9d7c564", "lastOpenFiles": [ + "src/content/blog/leet-code-1438-longest-continuous-subarray-with-absolute-diff-less-than-or-equal-to-limit.md", "src/content/blog/boj-2660-회장뽑기.md", + "src/content/blog/leet-code-74-search-a-2d-matrix.md", + "src/content/blog/leet-code-64-minimum-path-sum.md", "src/content/blog/boj-6593-상범-빌딩.md", "src/content/blog/boj-2529-부등호.md", "src/content/blog/왜-node에서-pino-logger를-이용한-log-io는-cpu-usage에-큰-영향이-없을까.md", "src/content/blog/.md", "src/content/blog/boj-1309-동물원.md", - "src/content/blog/leet-code-1438-longest-continuous-subarray-with-absolute-diff-less-than-or-equal-to-limit.md", "src/content/blog/leet-code-438-find-all-anagrams-in-a-string.md", "src/content/blog/boj-10159-저울.md", - "src/content/blog/leet-code-64-minimum-path-sum.md", "src/content/blog/leet-code-17-letter-combinations-of-a-phone-number.md", "src/content/blog/boj-2841-외계인의-기타-연주.md", "src/content/blog/boj-1926-그림.md", @@ -212,7 +213,6 @@ "dist/tags/ostep/1/index.html", "dist/tags/ostep/1", "dist/posts/우테코-2차-소감문.png", - "src/content/blog/boj-11725-트리의-부모-찾기.md", - "src/content/blog/boj-1935-후위-표기식2.md" + "src/content/blog/boj-11725-트리의-부모-찾기.md" ] } \ No newline at end of file diff --git a/src/content/blog/leet-code-74-search-a-2d-matrix.md b/src/content/blog/leet-code-74-search-a-2d-matrix.md new file mode 100644 index 000000000..c3ecd8fb8 --- /dev/null +++ b/src/content/blog/leet-code-74-search-a-2d-matrix.md @@ -0,0 +1,63 @@ +--- +author: Gyunseo Lee +title: "LeetCode 74: Search a 2D Matrix" +pubDatetime: 2024-07-10T20:02:00+09:00 +modDatetime: 2024-07-10T20:02:00+09:00 +featured: false +draft: false +tags: + - PS + - Algorithms + - Binary-Search + - LeetCode +description: 이분탐색 구현은 암기하고 있도록 하자 +ogImage: "" +--- + +## Table of contents + +## 들어가며 + +이 문제를 처음 읽었을 때, 각 행마다 bisect_left, bisect_right 쿼리를 날려서 문제를 풀려고 했습니다. +근데 그러면 시간 복잡도가 Order of mLgn이 되더라고요. 그러면 문제에서 요구한 Order of Lg(mn)보다 크게 돼서, 시간 초과가 납니다. +그래서 하는 수 없이 이분 탐색을 그냥 구현하기로 했습니다.😀 + +## 접근 + +matrix에 이분탐색을 어떻게 할까 생각을 해 봤습니다. +matrix를 행별로 끊어서 늘어 뜨리면 결국 하나의 정렬된 리스트가 될 것이라는 아이디어에서 출발했습니다. +그러면 list의 idx를 열개수로 나눈 몫과 나머지가 matrix의 좌표가 돼 버립니다. + +## 구현 + +```python +class Solution: + def searchMatrix(self, matrix: List[List[int]], target: int) -> bool: + r = len(matrix) + c = len(matrix[0]) + def binary_search(): + def is_valid(idx): + i, j = idx // c, idx % c + if matrix[i][j] > target: + return True + return False + + lo = -1 + hi = r * c + while lo + 1 < hi: + mid = (lo + hi) // 2 + if is_valid(mid): + hi = mid + else: + lo = mid + # lo is cross point + if matrix[lo // c][lo % c] == target: + return True + else: + return False + return binary_search() +``` + +이분탐색은 off-by-one Error가 나기 쉽습니다. +그래서 [이분 탐색 헷갈리지 않게 구현하기](https://www.acmicpc.net/blog/view/109)의 아티클을 예전에 읽은 적이 있습니다. +해당 아티클의 발상과 아이디어를 많이 기억해 나가면서 구현을 했습니다.