-
Notifications
You must be signed in to change notification settings - Fork 126
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #608 from obzva/main
- Loading branch information
Showing
5 changed files
with
294 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
/* | ||
νμ΄ | ||
- λ λ¨μ΄λ₯Ό μνλ²³ νλμ© μ°¨λ‘λλ‘ λΉκ΅νμ λ, 첫λ²μ§Έ μ°¨μ΄κ° λ°μνλ μ§μ μμ alien dictionaryμ orderλ₯Ό μ°Ύμ μ μμ΅λλ€ | ||
- 첫λ²μ§Έ λ¨μ΄λΆν° λ°λ‘ κ·Έ λ€μ λ¨μ΄μ λ λ¨μ΄μ© μ§μ§μ΄μ λΉκ΅νλ©΄ μμμ λ§ν μΌλ ¨μ orderλ₯Ό μ°ΎμλΌ μ μμ΅λλ€ | ||
μνλ²³ xκ° μνλ²³ yλ³΄λ€ alien dictionary orderμμ μμλ κ΄κ³, μ¦ x->yμΈ κ΄κ³λ₯Ό μ°Ύμμ x: {y1, y2, y3, ...}μΈ μ§ν©μ mapμ λ§λ€κ² μ΅λλ€ | ||
κ·Έλ¦¬κ³ μ΄λ₯Ό nextLettersλΌκ³ λͺ λͺ νμμ΅λλ€ | ||
- λ§μ½ νΉμ μνλ²³ xμ λν΄, z->xμΈ μνλ²³ zκ° μλ€λ©΄ xλ μ°λ¦¬κ° μ λ΅μΌλ‘ μ μΆν result stringμ μ΄λ μμΉμλ μμ λ‘κ² λΌμλ£μ μ μμ΅λλ€ | ||
(* If there are multiple solutions, return any of them.) | ||
μ°λ¦¬λ μ΄λ° μνλ²³ xλ₯Ό μ°ΎμλΌ λλ§λ€ λ°λ‘λ°λ‘ result string resμ μΆκ°νκ² μ΅λλ€ | ||
- z->xμΈ μνλ²³ zκ° νμ¬ μλμ§ μλμ§μ λν μνκ΄λ¦¬λ₯Ό νκΈ° μν΄μ prevLetterCountsλΌλ mapμ λ§λ€κ² μ΅λλ€ | ||
prevLetterCounts[x]: z->xμΈ zμ κ°μ | ||
- nextLetters, prevLetterCountsλ₯Ό μ μμ±ν νμλ prevLetterCountκ° 0μΈ μνλ²³λΆν° queueμ λ±λ‘μν¨ ν BFSλ₯Ό μ€νν©λλ€ | ||
BFSλ₯Ό μ€ννλ©° prevLetterCountκ° 0μΈ μνλ²³μ΄ μλ‘ λ°κ²¬λ κ²½μ° queueμ λ±λ‘μν΅λλ€ | ||
- μ£μ§μΌμ΄μ€κ° λ κ²½μ° λ°μνλλ°, | ||
첫λ²μ§Έλ nextLettersλ₯Ό μμ±νλ λ°λ³΅λ¬Έμμ λ°κ²¬λ©λλ€ | ||
λλ²μ§Έ λ¨μ΄κ° 첫λ²μ§Έ λ¨μ΄μ prefixμΈ κ²½μ°λ μ μ΄λΆν° μλͺ»λ dictionary orderμΈ κ²½μ°μ λλ€ | ||
μ κ²½μ°λ λ¨μ μνλ²³ λΉκ΅λ‘λ λ°κ²¬νκΈ° μ΄λ €μ°λ―λ‘ flagλ₯Ό μ¬μ©νμμ΅λλ€ | ||
λλ²μ§Έλ result stringμ κΈΈμ΄κ° inputμΌλ‘ μ£Όμ΄μ§ λ¨μ΄λ€μ λ±μ₯ν μνλ²³μ κ°μλ³΄λ€ μ μ κ²½μ°μ λλ€ | ||
μ΄ κ²½μ°λ nextLettersμ μνμ΄ λ°μν κ²½μ°μ΄λ―λ‘ dictionary orderκ° μλͺ»λμλ€κ³ νλ¨ν μ μμ΅λλ€ | ||
Big O | ||
- N: μ£Όμ΄μ§ λ°°μ΄ wordsμ κΈΈμ΄ | ||
- S(W): λ°°μ΄ wordsμ μν λͺ¨λ stringμ κΈΈμ΄μ μ΄ν© | ||
- Time complexity: O(N + S(W)) | ||
- prevLetterCountsμ nextLetters μμ± -> O(N) | ||
- nextLettersμ λ€μ΄κ° μνλ²³ μ νκ΄κ³ μ°ΎκΈ° -> O(S(W)) | ||
- μνλ²³ μλ¬Έμμ μλ μ νλμ΄ μκΈ° λλ¬Έμ BFSμ μκ° λ³΅μ‘λ μνμ μ μ ν΄μ Έ μμ΅λλ€ -> O(26 * 26) = O(1) | ||
- Space complexity: O(1) | ||
- μνλ²³ μλ¬Έμμ μλ μ νλμ΄ μκΈ° λλ¬Έμ κ³΅κ° λ³΅μ‘λμ μνμ μ μ ν΄μ Έ μμ΅λλ€ | ||
prevLetterCounts -> O(26) = O(1) | ||
nextLetters -> O(26 * 26) = O(1) | ||
queue -> O(26) = O(1) | ||
*/ | ||
|
||
import "strings" | ||
|
||
func alienOrder(words []string) string { | ||
n := len(words) | ||
// prevLetterCounts[x] = count of letters y that are in relation of y->x | ||
prevLetterCounts := make(map[string]int) | ||
// nextLetters[x] = set of letters y that are in relation of x->y | ||
nextLetters := make(map[string]map[string]bool) | ||
for _, word := range words { | ||
for _, c := range word { | ||
if _, ok := prevLetterCounts[string(c)]; !ok { | ||
prevLetterCounts[string(c)] = 0 | ||
nextLetters[string(c)] = make(map[string]bool) | ||
} | ||
} | ||
} | ||
|
||
for i := 0; i < n-1; i++ { | ||
currWord := words[i] | ||
nextWord := words[i+1] | ||
// flag for edge case below | ||
diff := false | ||
for j := 0; j < len(currWord) && j < len(nextWord); j++ { | ||
if currWord[j] != nextWord[j] { | ||
diff = true | ||
if _, ok := nextLetters[string(currWord[j])][string(nextWord[j])]; !ok { | ||
prevLetterCounts[string(nextWord[j])]++ | ||
nextLetters[string(currWord[j])][string(nextWord[j])] = true | ||
} | ||
break | ||
} | ||
} | ||
// tricky edge case!!! | ||
// if nextWord is prefix of currWord, then the provided dictionary order is invalid | ||
if !diff && len(currWord) > len(nextWord) { | ||
return "" | ||
} | ||
} | ||
// BFS | ||
queue := make([]string, 0, len(prevLetterCounts)) | ||
for letter := range prevLetterCounts { | ||
// we can arrange letters whose prevLetterCount is zero as we wish | ||
if prevLetterCounts[letter] == 0 { | ||
queue = append(queue, letter) | ||
} | ||
} | ||
// in Go, using strings.Builder is the most efficient way to build strings | ||
var sb strings.Builder | ||
for len(queue) > 0 { | ||
// pop the letter from the queue and append it to the result string | ||
popped := queue[0] | ||
queue = queue[1:] | ||
sb.WriteString(popped) | ||
|
||
for nextLetter := range nextLetters[popped] { | ||
prevLetterCounts[nextLetter]-- | ||
// if prevLetterCount for nextLetter becomes zero, we can add it to the queue | ||
// append to the result string (order) in the next iteration | ||
if prevLetterCounts[nextLetter] == 0 { | ||
queue = append(queue, nextLetter) | ||
} | ||
} | ||
} | ||
// res is result string | ||
res := sb.String() | ||
// this case means that there was a cycle | ||
if len(res) != len(prevLetterCounts) { | ||
return "" | ||
} | ||
// else return res | ||
return res | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
/* | ||
νμ΄ | ||
- μ¬λΌμ΄λ© μλμ° κΈ°λ²μ μ΄μ©νλ©΄ νμ΄ν μ μμ΅λλ€ | ||
Big O | ||
- N: μ£Όμ΄μ§ λ¬Έμμ΄ sμ κΈΈμ΄ | ||
- Time complexity: O(N^2) | ||
- window ν¨μκ° O(N)μ μκ°λ³΅μ‘λλ₯Ό κ°μ§λ―λ‘ | ||
κ° λ°λ³΅λ¬Έμ O(N * N) = O(N^2)μ μκ°λ³΅μ‘λλ₯Ό κ°μ§λ€κ³ λ³Ό μ μμ΅λλ€ | ||
- Space complexity: O(1) | ||
- λ³λμ μΆκ°μ μΈ κ³΅κ° λ³΅μ‘λλ₯Ό κ³ λ €νμ§ μμλ λ©λλ€ | ||
*/ | ||
|
||
func longestPalindrome(s string) string { | ||
n := len(s) | ||
maxStart := 0 | ||
maxEnd := 0 | ||
// for odd lengths | ||
for i := 0; i < n; i++ { | ||
window(&s, &maxStart, &maxEnd, i, false) | ||
} | ||
// for even lengths | ||
for i := 0; i < n-1; i++ { | ||
window(&s, &maxStart, &maxEnd, i, true) | ||
} | ||
|
||
return s[maxStart : maxEnd+1] | ||
} | ||
|
||
/* | ||
helper function for searching palindromic substring | ||
from the pivotal index `i` | ||
*/ | ||
func window(s *string, maxStart *int, maxEnd *int, i int, isEven bool) { | ||
n := len(*s) | ||
start := i | ||
end := i | ||
if isEven { | ||
end++ | ||
} | ||
for 0 <= start && end < n { | ||
if (*s)[start] != (*s)[end] { | ||
break | ||
} | ||
|
||
// if new palindromic substring is longer than the previously found one, | ||
// update the start and end index | ||
if *maxEnd-*maxStart < end-start { | ||
*maxStart = start | ||
*maxEnd = end | ||
} | ||
start-- | ||
end++ | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
/* | ||
νμ΄ | ||
- matrixλ₯Ό 4μ¬λΆλ©΄μΌλ‘ λλλλ€ | ||
1μ¬λΆλ©΄μ λͺ¨λ μ’νμ λν΄ μλμ κ°μ μ°μ°μ μνν©λλ€ | ||
- 1μ¬λΆλ©΄μ μ’ν a1μ λν΄ a2, a3, a4λ₯Ό μλμ²λΌ μ μν©λλ€ | ||
a2: a1μ 90λ νμ μμΌ°μ λμ μ’ν (2μ¬λΆλ©΄μ μμΉν¨) | ||
a3: a2λ₯Ό 90λ νμ μμΌ°μ λμ μ’ν (3μ¬λΆλ©΄μ μμΉν¨) | ||
a4: a3μ 90λ νμ μμΌ°μ λμ μ’ν (4μ¬λΆλ©΄μ μμΉν¨) | ||
a1 -> a2, a2 -> a3, a3 -> a4, a4 -> a1μΌλ‘ κ°μ λ³κ²½μν΅λλ€ | ||
Big O | ||
- N: 맀νΈλ¦μ€μ ν¬κΈ° | ||
- Time complexity: O(N^2) | ||
- Space complexity: O(1) | ||
*/ | ||
|
||
func rotate(matrix [][]int) { | ||
n := len(matrix) | ||
// μ¬λΆλ©΄μ ν¬κΈ°, qr, qc: μ¬λΆλ©΄μ ν, μ΄ ν¬κΈ° | ||
qr := n / 2 | ||
qc := (n + 1) / 2 | ||
|
||
for r := 0; r < qr; r++ { | ||
for c := 0; c < qc; c++ { | ||
r1 := r | ||
c1 := c | ||
|
||
r2 := c | ||
c2 := n - 1 - r | ||
|
||
r3 := n - 1 - r | ||
c3 := n - 1 - c | ||
|
||
r4 := n - 1 - c | ||
c4 := r | ||
|
||
matrix[r1][c1], matrix[r2][c2], matrix[r3][c3], matrix[r4][c4] = matrix[r4][c4], matrix[r1][c1], matrix[r2][c2], matrix[r3][c3] | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
/* | ||
νμ΄ | ||
- λ νΈλ¦¬κ° λμΌνμ§ κ²μ¬νλ dfs ν¨μλ₯Ό μ΄μ©νμ¬ νμ΄ν μ μμ΅λλ€ | ||
Big O | ||
- M: root νΈλ¦¬μ λ Έλ κ°μ | ||
- N: subRoot νΈλ¦¬μ λ Έλ κ°μ | ||
- Time complexity: O(MN) | ||
- μ΅μ μ κ²½μ° root νΈλ¦¬μ λͺ¨λ λ Έλμ λν΄ isSameTree ν¨μλ₯Ό μ€ν (O(M)) | ||
μ΅μ μ κ²½μ° isSameTree ν¨μλ O(N)μ μκ°λ³΅μ‘λλ₯Ό κ°μ§ | ||
- Space complexity: O(M+N) | ||
- isSubTreeμ μ¬κ·νΈμΆμ€ν κΉμ΄λ μ΅λ O(M)μ 곡κ°λ³΅μ‘λλ₯Ό κ°μ§ | ||
- isSameTreeμ μ¬κ·νΈμΆμ€ν κΉμ΄λ μ΅λ O(N)μ 곡κ°λ³΅μ‘λλ₯Ό κ°μ§ | ||
*/ | ||
|
||
/** | ||
* Definition for a binary tree node. | ||
* type TreeNode struct { | ||
* Val int | ||
* Left *TreeNode | ||
* Right *TreeNode | ||
* } | ||
*/ | ||
func isSubtree(root *TreeNode, subRoot *TreeNode) bool { | ||
// handling nil(null) inputs | ||
if root == nil { | ||
return false | ||
} | ||
// return true if root and subroot are same | ||
if isSameTree(root, subRoot) { | ||
return true | ||
} | ||
// else, check root.left and root.right | ||
return isSubtree(root.Left, subRoot) || isSubtree(root.Right, subRoot) | ||
} | ||
|
||
/* | ||
dfs helper function checking whether two treenodes are same or not | ||
*/ | ||
func isSameTree(a *TreeNode, b *TreeNode) bool { | ||
// handling nil(null) cases | ||
if a == nil || b == nil { | ||
return a == b | ||
} | ||
// falsy cases | ||
if a.Val != b.Val || !isSameTree(a.Left, b.Left) || !isSameTree(a.Right, b.Right) { | ||
return false | ||
} | ||
// else, return true | ||
return true | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
/* | ||
νμ΄ | ||
- BSTμ μμ±μ μ΄ν΄ν ν, ν΄λΉ μμ±μ κ²μ¬νλ dfs ν¨μλ₯Ό μ΄μ©νλ©΄ νμ΄ν μ μμ΅λλ€ | ||
Big O | ||
- N: root νΈλ¦¬μ λ Έλ κ°μ | ||
- Time complexity: O(N) | ||
- λͺ¨λ λ Έλμ λν΄ μ΅λ 1λ²μ νμμ΄ νμν©λλ€ | ||
- Space complexity: O(logN) (O(N) at worst) | ||
- check ν¨μμ μ¬κ·νΈμΆ μ€ν κΉμ΄λ νΈλ¦¬μ λμ΄μ λΉλ‘νμ¬ μ¦κ°νλ―λ‘ μΌλ°μ μΌλ‘ O(logN)μ 곡κ°λ³΅μ‘λλ₯Ό κ°μ§λ€κ³ λ³Ό μ μμ΅λλ€ | ||
νμ§λ§ νΈλ¦¬κ° μ¬νκ² μΉμ°μΉ κ²½μ° O(N)κΉμ§ μ»€μ§ μ μμ΅λλ€ | ||
*/ | ||
|
||
/** | ||
* Definition for a binary tree node. | ||
* type TreeNode struct { | ||
* Val int | ||
* Left *TreeNode | ||
* Right *TreeNode | ||
* } | ||
*/ | ||
|
||
const ( | ||
MIN = -(2_147_483_648 + 1) | ||
MAX = 2_147_483_647 + 1 | ||
) | ||
|
||
func isValidBST(root *TreeNode) bool { | ||
return check(root.Left, MIN, root.Val) && check(root.Right, root.Val, MAX) | ||
} | ||
|
||
/* | ||
helper dfs function | ||
*/ | ||
|
||
func check(node *TreeNode, min int, max int) bool { | ||
// base case | ||
if node == nil { | ||
return true | ||
} | ||
// node.val should be in the boundary (min, max) | ||
if !(min < node.Val && node.Val < max) { | ||
return false | ||
} | ||
// check for children nodes | ||
return check(node.Left, min, node.Val) && check(node.Right, node.Val, max) | ||
} |