Skip to content

Commit 80aaf9a

Browse files
authored
[JooKangsan] 2025.02.06 (#38)
* fix: 에러 수정 * 문자열 뒤집기 / 기초 * Ctrl Z / 기초 * 크레인 인형뽑기 / 중급 * 다트게임 / 중급 * 순서쌍의 갯수 / 기초 * 점의 위치 구하기 / 기초 * 로그인 성공? / 기초 * 이상한 정렬 / 기초 * 카드 뭉치 / 기초 * feat: md 파일 추가 * 공원 산책 / 중급 * 햄버거 만들기 / 중급 * 모스부호 / 기초 * A로B만들기 / 기초 * 진료 순서 정하기 /기초 * 완주하지 못한 사람 / 기초 * hash.md 파일추가 * 키패드 / 심화 * tree.md 파일 추가 * 이진 트리의 중위 순위 / 기초 * SameTree / 기초 * 이진 트리 반전 / 기초 * 이진 트리 레벨 순서 순회
1 parent 19a142d commit 80aaf9a

14 files changed

+604
-0
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
function solution(participant, completion) {
2+
participant.sort();
3+
completion.sort();
4+
5+
return participant.find((name, i) => name !== completion[i]);
6+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
function solution(emergency) {
2+
const orderMap = {};
3+
4+
const sorted = [...emergency].sort((a, b) => b - a);
5+
6+
sorted.forEach((value, index) => {
7+
orderMap[value] = index + 1;
8+
});
9+
10+
return emergency.map(value => orderMap[value]);
11+
}

JooKangSan/[week4]hash/Hash.md

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
# JavaScript Hash(Map) Algorithm
2+
3+
## 1. 해시(Hash)란?
4+
키-값 쌍으로 데이터를 저장하는 자료구조로, 빠른 데이터 검색을 지원합니다.
5+
6+
### 기본 특성
7+
- 고유한 키를 통해 값에 접근
8+
- 상수 시간 O(1)의 검색 복잡도
9+
- 충돌 처리 메커니즘 필요
10+
11+
## 2. 자바스크립트에서 해시 구현 방법
12+
13+
### 2.1 객체를 사용한 기본 구현
14+
```javascript
15+
// 기본적인 객체 사용
16+
const hash = {};
17+
18+
// 데이터 추가
19+
hash['key'] = 'value';
20+
21+
// 데이터 접근
22+
console.log(hash['key']); // 'value'
23+
24+
// 데이터 삭제
25+
delete hash['key'];
26+
27+
// 키 존재 확인
28+
console.log('key' in hash);
29+
```
30+
31+
### 2.2 Map 객체 사용
32+
```javascript
33+
// Map 객체 생성
34+
const hashMap = new Map();
35+
36+
// 데이터 추가
37+
hashMap.set('key', 'value');
38+
39+
// 데이터 접근
40+
console.log(hashMap.get('key')); // 'value'
41+
42+
// 데이터 삭제
43+
hashMap.delete('key');
44+
45+
// 키 존재 확인
46+
console.log(hashMap.has('key'));
47+
```
48+
49+
## 3. 해시의 주요 활용 사례
50+
51+
### 3.1 빈도수 계산
52+
```javascript
53+
function countFrequency(arr) {
54+
const frequency = {};
55+
56+
for(const item of arr) {
57+
frequency[item] = (frequency[item] || 0) + 1;
58+
}
59+
60+
return frequency;
61+
}
62+
63+
// 사용 예시
64+
const arr = ['a', 'b', 'a', 'c', 'b', 'a'];
65+
console.log(countFrequency(arr)); // { a: 3, b: 2, c: 1 }
66+
```
67+
68+
### 3.2 중복 제거
69+
```javascript
70+
function removeDuplicates(arr) {
71+
const hash = {};
72+
const result = [];
73+
74+
for(const item of arr) {
75+
if(!hash[item]) {
76+
hash[item] = true;
77+
result.push(item);
78+
}
79+
}
80+
81+
return result;
82+
}
83+
84+
// 사용 예시
85+
console.log(removeDuplicates([1, 2, 2, 3, 3, 3])); // [1, 2, 3]
86+
```
87+
88+
### 3.3 Two Sum 문제
89+
```javascript
90+
function findTwoSum(nums, target) {
91+
const hash = {};
92+
93+
for(let i = 0; i < nums.length; i++) {
94+
const complement = target - nums[i];
95+
96+
if(complement in hash) {
97+
return [hash[complement], i];
98+
}
99+
100+
hash[nums[i]] = i;
101+
}
102+
103+
return null;
104+
}
105+
106+
// 사용 예시
107+
console.log(findTwoSum([2, 7, 11, 15], 9)); // [0, 1]
108+
```
109+
110+
## 4. 성능 고려사항
111+
112+
### 4.1 시간 복잡도
113+
- 삽입: O(1)
114+
- 삭제: O(1)
115+
- 검색: O(1)
116+
- 충돌이 많은 경우: O(n)
117+
118+
### 4.2 공간 복잡도
119+
- O(n), 여기서 n은 저장된 키-값 쌍의 수
120+
121+
### 4.3 주의사항
122+
1. 해시 충돌 처리
123+
- 체이닝
124+
- 개방 주소법
125+
126+
2. 메모리 사용
127+
- 적절한 초기 크기 설정
128+
- 동적 크기 조정
129+
130+
3. 키 선택
131+
- 고른 분포의 해시값
132+
- 효율적인 해시 함수
133+
134+
## 5. Map vs Object 비교
135+
136+
### 5.1 Map의 장점
137+
- 키로 모든 타입 사용 가능
138+
- 순서 보장
139+
- 크기를 쉽게 알 수 있음
140+
- 순회가 더 편리함
141+
142+
### 5.2 Object의 장점
143+
- 리터럴 문법 지원
144+
- JSON과의 호환성
145+
- 프로토타입 체인
146+
- 더 적은 메모리 사용
147+
148+
### 5.3 사용 예시
149+
```javascript
150+
// Map
151+
const map = new Map();
152+
map.set(1, 'one');
153+
map.set({}, 'object');
154+
map.set(() => {}, 'function');
155+
156+
// Object
157+
const obj = {
158+
1: 'one',
159+
'key': 'value'
160+
};
161+
```
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
function solution(before, after) {
2+
const hash = {};
3+
4+
for(let char of before) {
5+
hash[char] = (hash[char] || 0) + 1;
6+
}
7+
8+
for(let char of after) {
9+
if(!hash[char]) return 0;
10+
hash[char]--;
11+
}
12+
13+
// 모든 값이 0이면 1 반환
14+
return Object.values(hash).every(count => count === 0) ? 1 : 0;
15+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
function solution(name, yearning, photo) {
2+
const scoreMap = {};
3+
4+
name.forEach((n, i) => scoreMap[n] = yearning[i]);
5+
6+
return photo.map(p =>
7+
p.reduce((sum, person) => sum + (scoreMap[person] || 0), 0)
8+
);
9+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
function solution(letter) {
2+
// 모스부호 해시맵 생성
3+
const morse = {
4+
'.-':'a','-...':'b','-.-.':'c','-..':'d','.':'e','..-.':'f',
5+
'--.':'g','....':'h','..':'i','.---':'j','-.-':'k','.-..':'l',
6+
'--':'m','-.':'n','---':'o','.--.':'p','--.-':'q','.-.':'r',
7+
'...':'s','-':'t','..-':'u','...-':'v','.--':'w','-..-':'x',
8+
'-.--':'y','--..':'z'
9+
};
10+
11+
return letter.split(' ').map(match => morse[match]).join('');
12+
}

JooKangSan/[week4]hash/Ranking.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
2+
function solution(score) {
3+
const sum = score.map((el) => (el[0] + el[1]));
4+
let sortedSum = sum.slice().sort((a, b) => b - a);
5+
6+
return sum.map((el) => sortedSum.indexOf(el) + 1);
7+
}

JooKangSan/[week4]hash/keypad.js

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
function solution(numbers, hand) {
2+
// 키패드를 열 기준 2차원 배열로 정의
3+
const keypad = [
4+
[1, 4, 7, "*"], // 왼쪽 열
5+
[2, 5, 8, 0], // 가운데 열
6+
[3, 6, 9, "#"] // 오른쪽 열
7+
]
8+
9+
// 각 숫자의 좌표를 Map으로 저장
10+
const getPos = new Map()
11+
// 열과 행 기준으로 좌표 저장
12+
for(let x = 0; x < keypad.length; x++) {
13+
for(let y = 0; y < keypad[x].length; y++) {
14+
getPos.set(keypad[x][y], [x, y])
15+
}
16+
}
17+
18+
let left = getPos.get("*") // 왼손 시작 위치
19+
let right = getPos.get("#") // 오른손 시작 위치
20+
21+
// 두 좌표 사이의 거리 계산
22+
const getDist = ([x1, y1], [x2, y2]) =>
23+
Math.abs(x1 - x2) + Math.abs(y1 - y2)
24+
25+
return numbers.map(num => {
26+
const target = getPos.get(num)
27+
28+
// 첫 번째 열은 무조건 왼손
29+
if(target[0] === 0) {
30+
left = target
31+
return "L"
32+
}
33+
34+
// 세 번째 열은 무조건 오른손
35+
if(target[0] === 2) {
36+
right = target
37+
return "R"
38+
}
39+
40+
// 가운데 열인 경우 거리 계산
41+
const leftDist = getDist(left, target)
42+
const rightDist = getDist(right, target)
43+
44+
// 거리가 같으면 주손잡이 기준
45+
if(leftDist === rightDist) {
46+
if(hand === "right") {
47+
right = target
48+
return "R"
49+
} else {
50+
left = target
51+
return "L"
52+
}
53+
}
54+
55+
// 거리가 다르면 가까운 손 사용
56+
if(leftDist < rightDist) {
57+
left = target
58+
return "L"
59+
} else {
60+
right = target
61+
return "R"
62+
}
63+
}).join("")
64+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
function inorderTraversal(root) {
2+
const result = [];
3+
4+
function inorder(node) {
5+
if (!node) return;
6+
7+
inorder(node.left);
8+
result.push(node.val);
9+
inorder(node.right);
10+
}
11+
12+
inorder(root);
13+
return result;
14+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/**
2+
* Definition for a binary tree node.
3+
* function TreeNode(val, left, right) {
4+
* this.val = (val===undefined ? 0 : val)
5+
* this.left = (left===undefined ? null : left)
6+
* this.right = (right===undefined ? null : right)
7+
* }
8+
*/
9+
/**
10+
* @param {TreeNode} root
11+
* @return {number[][]}
12+
*/
13+
function levelOrder(root){
14+
if (!root) return [];
15+
16+
const result = [];
17+
const queue = [root];
18+
19+
while (queue.length > 0) {
20+
const levelSize = queue.length;
21+
const levelNodes = [];
22+
23+
for (let i = 0; i < levelSize; i++) {
24+
const node = queue.shift();
25+
levelNodes.push(node.val);
26+
27+
if (node.left) queue.push(node.left);
28+
if (node.right) queue.push(node.right);
29+
}
30+
31+
result.push(levelNodes);
32+
}
33+
34+
return result;
35+
};
36+

0 commit comments

Comments
 (0)