From 9efbbce8e2ab47d283a1d5b31ce84ba3119b4124 Mon Sep 17 00:00:00 2001 From: BadAss <66264988+jjanguiyeontaehani@users.noreply.github.com> Date: Thu, 4 Jul 2024 21:49:12 +0900 Subject: [PATCH 1/6] Create Tweet_Engine.md add week6 --- taehan/week6/Tweet_Engine.md | 75 ++++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 taehan/week6/Tweet_Engine.md 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](https://prod-files-secure.s3.us-west-2.amazonaws.com/213ef69f-0d1e-4d21-9468-12fe04ca65b6/e45a5237-6ea6-4cd3-8d7b-4562b19c74b6/Untitled.png) + +런타임 155ms, 메모리 36.24MB + +## 풀이 복기 + +1. 복잡하게 생각할 거리는 딱히 없었고 예외처리도 별 게 없었던 것 같다. +2. 자바는 지원하는 함수가 너무 많다… + 1. 업무할땐 이런 기능 없어서 하나하나 내가 다 구현했는데 + 1. 오버라이딩도 못하게 막아놓아서 더 힘든데.. +3. 속도랑 메모리가 왜 잘나왔는진 모르겠다. + 1. 그나마 자바의 기본 기능이 최적화가 잘 된 편이다정도…? +4. 릿코드에서 다른 사람들의 예시를 보니 우선순위 큐를 사용한 사람들이 많다 + 1. 굳이 쓸 필요는 없었던 것 같은데…? From 8f310505379cd3dee9e4d3ed7db531a35b99910a Mon Sep 17 00:00:00 2001 From: BadAss <66264988+jjanguiyeontaehani@users.noreply.github.com> Date: Thu, 4 Jul 2024 21:53:22 +0900 Subject: [PATCH 2/6] Create leastClosedBrachet.md add week7 --- taehan/week7/leastClosedBrachet.md | 91 ++++++++++++++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 taehan/week7/leastClosedBrachet.md 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…. From 24fa925ba2295b5d9077046823547084dd7eb2d4 Mon Sep 17 00:00:00 2001 From: BadAss <66264988+jjanguiyeontaehani@users.noreply.github.com> Date: Thu, 4 Jul 2024 21:54:13 +0900 Subject: [PATCH 3/6] Create kthsmallest.md add week8 --- taehan/week8/kthsmallest.md | 66 +++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 taehan/week8/kthsmallest.md 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](https://prod-files-secure.s3.us-west-2.amazonaws.com/213ef69f-0d1e-4d21-9468-12fe04ca65b6/9b717d7a-e83b-4143-a08a-45f21555e6c7/Untitled.png) + +런타임 305ms, 메모리44.19MB + +## 풀이 복기 + +1. flatten 메소드가 왜 에러가 나는지는 확인이 필요할 것 같다. +2. 속도를 개선하려면 .flatmap().toIntArray().sort() 의 수정이 이루어져야 할 것 같다. + 1. 메모리 사용량이 내가 매우 적은 편임을 감안하면 다른 사람들은 직접 해쉬맵이나 변환을 이용한 것으로 보인다. +3. 내가 생각한 것보다 재미없게 끝났다.. + +4. 조금씩 수정해서 계속 돌려보는데, 같은 코드로도 속도가 달라진다.. From 54d42b6d949ffeb142f8251a6138a67dac914561 Mon Sep 17 00:00:00 2001 From: NovelJava Date: Thu, 19 Sep 2024 21:33:38 +0900 Subject: [PATCH 4/6] =?UTF-8?q?17=EC=A3=BC=EC=B0=A8=20=EB=AC=B8=EC=A0=9C?= =?UTF-8?q?=20=ED=95=B4=EA=B2=B0.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...00\354\203\211\355\212\270\353\246\254.md" | 38 +++++++++++++++++++ ...54\354\235\230\354\247\201\352\262\275.md" | 27 +++++++++++++ ...34\353\214\200\352\271\212\354\235\264.md" | 25 ++++++++++++ 3 files changed, 90 insertions(+) create mode 100644 "\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" create mode 100644 "\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" create mode 100644 "\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" 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 From 5d8ef839b40e397f78176b073efd7f8c4dc2ab23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EA=B9=80=ED=95=98=EA=B2=BD?= Date: Thu, 19 Sep 2024 21:53:23 +0900 Subject: [PATCH 5/6] =?UTF-8?q?Create=2017=EC=A3=BC=EC=B0=A8.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- "hagyoung99/17\354\243\274\354\260\250.md" | 58 ++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 "hagyoung99/17\354\243\274\354\260\250.md" 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) + +![image](https://github.com/user-attachments/assets/d93165f1-3e2b-4542-837f-241c586ae299) + +```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); + } + } + } + } +} +``` From 59347ae440882d43c93e9265a812e5a63f40861b Mon Sep 17 00:00:00 2001 From: Hyunwoo Kim Date: Thu, 19 Sep 2024 21:57:49 +0900 Subject: [PATCH 6/6] =?UTF-8?q?Create=2017=EC=A3=BC=EC=B0=A8.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../17\354\243\274\354\260\250.md" | 102 ++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 "6_\353\254\270\354\236\220\354\227\264/17\354\243\274\354\260\250.md" 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; + } + } +} +~~~