Skip to content

[sophia] Week2 답안 제출 #350

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

Merged
merged 9 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,66 @@
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {number[]} preorder
* @param {number[]} inorder
* @return {TreeNode}
*/
let buildTree = function (preorder, inorder) {
if (preorder.length === 0 || inorder.length === 0) {
return null;
}

// 중위 순회의 값과 인덱스를 매핑하는 Map 생성
const inorderIndexMap = new Map();
inorder.forEach((value, index) => {
inorderIndexMap.set(value, index);
});

// 재귀적 트리 구성 함수
function build(preStart, preEnd, inStart, inEnd) {
if (preStart > preEnd || inStart > inEnd) {
return null;
}

// 전위순회 배열에서 루트 노드를 얻기
const rootVal = preorder[preStart];
const root = new TreeNode(rootVal);

// 중위순회 배열에서 루트 노드의 인덱스 찾기
const rootIndexInInorder = inorderIndexMap.get(rootVal);

// 왼쪽 서브트리 크기 계산
const leftSize = rootIndexInInorder - inStart;

// 재귀적으로 왼쪽과 오른쪽 서브트리를 생성
root.left = build(
preStart + 1,
preStart + leftSize,
inStart,
rootIndexInInorder - 1
);
root.right = build(
preStart + leftSize + 1,
preEnd,
rootIndexInInorder + 1,
inEnd
);

return root;
}

return build(0, preorder.length - 1, 0, inorder.length - 1);
};

/*
1. 시간복잡도: O(n)
- 트리의 모든 노드를 한 번씩 처리해야함
2. 공간복잡도: O(n)
- map 저장공간, 재귀호출 스택, 트리노드 저장공간 -> O(n)
*/
16 changes: 16 additions & 0 deletions contains-duplicate/seona926.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/**
* @param {number[]} nums
* @return {boolean}
*/
let containsDuplicate = function (nums) {
let counts = {};

return nums.some((num) => {
if (counts[num] === undefined) {
counts[num] = 1;
return false;
} else {
return true;
}
});
};
30 changes: 30 additions & 0 deletions counting-bits/seona926.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/**
* @param {number} n
* @return {number[]}
*/
let countBits = function (n) {
let result = [];

for (let i = 0; i <= n; i++) {
let binaryString = i.toString(2);

let count = 0;
for (let item of binaryString) {
if (item === "1") {
count++;
}
}

result.push(count);
}

return result;
};

/*
1. 시간복잡도 : O(nlogn)
- 이진수 변환, 이진수 중 1의 개수를 세는 루프의 시간 복잡도: O(log i)
- 작업이 총 n번 일어남
2. 공간복잡도 : O(n)
- result 배열의 공간 복잡도가 O(n)
*/
43 changes: 43 additions & 0 deletions decode-ways/seona926.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/**
* @param {string} s
* @return {number}
*/
let numDecodings = function (s) {
// 입력받은 숫자가 decode될 수 있는 가짓수를 리턴하기
const n = s.length;
if (n === 0) return 0;

// dp[i]는 s[0...i-1]까지의 부분 문자열이 해석될 수 있는 방법의 수를 저장
const dp = new Array(n + 1).fill(0);

// 빈 문자열은 하나의 방법으로 해석될 수 있음 (아무것도 선택하지 않는 방법)
dp[0] = 1;

// 첫 글자가 '0'이 아니라면, 한 가지 방법으로 해석될 수 있음
dp[1] = s[0] === "0" ? 0 : 1;

for (let i = 2; i <= n; i++) {
const oneDigit = parseInt(s.slice(i - 1, i)); // 마지막 한 글자
const twoDigits = parseInt(s.slice(i - 2, i)); // 마지막 두 글자

// 한 글자가 유효하다면, 그 글자를 포함하는 모든 방법을 추가
if (oneDigit >= 1 && oneDigit <= 9) {
dp[i] += dp[i - 1];
}

// 두 글자가 유효하다면, 그 두 글자를 포함하는 모든 방법을 추가
if (twoDigits >= 10 && twoDigits <= 26) {
dp[i] += dp[i - 2];
}
}

return dp[n];
};

/*
1. 시간복잡도 : O(n)
- 반복문의 시간복잡도
2. 공간복잡도 : O(n)
- dp 배열의 공간 복잡도
*/

19 changes: 19 additions & 0 deletions number-of-1-bits/seona926.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* @param {number} n
* @return {number}
*/
let hammingWeight = function (n) {
let count = 0;
let sum = n;

while (sum > 0) {
// n에서 가장 오른쪽 비트가 1인 경우 count 증가
if (sum % 2 === 1) {
count++;
}
// sum을 2로 나누어서 다음 비트를 확인
sum = Math.floor(sum / 2);
}

return count;
};
41 changes: 41 additions & 0 deletions valid-anagram/seona926.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/**
* @param {string} s
* @param {string} t
* @return {boolean}
*/
let isAnagram = function (s, t) {
let cntObj = {};

s.split("").forEach((item) => {
if (cntObj[item]) {
++cntObj[item];
} else {
cntObj[item] = 1;
}
});

for (let item of t) {
if (cntObj[item] === undefined || cntObj[item] < 1) {
return false;
} else {
--cntObj[item];
}
}

for (let count of Object.values(cntObj)) {
if (count > 0) {
return false;
}
}

return true;
};

/*
1. 시간복잡도 : O(n)
각 반복문의 시간복잡도가 모두 O(n)

2. 공간복잡도 : O(n)
주어진 문자열인 s와 t갯수만큼 공간을 차지함
*/

Loading