일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- Class
- 파이썬
- 30. Substring with Concatenation of All Words
- 43. Multiply Strings
- 715. Range Module
- concurrency
- DWG
- 밴픽
- Python Implementation
- 운영체제
- shiba
- 컴퓨터의 구조
- Python Code
- Generator
- iterator
- attribute
- Decorator
- Protocol
- 시바견
- t1
- Python
- Substring with Concatenation of All Words
- 109. Convert Sorted List to Binary Search Tree
- 프로그래머스
- Regular Expression
- LeetCode
- data science
- kaggle
- 315. Count of Smaller Numbers After Self
- Convert Sorted List to Binary Search Tree
Archives
- Today
- Total
Scribbling
LeetCode: 212. Word Search II 본문
단순 구현 문제로 생각했는데, 시간 초과가 발생한다.
메모리를 더 써서 시간을 줄여야 한다.
class Solution:
def findWords(self, board: List[List[str]], words: List[str]) -> List[str]:
m, n = len(board), len(board[0])
ret = []
for word in words:
found_flag = False
for i in range(m):
for j in range(n):
if board[i][j] == word[0]:
visited = [[False] * n for _ in range(m)]
visited[i][j] = True
if self.dfs(board, visited, i, j, word[1:]):
ret.append(word)
found_flag = True
break
if found_flag:
break
return ret
def dfs(self, board, visited, y, x, word):
if not word:
return True
dy = [0, 1, 0, -1]
dx = [1, 0, -1, 0]
for i in range(4):
next_y = y + dy[i]
next_x = x + dx[i]
if 0 <= next_y <= len(board) - 1 and 0 <= next_x <= len(board[0]) - 1:
if board[next_y][next_x] == word[0] and not visited[next_y][next_x]:
visited[next_y][next_x] = True
if self.dfs(board, visited, next_y, next_x, word[1:]):
return True
visited[next_y][next_x] = False
return False
TRIE 구조를 사용해야 한다.
TRIE는 아래 글을 참고 바란다.
https://focalpoint.tistory.com/214
이 문제의 알고리즘 자체는 간단하다.
보드의 모든 좌표에 대해서 TRIE를 체크하면 된다.
시간복잡도는? O((단어 갯수 * 단어 최대 길이) * (보드 세로 * 보드 가로))
class TrieNode:
def __init__(self):
self.children = {}
self.endFlag = False
class Trie:
def __init__(self):
self.root = TrieNode()
def insert(self, word: str) -> None:
node = self.root
for char in word:
if char not in node.children:
node.children[char] = TrieNode()
node = node.children[char]
node.endFlag = True
def search(self, word: str) -> bool:
node = self.root
for char in word:
if char not in node.children:
return False
node = node.children[char]
return node.endFlag
def startsWith(self, prefix: str) -> bool:
node = self.root
for char in prefix:
if char not in node.children:
return False
node = node.children[char]
return True
def delete(self, word):
def recursive(node, word, i):
if i == len(word):
if not node.endFlag:
return False
node.endFlag = False
return (len(node.children) == 0)
if word[i] not in node.children:
return False
need_delete = recursive(node.children[word[i]], word, i+1)
if need_delete:
node.children.pop(word[i])
return (len(node.children) == 0)
return False
recursive(self.root, word, 0)
class Solution:
def findWords(self, board: List[List[str]], words: List[str]) -> List[str]:
self.trie = Trie()
self.root = self.trie.root
for word in words:
self.trie.insert(word)
self.ret = []
m, n = len(board), len(board[0])
for y in range(m):
for x in range(n):
self.dfs(self.root, board, y, x, '')
return self.ret
def dfs(self, node, board, y, x, path):
if node.endFlag:
self.ret.append(path)
# avoid appending duplicate words
node.endFlag = False
# invalid coordinate
if y < 0 or y >= len(board) or x < 0 or x >= len(board[0]):
return
char = board[y][x]
node = node.children.get(char)
if not node:
return
board[y][x] = '#'
self.dfs(node, board, y, x+1, path+char)
self.dfs(node, board, y+1, x, path+char)
self.dfs(node, board, y, x-1, path+char)
self.dfs(node, board, y-1, x, path+char)
board[y][x] = char
Success이긴하나 조금 느리다... 개선할 여지가 있을까?
1) Trie 구조를 단순화한다 -> 메모리 개선
2) 검색이 완료된 Trie를 제거한다 -> 시간 개선
class Solution:
def findWords(self, board, words):
self.ret = []
self.trie = {}
for word in words:
t = self.trie
for c in word:
if c not in t:
t[c] = {}
t = t[c]
t['#'] = '#'
m, n = len(board), len(board[0])
for y in range(m):
for x in range(n):
self.dfs(board, self.trie, y, x, '')
return self.ret
def dfs(self, board, node, y, x, word):
if '#' in node:
del node['#']
self.ret.append(word)
if 0 > y or y >= len(board) or 0 > x or x >= len(board[0]):
return
char = board[y][x]
if char not in node:
return
next_node = node[char]
board[y][x] = '@'
dy, dx = [0, 1, 0, -1], [1, 0, -1, 0]
for d in range(4):
next_y, next_x = y + dy[d], x + dx[d]
self.dfs(board, next_node, next_y, next_x, word+char)
board[y][x] = char
if not next_node:
del node[char]
'Computer Science > Coding Test' 카테고리의 다른 글
LeetCode: 208. Implement Trie (Prefix Tree) (0) | 2021.12.09 |
---|---|
LeetCode: 136. Single Number (0) | 2021.12.09 |
LeetCode: 210. Course Schedule II (0) | 2021.12.07 |
LeetCode: 1011. Capacity To Ship Packages Within D Days (0) | 2021.12.06 |
LeetCode: 204. Count Primes (0) | 2021.12.05 |