Skip to content
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

[윤태권] Week2 문제 풀이 #353

Merged
merged 6 commits into from
Aug 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* https://www.algodale.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/
*
* <풀이1 기준> 시도!
* - 공간 복잡도: O(N^2) - Java 에서는 Call-by-value, 메서드 호출 시 인자 값이 복사되어 전달됨 / 배열 길이에 따라서 재귀 호출 스택이 점점 깊어짐 (각 호출마다 서브 배열 생성)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

공간 복잡도가 O(n) 이 아니라 O(n^2) 인 이유가 무엇일까요?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dev-jonghoonpark 님 우선 리뷰 감사합니다!

재귀 함수 호출 과정에서 Call by value 로 Array 를 인자로 넘길 때 Copy가 일어난다고 판단해서 O(n^2)으로 본 것 같아요.
근데 생각해보니, Array는 값 자체를 복사하는 게 아니라 reference를 복사해서 넘기기 때문에 실질적으로 값 자체가 복사되는 것은 아닐 것 같고 - 그러면 말씀해주신 것 처럼 O(n)이 맞는 것 같네요.!

* - 시간 복잡도: inorder 배열에서 root 노드를 찾아가는 과정이 O(N), 그리고 이를 재귀 호출마다 반복하므로 O(N^2)
*/
class Solution {
public TreeNode buildTree(int[] preorder, int[] inorder) {
return buildTree(preorder, inorder, 0, 0, inorder.length - 1);
}

private TreeNode buildTree(int[] preorder, int[] inorder, int rootIdx, int inorderStartIdx, int inorderEndIdx) {
if (inorderStartIdx > inorderEndIdx) {
return null;
}

int rootVal = preorder[rootIdx];
TreeNode root = new TreeNode(rootVal);

int rootIdxOnInorder = 0;
for (int i = inorderStartIdx; i <= inorderEndIdx; i++) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

제가 자바 문법을 정확히 모르지만, 여기서 inorderEndIdx를 모두 for문으로 순회하지 않고 값의 인덱스를 찾는 방법은 없을까요? 그러면 더 시간복잡도가 줄어들 것 같아 여쭤봅니다!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

설사 그런 내장 함수를 사용하더라도, 내부적으로 결국 순회하지 않을까요? 🤔
시간 복잡도를 줄이기는 어려울 것 같고, 코드 양을 좀 줄일 수는 있을 것 같습니당 😁

if (inorder[i] == rootVal) {
rootIdxOnInorder = i;
break;
}
}

int leftLength = rootIdxOnInorder - inorderStartIdx;

root.left = buildTree(preorder, inorder, rootIdx + 1, inorderStartIdx, rootIdxOnInorder - 1);
root.right = buildTree(preorder, inorder, rootIdx + 1 + leftLength, rootIdxOnInorder + 1, inorderEndIdx);

return root;
}
}
19 changes: 19 additions & 0 deletions counting-bits/taekwon-dev.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* 공간 복잡도: O(N)
* 시간 복잡도: O(N)
* - 만약 1 ~ N 까지 각 수에 대해서 이진수로 변환한 뒤 1의 개수를 카운트 했다면? - O(NlogN)
* Note:
* - a >> b: a 의 이진 표현을 오픈쪽으로 b 비트만큼 이동
* - i >> 1: a 의 이진 표현에서 가장 오픈쪽 하나가 잘림 (i는 양수 범위를 가지므로, 왼쪽은 0으로 채워짐)
* - a & b: AND 연산
* - i & 1: 이전 결과 값이 메모되어 있으므로, 내가 궁금한 것 가장 마지막 자리 수 값이 1인지 여부.
Comment on lines +6 to +9
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

설명이 좋아용 👍

*/
class Solution {
public int[] countBits(int n) {
int[] result = new int[n + 1];
for (int i = 1; i <= n; i++) {
result[i] = result[i >> 1] + (i & 1);
}
return result;
}
}
28 changes: 28 additions & 0 deletions valid-anagram/taekwon-dev.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/**
* 처음 문제를 보고 들었던 생각: 정렬 시켜서 같으면 anagram?
* 근데, 정렬 시켜서 같다면, 결국 문자열을 구성하는 각 문자의 빈도수가 같다.
*
* 시간 복잡도: O(N)
* 공간 복잡도: O(1)
*/
class Solution {
public boolean isAnagram(String s, String t) {
if (s.length() != t.length()) return false;

int[] charCount = new int[26];

for (int i = 0; i < s.length(); i++) {
charCount[s.charAt(i) - 'a']++;
}

for (int i = 0; i < t.length(); i++) {
int index = t.charAt(i) - 'a';
charCount[index]--;
if (charCount[index] < 0) {
return false;
}
}

return true;
}
}
Loading