Skip to content
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
29 changes: 29 additions & 0 deletions coin-change/Blossssom.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* @param coins - 동전 종류 배열
* @param amount - 총 금액
* @returns - 총 사용 코인 갯수
* @description
* - 탐욕으로 풀면 최소 동전갯수를 구할 수 없음
* - dp 로 풀이
* - 1 부터 금액의 코인 사용 갯수를 추가해 가며, 이전에 구해놓은 값과 min 비교
*/
function coinChange(coins: number[], amount: number): number {
const dp = new Array(amount + 1).fill(Infinity);

dp[0] = 0;

for (let i = 1; i <= amount; i++) {
for (const coin of coins) {
if (i - coin >= 0) {
dp[i] = Math.min(dp[i], dp[i - coin] + 1);
}
}
}

return dp[amount] === Infinity ? -1 : dp[amount];
}

const coins = [1, 2, 5];
const amount = 11;
coinChange(coins, amount);

32 changes: 32 additions & 0 deletions find-minimum-in-rotated-sorted-array/Blossssom.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/**
* @param nums - 오름차순 정렬된 정수 배열
* @returns - 최솟값
* @description
* - 이진 탐색으로 right와 비교하며 배열의 범위를 좁혀가며 탐색
* - left와 right가 겹치는 포인트가 최솟값
*/

function findMin(nums: number[]): number {
let left = 0;
let mid = Math.floor(nums.length / 2);
let right = nums.length - 1;

if (nums.length < 2) {
return nums[0];
}

while (left < right) {
if (nums[right] < nums[mid]) {
left = mid + 1;
} else {
right = mid;
}

mid = Math.floor((left + right) / 2);
}
return nums[left];
}

const nums = [2, 1];
console.log(findMin(nums));

53 changes: 53 additions & 0 deletions maximum-depth-of-binary-tree/Blossssom.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
class TreeNode {
val: number;
left: TreeNode | null;
right: TreeNode | null;
constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) {
this.val = val === undefined ? 0 : val;
this.left = left === undefined ? null : left;
this.right = right === undefined ? null : right;
}
}

/**
* @param root - 이진 트리
* @returns - 루트 노드에서 가장 먼 리프노드 까지 가장 긴 경로를 따른 노드 수
* @description
* - root가 없는 경우를 제외 후 재귀 호출로 1씩 증가
* - left, right 중 가장 큰 값을 return
* - maxDepth 자체를 재귀로 사용하는 방식이 가장 효율적
*/

// function maxDepth(root: TreeNode | null): number {
// if (!root) {
// return 0;
// }

// function recursive(current: TreeNode | null): number {
// if (!current) {
// return 0;
// }

// return 1 + Math.max(recursive(current.left), recursive(current.right));
// }

// return recursive(root);
// }

function maxDepth(root: TreeNode | null): number {
if (root === null) {
return 0;
}

const left = 1 + maxDepth(root.left);
const right = 1 + maxDepth(root.right);

return Math.max(left, right);
}

const root = new TreeNode(
3,
new TreeNode(9),
new TreeNode(20, new TreeNode(15), new TreeNode(7))
);

49 changes: 49 additions & 0 deletions merge-two-sorted-lists/Blossssom.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
class ListNode {
val: number;
next: ListNode | null;
constructor(val?: number, next?: ListNode | null) {
this.val = val === undefined ? 0 : val;
this.next = next === undefined ? null : next;
}
}

/**
* @param linked_list list1
* @param linked_list list2
* @returns 정렬된 linked_list
* @description
* - 연결리스트로 각 단계를 탐색하려니 접근 방법이 떠오르지 않음
* - 해당 유형의 문제를 더 풀어볼 예정
*/

function mergeTwoLists(
list1: ListNode | null,
list2: ListNode | null
): ListNode | null {
if (!list1 && !list2) {
return null;
}

const temp = new ListNode();
let current = temp;

while (list1 && list2) {
if (list1.val < list2.val) {
current.next = list1;
list1 = list1.next;
} else {
current.next = list2;
list2 = list2.next;
}
current = current.next;
}
current.next = list1 || list2;

return temp.next;
}

const list1 = new ListNode(1, new ListNode(2, new ListNode(4)));
const list2 = new ListNode(1, new ListNode(3, new ListNode(4)));

mergeTwoLists(list1, list2);

73 changes: 73 additions & 0 deletions word-search/Blossssom.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/**
* @param board - m * n 문자 그리드
* @param word - 찾을 단어
* @returns - 그리드 내 인접한 셀의 글자로 word를 만들 수 있는지 반환
* @description
* - 동일한 셀 글자는 한 번만 사용가능
* - visit 체크 부분에서 조금 생각을 잘못해 오래걸림
* - dfs 연습 필요, 문제를 최대한 잘게 잘라서 생각해보기
*/

function exist(board: string[][], word: string): boolean {
const maximumRow = board.length - 1;
const maximumCol = board[0].length - 1;
// 시작지점 찾기
const starter = board.reduce<number[][]>((acc, row, rIndex) => {
row.forEach((col, cIndex) => {
if (col === word[0]) {
acc.push([rIndex, cIndex]);
}
});
return acc;
}, []);

function recursive(row: number, col: number, target: number): boolean {
// word의 길이까지 왔다면 이전 조건은 통과 즉, word와 동일 문자열
if (target === word.length) {
return true;
}

// 인접 index 범위 체크 및 값 체크
if (
row < 0 ||
row > maximumRow ||
col < 0 ||
col > maximumCol ||
board[row][col] !== word[target]
) {
return false;
}
// 이전 값을 동일 체크하지 않도록 값을 저장 및 변경
const saveValue = board[row][col];
// 찡긋
board[row][col] = ">_o";

const finding =
recursive(row + 1, col, target + 1) ||
recursive(row - 1, col, target + 1) ||
recursive(row, col + 1, target + 1) ||
recursive(row, col - 1, target + 1);

// 다음 순회 및 체크를 위한 원상복구
board[row][col] = saveValue;
return finding;
}

for (const start of starter) {
const isFind = recursive(start[0], start[1], 0);
if (isFind) {
return true;
}
}
return false;
}

const board = [
["A", "B", "C", "E"],
["S", "F", "C", "S"],
["A", "D", "E", "E"],
];

const word = "ABCCED";
console.log(exist(board, word));