-
Notifications
You must be signed in to change notification settings - Fork 2.3k
/
0079-word-search.swift
94 lines (75 loc) · 2.46 KB
/
0079-word-search.swift
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
class Solution {
let dirX: [Int] = [-1, 1, 0, 0]
let dirY: [Int] = [0, 0, -1, 1]
func exist(_ board: [[Character]], _ word: String) -> Bool {
let ROWS = board.count
let COLS = board[0].count
var visited = [[Bool]](
repeating: [Bool](repeating: false, count: COLS),
count: ROWS
)
var wordArr: [Character] = Array(word)
for r in 0..<ROWS {
for c in 0..<COLS {
visited[r][c] = true
if dfs(
startRow: r,
startCol: c,
&visited,
board,
&wordArr,
startIdx: 0
) == true {
return true
}
visited[r][c] = false
}
}
return false
}
}
private extension Solution {
func isWithinBounds(row: Int, col: Int, _ board: [[Character]]) -> Bool {
((row >= 0) && (col >= 0) &&
(row < board.count) && (col < board[0].count))
}
func dfs(
startRow row: Int,
startCol col: Int,
_ visited: inout [[Bool]],
_ board: [[Character]],
_ wordArr: inout [Character],
startIdx index: Int
) -> Bool {
let strLen = wordArr.count
// Last index check
if index == (strLen - 1) {
return board[row][col] == wordArr[index]
}
// Edge case
guard index < strLen else { return false }
guard board[row][col] == wordArr[index] else { return false }
for (dX, dY) in zip(dirX, dirY) {
let rowNew = row + dX
let colNew = col + dY
guard isWithinBounds(row: rowNew, col: colNew, board) else { continue }
guard visited[rowNew][colNew] == false else { continue }
// Visit
visited[rowNew][colNew] = true
// Recursive DFS
if dfs(
startRow: rowNew,
startCol: colNew,
&visited,
board,
&wordArr,
startIdx: index + 1
) == true {
return true
}
// Unvisit [for backtrack]
visited[rowNew][colNew] = false
}
return false
}
}