Skip to content

[JANGSEYEONG] WEEK 06 solutions #1411

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 5 commits into from
May 11, 2025
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
49 changes: 49 additions & 0 deletions container-with-most-water/JANGSEYEONG.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/** 첫번째 풀이: 재귀
* 시간복잡도: O(2^n)
*/
/**
*
var maxArea = function(height) {
let maxWater = (height.length - 1) * Math.min(height[0], height[height.length-1]);
function recursion(start, end){
if(start >= end){
// start와 end가 같거나 start가 end보다 커진 경우
return;
}
maxWater = Math.max(maxWater, (end-start)*(Math.min(height[start], height[end])));
recursion(start+1, end); // 왼쪽 늘려보고
recursion(start, end-1); // 우측 늘려보기
}
recursion(0, height.length-1);
return maxWater;
};

/**
* 두번째 풀이: 투포인터
* 시간 복잡도: O(n)
*/
/**
* @param {number[]} height
* @return {number}
*/
var maxArea = function (height) {
let left = 0;
let right = height.length - 1;
let maxWater = 0;

while (left < right) {
// 현재 포인터 위치에서 물의 양 계산
const water = (right - left) * Math.min(height[left], height[right]);
maxWater = Math.max(maxWater, water);

// 더 작은 높이를 가진 쪽의 포인터를 이동
// 물의 양은 더 작은 높이에 의해 제한되기 때문에 작은 높이를 가리키던 포인터를 이동
if (height[left] < height[right]) {
left++;
} else {
right--;
}
}

return maxWater;
};
54 changes: 54 additions & 0 deletions design-add-and-search-words-data-structure/JANGSEYEONG.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
var WordDictionary = function () {
this.root = {};
};

/**
* @param {string} word
* @return {void}
*/
WordDictionary.prototype.addWord = function (word) {
let node = this.root;
for (const char of word) {
if (!node[char]) {
// 현재 문자에 해당하는 노드가 없으면 새로 생성
node[char] = { isEnd: false };
}
node = node[char]; // 다음 노드로 이동
}
node.isEnd = true; // 단어 끝 표시
};

/**
* @param {string} word
* @return {boolean}
*/
WordDictionary.prototype.search = function (word) {
function dfs(node, index) {
// 단어의 끝에 도달했으면 isEnd 값 반환
if (index === word.length) return node.isEnd;

const char = word[index];

if (node[char]) {
// 현재 문자가 노드에 존재하면 해당 노드로 이동하여 계속 검색
return dfs(node[char], index + 1);
}

if (char === ".") {
// "."인 경우: 모든 가능한 문자에 대해 검색 시도
return Object.keys(node)
.filter((key) => key !== "isEnd")
.some((key) => dfs(node[key], index + 1)); // 하나라도 true를 반환하면 true
}

return false;
}
return dfs(this.root, 0);
};

/**
* Your WordDictionary object will be instantiated and called as such:
* var obj = new WordDictionary()
* obj.addWord(word)
* var param_2 = obj.search(word)
*/
21 changes: 21 additions & 0 deletions longest-increasing-subsequence/JANGSEYEONG.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* @param {number[]} nums
* @return {number}
*/
var lengthOfLIS = function (nums) {
let sub = [nums[0]]; // 가장 첫번째 원소 일단 넣고 보기
for (const num of nums.slice(1)) {
if (num > sub[sub.length - 1]) {
// 수열의 마지막값보다 크면 무조건 추가
sub.push(num);
} else {
// 수열의 마지막값보다 작다면 이 숫자보다 큰 숫자들 중 가장 작은 숫자를 찾아서 교체
let i = 0;
while (sub[i] < num) {
i++;
}
sub[i] = num;
}
}
return sub.length;
};
48 changes: 48 additions & 0 deletions spiral-matrix/JANGSEYEONG.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/**
* @param {number[][]} matrix
* @return {number[]}
*/
var spiralOrder = function (matrix) {
let top = 0; // 상단 행 인덱스
let bottom = matrix.length - 1; // 하단 행 인덱스
let left = 0; // 좌측 열 인덱스
let right = matrix[0].length - 1; // 우측 열 인덱스

const answer = [];

// 상단, 우측, 하단, 좌측 경계를 차례로 순회하며 값을 수집
// 각 반복마다 경계가 안쪽으로 줄어듦
while (top <= bottom && left <= right) {
// 1. 상단 행 순회
for (let col = left; col <= right; col++) {
answer.push(matrix[top][col]);
}
top++; // 상단 경계를 아래로 한칸 이동
// 상단 경계가 하단 경계를 넘어가면 중단
if (top > bottom) {
break;
}
// 2. 우측 열 순회
for (let row = top; row <= bottom; row++) {
answer.push(matrix[row][right]);
}
right--; // 우측 경계를 왼쪽으로 한칸 이동
// 우측 경계가 좌측 경계를 넘어가면 중단
if (left > right) {
break;
}
// 3. 하단 행 순회
for (let col = right; col >= left; col--) {
answer.push(matrix[bottom][col]);
}
bottom--; // 하단 경계를 위쪽으로 한칸 이동

// 4. 좌측 열 순회
for (let row = bottom; row >= top; row--) {
answer.push(matrix[row][left]);
}
left++; // 좌측 경계를 우측으로 한칸 이동
}

return answer;
};
24 changes: 24 additions & 0 deletions valid-parentheses/JANGSEYEONG.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* 시간복잡도: O(n) - 문자열의 각 문자를 한 번씩만 순회
* 공간복잡도: O(n) - 최악의 경우 모든 문자가 여는 괄호일 때 스택에 n개 저장
* @param {string} s
* @return {boolean}
*/
var isValid = function (s) {
const length = s.length;
if (length % 2 === 1) return false; // 홀수일 경우 바로 return false

const MATCHES = { "(": ")", "{": "}", "[": "]" };

// 여는 괄호가 나오면 스택에 저장, 닫는 괄호가 나오면 스택의 마지막 여는 괄호와 비교
const stack = [];
for (let char of s) {
if (char in MATCHES) {
stack.push(char);
} else if (MATCHES[stack.pop()] !== char) {
return false;
}
}
// 짝이 맞으면 size 0
return stack.length === 0;
};