-
-
Notifications
You must be signed in to change notification settings - Fork 250
[SeongA] WEEK 15 solutions #1964
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
마지막까지 깔끔하게 잘 푸셨네요! 그동안 수고 많으셨어요!
| @@ -0,0 +1,26 @@ | |||
| class Solution { | |||
| // Time O(N) | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
알고달레 풀이 1의 index처럼 for 반복문이 시간 병목이 됩니다. 선형 시간으로 줄일 수는 있던데 좀 어렵더라고요!
| // Time O(N) | |
| // Time O(N^2) |
| } | ||
| } | ||
|
|
||
| rootNode.left = buildTree(Array(preorder[1..<rootIndex + 1]), Array(inorder[0..<rootIndex + 1])) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
preorder.count와 inorder.count가 같음을 보장하려면 이렇게 줄일 수 있어요:
| rootNode.left = buildTree(Array(preorder[1..<rootIndex + 1]), Array(inorder[0..<rootIndex + 1])) | |
| rootNode.left = buildTree(Array(preorder[1..<rootIndex + 1]), Array(inorder[0..<rootIndex])) |
| // Space O(N) | ||
| func buildTree(_ preorder: [Int], _ inorder: [Int]) -> TreeNode? { | ||
| if preorder.isEmpty { | ||
| return nil | ||
| } | ||
|
|
||
| let totalCount = preorder.count | ||
| let rootNode = TreeNode(preorder[0]) | ||
| var rootIndex = 0 | ||
|
|
||
| for (index, value) in inorder.enumerated() { | ||
| if value == rootNode.val { | ||
| rootIndex = index | ||
| break | ||
| } | ||
| } | ||
|
|
||
| rootNode.left = buildTree(Array(preorder[1..<rootIndex + 1]), Array(inorder[0..<rootIndex + 1])) | ||
| rootNode.right = buildTree(Array(preorder[1 + rootIndex..<totalCount]), Array(inorder[1 + rootIndex..<totalCount])) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
마찬가지로 알고달레 풀이 1에서처럼 Slice가 시간과 공간 병목이 될 수 있어요. 그래서 Slice 대신 Two Pointers를 사용하거나 또는 Swift에서는 다음과 같이 Array 형변환을 피하도록 고치면 선형 공간으로는 최적화할 수 있습니다:
| // Space O(N) | |
| func buildTree(_ preorder: [Int], _ inorder: [Int]) -> TreeNode? { | |
| if preorder.isEmpty { | |
| return nil | |
| } | |
| let totalCount = preorder.count | |
| let rootNode = TreeNode(preorder[0]) | |
| var rootIndex = 0 | |
| for (index, value) in inorder.enumerated() { | |
| if value == rootNode.val { | |
| rootIndex = index | |
| break | |
| } | |
| } | |
| rootNode.left = buildTree(Array(preorder[1..<rootIndex + 1]), Array(inorder[0..<rootIndex + 1])) | |
| rootNode.right = buildTree(Array(preorder[1 + rootIndex..<totalCount]), Array(inorder[1 + rootIndex..<totalCount])) | |
| // Space O(N) | |
| func buildTree(_ preorder: [Int], _ inorder: [Int]) -> TreeNode? { | |
| return buildTree(preorder[...], inorder[...]) | |
| } | |
| func buildTree(_ preorder: ArraySlice<Int>, _ inorder: ArraySlice<Int>) -> TreeNode? { | |
| if preorder.isEmpty { | |
| return nil | |
| } | |
| let rootNode = TreeNode(preorder.first!) | |
| var rootIndex = 0 | |
| for (index, value) in inorder.enumerated() { | |
| if value == rootNode.val { | |
| rootIndex = index | |
| break | |
| } | |
| } | |
| rootNode.left = buildTree(preorder[preorder.startIndex + 1..<preorder.startIndex + rootIndex + 1], inorder[inorder.startIndex..<inorder.startIndex + rootIndex]) | |
| rootNode.right = buildTree(preorder[preorder.startIndex + 1 + rootIndex..<preorder.endIndex], inorder[inorder.startIndex + 1 + rootIndex..<inorder.endIndex]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
오! 이건 생각지도 못한 부분이네요 조금 더 최적화할 수 있는 방법을 배워갑니다
| @@ -0,0 +1,29 @@ | |||
| class Solution { | |||
| // Time O(M * N) | |||
| // Space O(N) | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| // Space O(N) | |
| // Space O(M + N) |
| if let root = root, let subRoot = subRoot { | ||
| if root.val == subRoot.val { | ||
| return dfs(root.left, subRoot: subRoot.left) && dfs(root.right, subRoot: subRoot.right) || isSubtree(root.left, subRoot) || isSubtree(root.right, subRoot) | ||
| } | ||
| return isSubtree(root.left, subRoot) || isSubtree(root.right, subRoot) | ||
| } | ||
|
|
||
| return false | ||
| } | ||
|
|
||
| private func dfs(_ root: TreeNode?, subRoot: TreeNode?) -> Bool { | ||
| if root == nil && subRoot == nil { | ||
| return true | ||
| } | ||
|
|
||
| if let root = root, let subRoot = subRoot { | ||
| if root.val == subRoot.val { | ||
| return dfs(root.left, subRoot: subRoot.left) && dfs(root.right, subRoot: subRoot.right) | ||
| } | ||
| } | ||
|
|
||
| return false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
사소한 간소화입니다 ㅎㅎ
| if let root = root, let subRoot = subRoot { | |
| if root.val == subRoot.val { | |
| return dfs(root.left, subRoot: subRoot.left) && dfs(root.right, subRoot: subRoot.right) || isSubtree(root.left, subRoot) || isSubtree(root.right, subRoot) | |
| } | |
| return isSubtree(root.left, subRoot) || isSubtree(root.right, subRoot) | |
| } | |
| return false | |
| } | |
| private func dfs(_ root: TreeNode?, subRoot: TreeNode?) -> Bool { | |
| if root == nil && subRoot == nil { | |
| return true | |
| } | |
| if let root = root, let subRoot = subRoot { | |
| if root.val == subRoot.val { | |
| return dfs(root.left, subRoot: subRoot.left) && dfs(root.right, subRoot: subRoot.right) | |
| } | |
| } | |
| return false | |
| if let root = root, let subRoot = subRoot { | |
| return dfs(root, subRoot) || isSubtree(root.left, subRoot) || isSubtree(root.right, subRoot) | |
| } | |
| return root == nil && subRoot == nil | |
| } | |
| private func dfs(_ root: TreeNode?, _ subRoot: TreeNode?) -> Bool { | |
| if let root = root, let subRoot = subRoot { | |
| return root.val == subRoot.val && dfs(root.left, subRoot.left) && dfs(root.right, subRoot.right) | |
| } | |
| return root == nil && subRoot == nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
짧으면서도 이해하기 쉬운 코드 덕분에 공부가 되었습니다.
답안 제출 문제
작성자 체크 리스트
In Review로 설정해주세요.검토자 체크 리스트
Important
본인 답안 제출 뿐만 아니라 다른 분 PR 하나 이상을 반드시 검토를 해주셔야 합니다!