diff --git "a/6_\353\254\270\354\236\220\354\227\264/17\354\243\274\354\260\250.md" "b/6_\353\254\270\354\236\220\354\227\264/17\354\243\274\354\260\250.md"
new file mode 100644
index 0000000..223d8af
--- /dev/null
+++ "b/6_\353\254\270\354\236\220\354\227\264/17\354\243\274\354\260\250.md"
@@ -0,0 +1,102 @@
+# 47
+
+~~~java
+public int maxDepth(TreeNode root){
+ if(root == null) return 0;
+
+ int left = maxDepth(root.left);
+ int right = maxDepth(root.right);
+
+ return Math.max(left,right) + 1;
+}
+
+~~~
+
+# 48
+
+왜 -1로 하는지 이해가 잘 안감. 0으로 해도 답이 나오고 정 이진트리가 아닌 대부분의 경우에도 0으로 해도 무방함. 거의 0 or null로 처리하는듯
+
+~~~java
+public class Solution {
+ private int maxDiameter = 0;
+
+ public int diameterOfBinaryTree(TreeNode root) {
+ dfs(root);
+ return maxDiameter;
+ }
+
+ private int dfs(TreeNode node) {
+ if (node == null) return 0;
+
+ // 왼쪽 자식에서의 최대 깊이
+ int leftDepth = dfs(node.left);
+ // 오른쪽 자식에서의 최대 깊이
+ int rightDepth = dfs(node.right);
+
+ // 현재 노드를 루트로 하는 경로의 길이 갱신
+ maxDiameter = Math.max(maxDiameter, leftDepth + rightDepth);
+
+ // 현재 노드에서의 최대 깊이 반환
+ return Math.max(leftDepth, rightDepth) + 1;
+ }
+}
+~~~
+
+
+
+# 문제
+
+~~~java
+import java.util.*;
+
+public class Main {
+
+ public static void main(String[] args) {
+ Scanner scanner = new Scanner(System.in);
+ TreeNode root = null;
+
+ // 입력이 있는 동안 트리를 생성
+ while (scanner.hasNextInt()) {
+ int val = scanner.nextInt();
+ root = insert(root, val);
+ }
+
+ // 후위 순회 출력
+ postOrder(root);
+ }
+
+ public static void postOrder(TreeNode root) {
+ if (root == null) return;
+
+ postOrder(root.left);
+ postOrder(root.right);
+
+ System.out.println(root.val);
+ }
+
+ public static TreeNode insert(TreeNode root, int val) {
+ if (root == null) return new TreeNode(val);
+
+ if (root.val > val) {
+ root.left = insert(root.left, val);
+ } else {
+ root.right = insert(root.right, val);
+ }
+
+ return root;
+ }
+
+ // 이진 트리 노드 클래스
+ public static class TreeNode {
+ TreeNode left;
+ TreeNode right;
+ int val;
+
+ TreeNode(int val) {
+ this.val = val;
+ this.left = null;
+ this.right = null;
+ }
+ }
+}
+~~~
diff --git "a/hagyoung99/17\354\243\274\354\260\250.md" "b/hagyoung99/17\354\243\274\354\260\250.md"
new file mode 100644
index 0000000..47d5a1d
--- /dev/null
+++ "b/hagyoung99/17\354\243\274\354\260\250.md"
@@ -0,0 +1,58 @@
+[5639.이진 검색 트리](https://www.acmicpc.net/problem/5639)
+
+
+
+```java
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
+public class Main {
+ public static void main(String[] args) throws IOException {
+ BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
+ Node root = new Node(Integer.parseInt(br.readLine()));
+
+ String input;
+ while ((input = br.readLine()) != null) {
+ root.insert(Integer.parseInt(input));
+ }
+
+ preOrder(root);
+ }
+
+ static void preOrder(Node node){
+ if(node==null) return;
+ preOrder(node.left);
+ preOrder(node.right);
+ System.out.println(node.val);
+ }
+
+ static class Node {
+ int val;
+ Node left;
+ Node right;
+ Node() {}
+ Node(int val) { this.val = val; }
+ Node(int val, Node left, Node right) {
+ this.val = val;
+ this.left = left;
+ this.right = right;
+ }
+ void insert(int val) {
+ if(val < this.val) {
+ if(this.left == null){
+ this.left = new Node(val);
+ } else {
+ this.left.insert(val);
+ }
+ } else {
+ if(this.right == null){
+ this.right = new Node(val);
+ } else {
+ this.right.insert(val);
+ }
+ }
+ }
+ }
+}
+```
diff --git a/taehan/week6/Tweet_Engine.md b/taehan/week6/Tweet_Engine.md
new file mode 100644
index 0000000..a1b55ed
--- /dev/null
+++ b/taehan/week6/Tweet_Engine.md
@@ -0,0 +1,75 @@
+## 문제 정의
+
+1. 트위터의 기능을 유사하게 일부 구현하는 클래스
+2. 이러한 일반 기능 구현은 언제나 그렇듯이 예외처리를 얼마나 잘 고려하느냐가 관건이다
+3. 릿코드 특성상 시간 제한은 없을 것으로 예상됨
+
+## 예외사항
+
+1. follow/unfollow 를 본인을 할 때
+ 1. 어차피 자신의 뉴스피드에는 자신의 포스트가 뜨니까 괜찮을 듯
+2. follow/unfollow 를 두 번 할 때
+ 1. 일단 배제하고 돌려보자
+
+## 1차 코드 작성
+
+```kotlin
+class Twitter() {
+ val posts = mutableListOf>()
+ val followers = mutableMapOf>()
+
+ fun postTweet(userId: Int, tweetId: Int) {
+ posts.add(0,Pair(userId, tweetId))
+ }
+
+ fun getNewsFeed(userId: Int): List {
+ val searchCount = 10
+ val result = mutableListOf()
+ val followees = followers.getOrDefault(userId, mutableListOf())
+ val allPosts = posts.filter { it.first == userId || followees.contains(it.first) }
+
+ allPosts.forEach {
+ if (result.size < searchCount) {
+ result.add(it.second)
+ }
+ }
+
+ return result
+ }
+
+ fun follow(followerId: Int, followeeId: Int) {
+ followers[followerId] = followers.getOrDefault(followerId, mutableListOf()).apply {
+ add(followeeId)
+ }
+ }
+
+ fun unfollow(followerId: Int, followeeId: Int) {
+ followers[followerId]?.remove(followeeId)
+ }
+
+}
+
+/**
+ * Your Twitter object will be instantiated and called as such:
+ * var obj = Twitter()
+ * obj.postTweet(userId,tweetId)
+ * var param_2 = obj.getNewsFeed(userId)
+ * obj.follow(followerId,followeeId)
+ * obj.unfollow(followerId,followeeId)
+ */
+```
+
+
+
+런타임 155ms, 메모리 36.24MB
+
+## 풀이 복기
+
+1. 복잡하게 생각할 거리는 딱히 없었고 예외처리도 별 게 없었던 것 같다.
+2. 자바는 지원하는 함수가 너무 많다…
+ 1. 업무할땐 이런 기능 없어서 하나하나 내가 다 구현했는데
+ 1. 오버라이딩도 못하게 막아놓아서 더 힘든데..
+3. 속도랑 메모리가 왜 잘나왔는진 모르겠다.
+ 1. 그나마 자바의 기본 기능이 최적화가 잘 된 편이다정도…?
+4. 릿코드에서 다른 사람들의 예시를 보니 우선순위 큐를 사용한 사람들이 많다
+ 1. 굳이 쓸 필요는 없었던 것 같은데…?
diff --git a/taehan/week7/leastClosedBrachet.md b/taehan/week7/leastClosedBrachet.md
new file mode 100644
index 0000000..760e3e4
--- /dev/null
+++ b/taehan/week7/leastClosedBrachet.md
@@ -0,0 +1,91 @@
+## 문제 정의
+
+- (()), (()()) 는 올바른 괄호 문자열이다.
+- 괄호 문자열은 결국 ( 와 ) 가 조건에 부합해야 하며, 이는 생각을 어렵게 만든다
+ - n*n 이 사실 가장 먼저 드는 생각임
+- 문제는 백준 특성상 시간 초과가 분명히 발생할 것이고 문제의 풀이는 그냥 전부 탐색하면 되니 시간을 줄이는 게 가장 중요한 관건이다.
+ - nlogn 이 직관상 가장 부합할 것으로 보이나 생각이 나지 않음
+- 가장 긴 팰린드롬과도 유사한 느낌이 있으나 세부 탐색 방식이 다르다.
+ - 가장 긴 팰린드롬과 이 문제의 가장 큰 차이점은
+ (())()
+ 이 가능하다는 것임
+ - 이말인 즉 2n 만에 탐색하는 방식이 불가능하며, 다른 방식을 찾아보아야 함
+
+## 풀이 논리
+
+
+
+1. 먼저 문자열을 1차로 하나씩 찾으며 닫힌 문자열인지 확인한다.
+ 1. 확인하는 방법은 좌측에서 우측으로 1씩 움직이며 ( 일때 열고 ) 일때 닫으며 열린 후 닫혔는지 확인하는 것이다.
+ 1. 이는 빗물 트래핑과 유사한 방식이다.
+ 1. 열릴 때마다 높이를 1 높이고, 닫힐 때마다 높이를 1 낮춘다고 가정하면 완전히 동일한 접근도 가능하다.
+ 2. 쓰고 지웠는데
+ 1. 심지어 방법도 n*n 으로 만들었었는데..
+2. 확인되었다면 그 길이를 담는 리스트를 만든다.
+ 1. ex: )4)(6(
+ 2. 여기에서 연속된 일부를 빼는 것이 관건이며, 어차피 (로 시작하여 열린 문자열은 ) 로 닫힐 수 없으니 배제하면 된다.
+3. 4)(6
+같이 더했을 때 가장 큰 숫자를 가진 닫힌 문자열들을 찾으면 끝난다.
+- 위와 같이 반복 횟수를 줄이는 관건은 1번의 역할이 가장 크며, 다음은 N 의 반복만 시행하면 끝난다.
+ - 이마저도 첫번째 반복 안에서 실행할 수 있음
+ - 닫힌 문자열의 길이를 확정했을 때마다 1회씩
+- 2-b 의 조건을 생각해보면 열린 문자열을 굳이 문자열에 포함할 필요 없이 닫힌 문자열의 길이만 리스트로 넣는 게 조금 더 빠를 것으로 보임
+ - 문자를 추가해서 만들라면 포함해야겠지만 이는 필요 없는 가정이다.
+
+## 1차 코드 작성
+
+```jsx
+import java.io.BufferedReader
+import java.io.InputStreamReader
+
+fun main() {
+ // var br = BufferedReader(InputStreamReader(System.`in`))
+ // var bw = System.out.bufferedWriter()
+ // var input: String = br.readLine()
+
+ var input = ")(()(())))(()()(()()("
+
+ var ret = checkIsClosedBracket(input)
+
+// bw.write("$ret\n")
+// bw.flush()
+}
+
+fun checkIsClosedBracket(input: String): Int {
+ var opened = 0
+ var closed = 0
+ var cutFlag = true
+ var listOfClosed = mutableListOf()
+
+ for (i in input.indices) {
+ if (input[i] == ')') {
+ if (opened > 0) {
+ closed++
+
+ if(cutFlag) {
+ listOfClosed.add(closed + )
+ cutFlag = false
+ } else {
+ listOfClosed[listOfClosed.size - 1] = closed * 2
+ }
+
+ } else {
+ opened = 0
+ closed = 0
+ cutFlag = true
+ }
+
+ } else {
+ opened++
+ }
+ println("i: $i, text: ${input[i]}, opened: $opened, closed: $closed, listOfClosed: $listOfClosed")
+ }
+
+ return listOfClosed.size
+}
+```
+
+to be continued….
diff --git a/taehan/week8/kthsmallest.md b/taehan/week8/kthsmallest.md
new file mode 100644
index 0000000..540b0b5
--- /dev/null
+++ b/taehan/week8/kthsmallest.md
@@ -0,0 +1,66 @@
+## 문제 정의
+
+1. matrix 의 크기 n 은 정사각형 크기이다.
+2. n*n 보다 좋은 방법을 찾아야 한다.
+3. matrix 는 row, column 별로 정렬되어 있다.
+4. matrix의 형태를 보니 바로 퀵, 삽입 정렬이 생각난다.
+5. 그래도 혹시 모르니 바로 인덱스로 변환해서 돌려 보자
+
+## 1차 코드 작성
+
+```jsx
+class Solution {
+ fun kthSmallest(matrix: Array, k: Int): Int {
+ var inputIndex = k - 1
+ var m = matrix[0].size
+ var leftIndex = (inputIndex / m)
+ var rightIndex = (inputIndex % m)
+ return matrix[leftIndex][rightIndex]
+ }
+}
+```
+
+![[[1,2],[1,3]] 에서 아웃이 1이 나와야 하나 2로 나옴](https://prod-files-secure.s3.us-west-2.amazonaws.com/213ef69f-0d1e-4d21-9468-12fe04ca65b6/a1424044-855b-44e9-b924-b2a0004135ed/Untitled.png)
+
+[[1,2],[1,3]] 에서 아웃이 1이 나와야 하나 2로 나옴
+
+## 풀이 복기
+
+- 당연히 날먹은 안된다
+
+## 풀이 논리
+
+1. 먼저 입력받은 nxn matrix 의 정렬을 진행한다.
+ 1. 당연히 nlogn 의 효율을 보이는 퀵 정렬이 좋을 것이다.
+ 1. 퀵 정렬은 자바에서 지원하는 기능이 있었던 것 같다.
+ 2. 다만 같은 column 내에서는 정렬되어 있다는 점을 고려하면 삽입 정렬을 조금 수정하여 사용해도 그리 나쁘지 않을 것으로 예상된다.
+ 3. 이진 탐색을 포함하여 사용 시예상 시간 복잡도는 nlogn
+2. 이후 정렬한 array 에서 바로 리턴한다.
+
+## 1차 코드 작성
+
+```jsx
+class Solution {
+ fun kthSmallest(matrix: Array, k: Int): Int {
+ return convert2SortedFlatList(matrix)[k-1]
+ }
+ fun convert2SortedFlatList(matrix: Array): IntArray {
+ val flatArray = matrix.flatMap { it.toList() }
+ flatArray.sort()
+ return flatArray
+ }
+}
+```
+
+
+
+런타임 305ms, 메모리44.19MB
+
+## 풀이 복기
+
+1. flatten 메소드가 왜 에러가 나는지는 확인이 필요할 것 같다.
+2. 속도를 개선하려면 .flatmap().toIntArray().sort() 의 수정이 이루어져야 할 것 같다.
+ 1. 메모리 사용량이 내가 매우 적은 편임을 감안하면 다른 사람들은 직접 해쉬맵이나 변환을 이용한 것으로 보인다.
+3. 내가 생각한 것보다 재미없게 끝났다..
+
+4. 조금씩 수정해서 계속 돌려보는데, 같은 코드로도 속도가 달라진다..
diff --git "a/\354\236\241\353\266\200/17\354\243\274\354\260\250/\354\235\264\354\247\204\352\262\200\354\203\211\355\212\270\353\246\254.md" "b/\354\236\241\353\266\200/17\354\243\274\354\260\250/\354\235\264\354\247\204\352\262\200\354\203\211\355\212\270\353\246\254.md"
new file mode 100644
index 0000000..b8d7339
--- /dev/null
+++ "b/\354\236\241\353\266\200/17\354\243\274\354\260\250/\354\235\264\354\247\204\352\262\200\354\203\211\355\212\270\353\246\254.md"
@@ -0,0 +1,38 @@
+```Kotlin
+import java.io.BufferedReader
+import java.io.InputStreamReader
+
+fun main() {
+ val br = BufferedReader(InputStreamReader(System.`in`))
+ val nodes = mutableListOf()
+
+ while (true) {
+ val input = br.readLine() ?: break
+ nodes.add(input.toInt())
+ }
+
+ postOrder(nodes, 0, nodes.size - 1)
+}
+
+fun postOrder(nodes: List, start: Int, end: Int) {
+ if (start > end) return
+
+ val root = nodes[start]
+ var rightStart = end + 1
+
+ for (i in start + 1..end) {
+ if (nodes[i] > root) {
+ rightStart = i
+ break
+ }
+ }
+
+ postOrder(nodes, start + 1, rightStart - 1) // 왼쪽 서브트리
+ postOrder(nodes, rightStart, end) // 오른쪽 서브트리
+ println(root) // 루트 출력
+}
+```
+
+현재 값보다 큰 값을 찾는다.
+
+큰 값을 기준으로 Left / Right 가 나눠지기 때문이다.
diff --git "a/\354\236\241\353\266\200/17\354\243\274\354\260\250/\354\235\264\354\247\204\355\212\270\353\246\254\354\235\230\354\247\201\352\262\275.md" "b/\354\236\241\353\266\200/17\354\243\274\354\260\250/\354\235\264\354\247\204\355\212\270\353\246\254\354\235\230\354\247\201\352\262\275.md"
new file mode 100644
index 0000000..e4d4366
--- /dev/null
+++ "b/\354\236\241\353\266\200/17\354\243\274\354\260\250/\354\235\264\354\247\204\355\212\270\353\246\254\354\235\230\354\247\201\352\262\275.md"
@@ -0,0 +1,27 @@
+```Kotlin
+import utils.TreeNode
+import kotlin.math.max
+
+class DiameterOfBinaryTree {
+ private var longest:Int = 0
+
+ private fun dfs(root: TreeNode?): Int {
+ if (root == null) {
+ return -1
+ }
+
+ val left = dfs(root.left)
+ val right = dfs(root.right)
+
+ longest = max(longest, left + right + 2)
+ return max(right, left) + 1
+ }
+
+ fun diameterOfBinaryTree(root: TreeNode?): Int {
+ dfs(root)
+ return longest
+ }
+}
+```
+
+leaf 노드로부터 leaf 노드가 가질 수 있는 최고의 길이를 구하여 활용할 수 있도록 한다.
diff --git "a/\354\236\241\353\266\200/17\354\243\274\354\260\250/\354\235\264\354\247\204\355\212\270\353\246\254\354\235\230\354\265\234\353\214\200\352\271\212\354\235\264.md" "b/\354\236\241\353\266\200/17\354\243\274\354\260\250/\354\235\264\354\247\204\355\212\270\353\246\254\354\235\230\354\265\234\353\214\200\352\271\212\354\235\264.md"
new file mode 100644
index 0000000..6de5087
--- /dev/null
+++ "b/\354\236\241\353\266\200/17\354\243\274\354\260\250/\354\235\264\354\247\204\355\212\270\353\246\254\354\235\230\354\265\234\353\214\200\352\271\212\354\235\264.md"
@@ -0,0 +1,25 @@
+```Kotlin
+class MaximumDepthOfBinaryTree {
+ fun recv(root: TreeNode?, depth: Int): Int {
+ if (root == null) return depth
+
+ var currentDepth = depth;
+ if (root.left != null) {
+ currentDepth = max(recv(root.left, depth+1), currentDepth)
+ }
+
+ if (root.right != null) {
+ currentDepth = max(recv(root.right, depth+1), currentDepth)
+ }
+
+ return currentDepth
+ }
+
+ fun maxDepth(root: TreeNode?): Int {
+ if (root == null) return 0
+ return recv(root, 1);
+ }
+}
+```
+
+재귀를 통해서, 가장 깊이 들어갈 수 있는 값을 구한다.
\ No newline at end of file