Skip to content
Open
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
43 changes: 43 additions & 0 deletions container-with-most-water/Baekwangho.ts
Copy link
Contributor

@radiantchoi radiantchoi Dec 19, 2025

Choose a reason for hiding this comment

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

컴퓨터가 선택하는 과정을 찾아가는 것 같아서 흥미로웠던 기억이 납니다. 면적이란 (둘 중 낮은 봉의 높이) * (인덱스 차이)라는 것까지는 저도 이전에 비슷한 문제를 풀어 본 경험이 있어 감이 왔는데, 시간복잡도에서 애를 먹었거든요. 투 포인터를 쓰자는 아이디어를 떠올리고, 둘 중 어느 쪽의 포인터를 움직여야 모든 경우의 수를 파악할 수 있을까? 라는 물음에, 컴퓨터라면 높이가 낮은 쪽을 제거하겠지! 라는 것을 떠올려 흥미로웠던 기억이 납니다. 거의 저와 같은 흐름을 타셔서 공감이 되네요.

Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/**
f((a,ax), (b,bx)) => min(ax, bx) * (b - a) (단, b > a)
라고 하자
(1,1) (2,8) => 1
(1,1) (3,6) => 2
(2,8) (3,6) => 6
(1,1) (4,2) => 3
(2,8) (4,2) => 4
(3,6) (4,2) => 2
...
(2,8) (5,5) => 15

근데 생각해보니, 순회하면서 가장 큰 왼쪽 봉을 구하고, 한칸씩 움직이며 그 봉으로부터의 너비를 계산하면 되는 것 같음.
그러다가 왼쪽 봉보다 더 큰 봉이 있다면 거기서부터 시작하되, 최댓값은 그대로 두기

를 생각했다가 보니, 투 포인터를 사용해서 가장 큰 수를 구하는 방법이 있을 것 같음.
힌트를 보니, 낮은 바를 항상 움직이라고 함.

시간 복잡도: o(n) / 공간 복잡도: o(1)
*/
function maxArea(height: number[]): number {
let left = 0;
let right = height.length - 1;
let max = 0;

while (left < right) {
const ltemp = height[left];
const rtemp = height[right];

if (ltemp < rtemp) {
left++;
} else {
right--;
}

const result = (right - left + 1) * Math.min(ltemp, rtemp);
if (result > max) {
max = result;
}
}

return max;
}
102 changes: 102 additions & 0 deletions design-add-and-search-words-data-structure/Baekwangho.ts
Copy link
Contributor

Choose a reason for hiding this comment

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

제가 이번주에 유일하게 Swift로 푼 문제군요! 주로 사용하는 언어로 자료구조를 구현하는 것은 중요한 것 같습니다. 와일드카드 문자가 있는 Trie는 그 시점에서 DFS를 태우면 된다고, 이전에 AI와 대화해 봤던 기억이 나네요.

Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/**
search 의 역할을 보았을 때, 각 글자의 길이별로 set 을 두는 형태로 구현해볼 수 있을 듯 하다.
class WordDictionary {
setArray: Array<Set<string>>
wordSet: Set<string>
constructor() {
this.setArray = Array.from({length:25}, () => new Set())
this.wordSet = new Set()
}

addWord(word: string): void {
for(let i=0; i<word.length; i++) {
this.setArray[i].add(word[i])
}
this.wordSet.add(word)
}

search(word: string): boolean {
if (word.includes('.')) {
for(let i=0; i<word.length; i++) {
console.log(word[i], this.setArray[i])
if (word[i] === '.') {
if (this.setArray[i].size) continue
return false
} else {
if (this.setArray[i].has(word[i])) continue
return false
}
}
return true
} else {
if (this.wordSet.has(word)) return true
return false
}
}
}
*/

/**
실패했다. 한글자의 '.' 케이스를 충족시킬 수 없었다.
실제 word 기반한 데이터가 아니기 때문에 발생하는 오류인 듯 하다.
힌트에서 trie 를 얘기하니, 그것을 구현해보자.
...
근데 결국 search 에서 탐색이 최악의 경우 '..............n' 등에서 최악일 듯 하다.
...
하지만 힌트를 보니, dfs 기반으로 구현하라고 하는구나.

시간 복잡도: O(L) ~ O(n * L) / 공간 복잡도: O(n * L)
O(L) 은 search 에 wildcard 가 없을 때, L은 글자 길이
*/
class WordDictionary {
headMap: any;

constructor() {
this.headMap = {};
}

addWord(word: string): void {
let curMap = this.headMap;

for (let i = 0; i < word.length; i++) {
const cur = curMap[word[i]];
if (!cur) {
const temp = {};
curMap[word[i]] = temp;
curMap = temp;
} else {
curMap = cur;
}
}
curMap["count"] ? curMap["count"]++ : (curMap["count"] = 1);
}

search(word: string): boolean {
function call(dict: any, subset?: string): boolean {
if (dict["count"] && !subset) {
return true;
}

const firstChar = subset![0];
if (firstChar === ".") {
return Object.values(dict).some((el) =>
call(el, subset!.slice(1, subset!.length))
);
} else {
const firstCharDict = dict[firstChar];
if (!firstCharDict) return false;

return call(firstCharDict, subset!.slice(1, subset!.length));
}
}

return call(this.headMap, word);
}
}

/**
* Your WordDictionary object will be instantiated and called as such:
* var obj = new WordDictionary()
* obj.addWord(word)
* var param_2 = obj.search(word)
*/
Empty file.
86 changes: 86 additions & 0 deletions spiral-matrix/Baekwangho.ts
Copy link
Contributor

@radiantchoi radiantchoi Dec 19, 2025

Choose a reason for hiding this comment

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

저 또한 xMinimum, yMaximum 따위를 구현하려고 하다가 분기처리하는 것이 너무 헷갈려서 visited 배열을 정의하는 식으로 풀었는데, 이 부분을 완벽하게 컨트롤해 주셨군요! 인상적입니다.

Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/**
(0,0) 에서 시작해서, 위 아래 끝값 및 왼쪽 오른쪽의 끝값을 갱신해가며
현재 위치가 이보다 커질 경우 각각을 -1 하고 방향을 바꿔준다.
*/
function spiralOrder(matrix: number[][]): number[] {
let hmin = 0,
hmax = matrix[0].length - 1,
vmin = 0,
vmax = matrix.length - 1;
let x = 0,
y = 0;
const result = [];
let currentStep = [1, 0];

while (hmax >= hmin && vmax >= vmin) {
result.push(matrix[y][x]);

const next = applyCurrentStep(currentStep, x, y, hmin, hmax, vmin, vmax);
currentStep = next.nextStep;
x = next.x;
y = next.y;
hmin = next.hmin;
hmax = next.hmax;
vmin = next.vmin;
vmax = next.vmax;

// console.log(currentStep, x, y, hmin, hmax, vmin, vmax)
}
return result;
}

function applyCurrentStep(
currentStep: number[],
x: number,
y: number,
hmin: number,
hmax: number,
vmin: number,
vmax: number
) {
let nextStep = currentStep;

switch (true) {
case currentStep[0] === 1 && currentStep[1] === 0: {
if (x >= hmax) {
nextStep = [0, 1];
y += 1;
vmin += 1;
} else {
x += 1;
}
break;
}
case currentStep[0] === 0 && currentStep[1] === 1: {
if (y >= vmax) {
nextStep = [-1, 0];
x -= 1;
hmax -= 1;
} else {
y += 1;
}
break;
}
case currentStep[0] === -1 && currentStep[1] === 0: {
if (hmin >= x) {
nextStep = [0, -1];
y -= 1;
vmax -= 1;
} else {
x -= 1;
}
break;
}
case currentStep[0] === 0 && currentStep[1] === -1: {
if (vmin >= y) {
nextStep = [1, 0];
x += 1;
hmin += 1;
} else {
y -= 1;
}
break;
}
}
return { nextStep, x, y, hmin, hmax, vmin, vmax };
}
35 changes: 35 additions & 0 deletions valid-parentheses/Baekwangho.ts
Copy link
Contributor

Choose a reason for hiding this comment

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

시작 괄호를 미리 정의된 배열로 가져다놓는 것도 좋은 것 같습니다! 보통 이런 문제들은 마지막에 스택이 비었는지만 체크하지만, 조금 코드가 복잡해지더라도 제시해주신 풀이처럼 early return을 사용한다면 일종의 최적화가 되는 효과가 있겠지요.

Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**
* 공간 복잡도: o(n) 시간 복잡도: o(n)
*/
function isValid(s: string): boolean {
const stack = [];

const start = ["(", "{", "["];

for (let i = 0; i < s.length; i++) {
if (start.includes(s[i])) {
stack.push(s[i]);
} else {
const last = stack.pop();
switch (last) {
case "(": {
if (s[i] !== ")") return false;
break;
}
case "{": {
if (s[i] !== "}") return false;
break;
}
case "[": {
if (s[i] !== "]") return false;
break;
}
default: {
return false;
}
}
}
}

return stack.length > 0 ? false : true;
}