From 08e05567909d5add7e1464de0f0ea5f333b8fec8 Mon Sep 17 00:00:00 2001 From: wch2208 Date: Tue, 24 Sep 2024 23:50:53 +0900 Subject: [PATCH 01/36] 217 / Contains Duplicate / Easy / 6m --- wch2208/217_Contains Duplicate.js | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 wch2208/217_Contains Duplicate.js diff --git a/wch2208/217_Contains Duplicate.js b/wch2208/217_Contains Duplicate.js new file mode 100644 index 0000000..77d4139 --- /dev/null +++ b/wch2208/217_Contains Duplicate.js @@ -0,0 +1,9 @@ +/** + * @param {number[]} nums + * @return {boolean} + */ +var containsDuplicate = function (nums) { + return nums.length !== new Set(nums).size; +}; + +// Time taken: 6 m From 7497658c747c372a7b30de977d696e0fc61efb7a Mon Sep 17 00:00:00 2001 From: wch2208 Date: Tue, 24 Sep 2024 23:51:41 +0900 Subject: [PATCH 02/36] 268 / Missing Number / Easy / 48m --- wch2208/268_Missing Number.js | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 wch2208/268_Missing Number.js diff --git a/wch2208/268_Missing Number.js b/wch2208/268_Missing Number.js new file mode 100644 index 0000000..874cec9 --- /dev/null +++ b/wch2208/268_Missing Number.js @@ -0,0 +1,23 @@ +/** + * @param {number[]} nums + * @return {number} + */ +var missingNumber = function (nums) { + const n = nums.length; + + nums.sort((a, b) => a - b); + + if (n === 1) { + return nums[0] === 0 ? 1 : 0; + } + + for (let i = 0; i < n; i++) { + if (nums[i] !== i) { + return i; + } + } + + return n; +}; + +// Time taken: 48 m From 84e4e6b75cc1766cdd698570f919737796083dcd Mon Sep 17 00:00:00 2001 From: wch2208 Date: Tue, 24 Sep 2024 23:52:14 +0900 Subject: [PATCH 03/36] 121 / Best Time to Buy and Sell Stock / Easy / 31m --- wch2208/121_Best_Time_to_Buy_and_Sell_Stock.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 wch2208/121_Best_Time_to_Buy_and_Sell_Stock.js diff --git a/wch2208/121_Best_Time_to_Buy_and_Sell_Stock.js b/wch2208/121_Best_Time_to_Buy_and_Sell_Stock.js new file mode 100644 index 0000000..d6287e0 --- /dev/null +++ b/wch2208/121_Best_Time_to_Buy_and_Sell_Stock.js @@ -0,0 +1,18 @@ +/** + * @param {number[]} prices + * @return {number} + */ +var maxProfit = function (prices) { + let answer = 0; + let minPrice = Infinity; + + prices.forEach(currentPrice => { + minPrice = Math.min(minPrice, currentPrice); + const profit = currentPrice - minPrice; + answer = Math.max(answer, profit); + }); + + return answer; +}; + +// Time taken: 31 m From 0d4f11c1051f32d9c6e61058efac24ecb73baa44 Mon Sep 17 00:00:00 2001 From: wch2208 Date: Tue, 24 Sep 2024 23:52:41 +0900 Subject: [PATCH 04/36] 252 / Meeting Schedule / Easy / 43m --- wch2208/252_Meeting_Schedule.js | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 wch2208/252_Meeting_Schedule.js diff --git a/wch2208/252_Meeting_Schedule.js b/wch2208/252_Meeting_Schedule.js new file mode 100644 index 0000000..2ad426e --- /dev/null +++ b/wch2208/252_Meeting_Schedule.js @@ -0,0 +1,28 @@ +/** + * Definition of Interval: + * class Interval { + * constructor(start, end) { + * this.start = start; + * this.end = end; + * } + * } + */ + +class Solution { + /** + * @param {Interval[]} intervals + * @returns {boolean} + */ + canAttendMeetings(intervals) { + intervals.sort((a, b) => a.start - b.start); + + const noConflict = intervals.every((interval, i) => { + if (i === 0) return true; + return interval.start >= intervals[i - 1].end; + }); + + return noConflict; + } +} + +// Time taken: 43 m From bdd4e2f3dbeb44bdc968af63432cb54014699e26 Mon Sep 17 00:00:00 2001 From: wch2208 Date: Tue, 24 Sep 2024 23:53:34 +0900 Subject: [PATCH 05/36] 70 / 3Sum / Medium / 29m --- wch2208/15_3Sum.js | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 wch2208/15_3Sum.js diff --git a/wch2208/15_3Sum.js b/wch2208/15_3Sum.js new file mode 100644 index 0000000..6d49899 --- /dev/null +++ b/wch2208/15_3Sum.js @@ -0,0 +1,38 @@ +/** + * @param {number[]} nums + * @return {number[][]} + */ + +var threeSum = function (nums) { + let result = []; + nums.sort((a, b) => a - b); + + for (let i = 0; i < nums.length - 2; i++) { + if (i > 0 && nums[i - 1] === nums[i]) continue; + + let j = i + 1; + let k = nums.length - 1; + + while (j < k) { + const sum = nums[i] + nums[j] + nums[k]; + + if (sum > 0) { + k--; + } else if (sum < 0) { + j++; + } else { + result.push([nums[i], nums[j], nums[k]]); + + while (j < k && nums[j] === nums[j + 1]) j++; + while (j < k && nums[k] === nums[k - 1]) k--; + + j++; + k--; + } + } + } + + return result; +}; + +// Time taken: 29 m 55 s From b3ed0c0c6972d3ae97a5356f7e299dfd1cee2156 Mon Sep 17 00:00:00 2001 From: wch2208 Date: Tue, 1 Oct 2024 19:23:28 +0900 Subject: [PATCH 06/36] 242 / Valid Anagram / Easy / 17m --- wch2208/242_Valid_Anagram.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 wch2208/242_Valid_Anagram.js diff --git a/wch2208/242_Valid_Anagram.js b/wch2208/242_Valid_Anagram.js new file mode 100644 index 0000000..96c258e --- /dev/null +++ b/wch2208/242_Valid_Anagram.js @@ -0,0 +1,19 @@ +/** + * @param {string} s + * @param {string} t + * @return {boolean} + */ +var isAnagram = function (s, t) { + if (s.length !== t.length) return false; + + const sArr = s.split("").sort(); + const tArr = t.split("").sort(); + + for (let i = 0; i < sArr.length; i++) { + if (sArr[i] !== tArr[i]) return false; + } + + return true; +}; + +// time: 17m 55s From 51ab1aee8de9be9921da17b7f185879b26c4f027 Mon Sep 17 00:00:00 2001 From: wch2208 Date: Tue, 1 Oct 2024 20:12:52 +0900 Subject: [PATCH 07/36] 238 / Product of Array Except Self / Medium / 39m --- wch2208/238_Product_of_Array_Except_Self.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 wch2208/238_Product_of_Array_Except_Self.js diff --git a/wch2208/238_Product_of_Array_Except_Self.js b/wch2208/238_Product_of_Array_Except_Self.js new file mode 100644 index 0000000..fab73da --- /dev/null +++ b/wch2208/238_Product_of_Array_Except_Self.js @@ -0,0 +1,21 @@ +/** + * @param {number[]} nums + * @return {number[]} + */ +var productExceptSelf = function (nums) { + const answer = new Array(nums.length); + + nums.reduce((accumulator, currentValue, index) => { + answer[index] = accumulator; + return accumulator * currentValue; + }, 1); + + nums.reduceRight((accumulator, currentValue, index) => { + answer[index] *= accumulator; + return accumulator * currentValue; + }, 1); + + return answer; +}; + +//time: 39m 12s From 9e03515f26e5abc46d69da3ed4c076199a210146 Mon Sep 17 00:00:00 2001 From: wch2208 Date: Tue, 1 Oct 2024 20:41:59 +0900 Subject: [PATCH 08/36] 191 / Number of 1 Bits / Easy / 10m --- wch2208/191_Number_of_1_Bits.js | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 wch2208/191_Number_of_1_Bits.js diff --git a/wch2208/191_Number_of_1_Bits.js b/wch2208/191_Number_of_1_Bits.js new file mode 100644 index 0000000..3f33879 --- /dev/null +++ b/wch2208/191_Number_of_1_Bits.js @@ -0,0 +1,9 @@ +/** + * @param {number} n + * @return {number} + */ +var hammingWeight = function (n) { + return n.toString(2).split("0").join("").length; +}; + +//time: 10m From 68c6bad66a29ad36623ff88373b2f6eadfcad6ea Mon Sep 17 00:00:00 2001 From: wch2208 Date: Tue, 1 Oct 2024 21:18:08 +0900 Subject: [PATCH 09/36] 100 / Same Tree / Easy / 20m --- wch2208/100_Same_Tree.js | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 wch2208/100_Same_Tree.js diff --git a/wch2208/100_Same_Tree.js b/wch2208/100_Same_Tree.js new file mode 100644 index 0000000..5853542 --- /dev/null +++ b/wch2208/100_Same_Tree.js @@ -0,0 +1,28 @@ +/** + * 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 {TreeNode} p + * @param {TreeNode} q + * @return {boolean} + */ +var isSameTree = function (p, q) { + // 두 노드가 모두 null이면 동일한 위치에 노드가 없음 + if (p === null && q === null) return true; + + // 한쪽만 null이면 구조가 다름 + if (p === null || q === null) return false; + + // 현재 노드의 값이 다르면 트리가 다름 + if (p.val !== q.val) return false; + + // 왼쪽과 오른쪽 자식을 재귀적으로 비교 + return isSameTree(p.left, q.left) && isSameTree(p.right, q.right); +}; + +// time: 20m From 118ef3d713023bfab2b9ff0978bfedc49cf9ef62 Mon Sep 17 00:00:00 2001 From: wch2208 Date: Tue, 1 Oct 2024 22:22:53 +0900 Subject: [PATCH 10/36] 746 / Min Cost Climbing Stairs / Easy / 40m --- wch2208/746_Min_Cost_Climbing_Stairs.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 wch2208/746_Min_Cost_Climbing_Stairs.js diff --git a/wch2208/746_Min_Cost_Climbing_Stairs.js b/wch2208/746_Min_Cost_Climbing_Stairs.js new file mode 100644 index 0000000..f705c27 --- /dev/null +++ b/wch2208/746_Min_Cost_Climbing_Stairs.js @@ -0,0 +1,18 @@ +/** + * @param {number[]} cost + * @return {number} + */ +var minCostClimbingStairs = function (cost) { + const n = cost.length; + const dp = new Array(n); + dp[0] = cost[0]; + dp[1] = cost[1]; + + for (let i = 2; i < n; i++) { + dp[i] = cost[i] + Math.min(dp[i - 1], dp[i - 2]); + } + + return Math.min(dp[n - 1], dp[n - 2]); +}; + +// time: 40m From 00b1c8fcae1d8fa083c141e682a0be6bc1dd24c8 Mon Sep 17 00:00:00 2001 From: wch2208 Date: Tue, 8 Oct 2024 20:07:21 +0900 Subject: [PATCH 11/36] 49 / Group Anagrams / medium / 50m --- wch2208/49_Group_Anagrams.js | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 wch2208/49_Group_Anagrams.js diff --git a/wch2208/49_Group_Anagrams.js b/wch2208/49_Group_Anagrams.js new file mode 100644 index 0000000..8589665 --- /dev/null +++ b/wch2208/49_Group_Anagrams.js @@ -0,0 +1,26 @@ +/** + * @param {string[]} strs + * @return {string[][]} + */ +var groupAnagrams = function (strs) { + // 결과를 저장할 Map 객체 생성 + let map = new Map(); + + // strs 배열 순회 + for (let str of strs) { + // 문자열을 알파벳 순서로 정렬 + let sortedStr = str.split("").sort().join(""); + + // 정렬된 문자열을 키로 사용하여 Map에 추가 + if (!map.has(sortedStr)) { + map.set(sortedStr, []); + } + map.get(sortedStr).push(str); + } + + // Map의 값들만 배열로 반환하고, 길이 순서대로 정렬 + return Array.from(map.values()).sort((a, b) => a.length - b.length); +}; + +// time: 50m 27s +// memory: 63.68MB From 3ef3f053c5fb9d1db16cfb3267886a0c4faad655 Mon Sep 17 00:00:00 2001 From: wch2208 Date: Tue, 8 Oct 2024 21:14:14 +0900 Subject: [PATCH 12/36] 190 / Reverse Bits / easy / 49m --- wch2208/190_Reverse_Bits.js | 50 +++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 wch2208/190_Reverse_Bits.js diff --git a/wch2208/190_Reverse_Bits.js b/wch2208/190_Reverse_Bits.js new file mode 100644 index 0000000..fbcbcd2 --- /dev/null +++ b/wch2208/190_Reverse_Bits.js @@ -0,0 +1,50 @@ +// 메서드를 써서 문자열로 다루는 방법 +// /** +// * @param {number} n - a positive integer +// * @return {number} - a positive integer +// */ +// var reverseBits = function (n) { +// // 32비트 이진수 문자열로 변환, 32비트 유지 필요 +// const binaryString = n.toString(2).padStart(32, "0"); +// // console.log(binaryString) +// // 00000010100101000001111010011100 + +// // 문자열을 배열로 바꾸고 뒤집은 후 다시 문자열로 합치기 +// const reversedBinaryString = binaryString.split("").reverse().join(""); +// // console.log(reversedBinaryString) +// // 00111001011110000010100101000000 + +// // 이진수 문자열을 정수로 변환 +// return parseInt(reversedBinaryString, 2); +// }; + +// 접근법 +// 비트 조작을 통해 32비트 이진수 n을 직접 뒤집고, +// >>> 0 연산을 사용하여 부호 없는 32비트 정수로 변환한 후, return하면 +// 자바스크립트의 기본 숫자 출력 형식에 따라 10진수로 반환된다. + +/** + * @param {number} n - a positive integer + * @return {number} - a positive integer + */ +var reverseBits = function (n) { + let result = 0; // 결과를 저장할 변수 + + // 32비트 반복 + for (let i = 0; i < 32; i++) { + // 현재 가장 오른쪽 비트를 가져오기 + let bit = n & 1; + + // 결과의 비트를 왼쪽으로 시프트하고 가져온 비트를 더하기 + result = (result << 1) | bit; + + // 입력값 n을 오른쪽으로 1비트 시프트 + n = n >> 1; + } + + // 부호 없는 32비트 정수로 변환하여 반환 + return result >>> 0; +}; + +// time: 49m +// memory: 50.61MB From f8e6ab1c93a212b04d438a7ce22c6d9c5e7cd31d Mon Sep 17 00:00:00 2001 From: wch2208 Date: Tue, 8 Oct 2024 21:57:40 +0900 Subject: [PATCH 13/36] 125 / Valid Palindrome / easy / 41m --- wch2208/125_Valid_Palindrome.js | 45 +++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 wch2208/125_Valid_Palindrome.js diff --git a/wch2208/125_Valid_Palindrome.js b/wch2208/125_Valid_Palindrome.js new file mode 100644 index 0000000..0354fcb --- /dev/null +++ b/wch2208/125_Valid_Palindrome.js @@ -0,0 +1,45 @@ +/** + * @param {string} s + * @return {boolean} + */ +var isPalindrome = function (s) { + // 문자열에서 알파벳과 숫자가 아닌 것은 제거하는 함수 + const removeNonAlphanumeric = str => { + let result = ""; + for (let i = 0; i < str.length; i++) { + let char = str[i]; + // 소문자, 숫자인지 확인 + if ((char >= "a" && char <= "z") || (char >= "0" && char <= "9")) { + result += char; + } + } + return result; + }; + + // 입력값 다듬기 + // 소문자변환 후 알파벳과 숫자가 아닌 것 제거 + const newS = removeNonAlphanumeric(s.toLowerCase()); + + //투포인터 구현 + // for문 + // for (let i = 0, j = newS.length - 1; i < j; i++, j--) { + // if (newS[i] !== newS[j]) return false; + // }; + + // while문 + let left = 0; + let right = newS.length - 1; + + while (left < right) { + if (newS[left] !== newS[right]) { + return false; + } + left++; + right--; + } + + return true; +}; + +// time: 41m +// memory: 51.70MB From dae0369065e8327e6a0193dfb79c47576484bd4e Mon Sep 17 00:00:00 2001 From: wch2208 Date: Tue, 22 Oct 2024 19:46:38 +0900 Subject: [PATCH 14/36] 338 / counting bits / easy / 41m --- wch2208/338_Counting_Bits.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 wch2208/338_Counting_Bits.js diff --git a/wch2208/338_Counting_Bits.js b/wch2208/338_Counting_Bits.js new file mode 100644 index 0000000..419225a --- /dev/null +++ b/wch2208/338_Counting_Bits.js @@ -0,0 +1,21 @@ +/** + * @param {number} n + * @return {number[]} + */ +var countBits = function (n) { + let answer = Array.from({ length: n + 1 }, (_, index) => index); + + answer.map((v, i) => { + let count = 0; + while (v > 0) { + v &= v - 1; + count++; + } + answer[i] = count; + }); + + return answer; +}; + +// 41m +// 56.11MB From f9cd00bba8f671854ebd353d9358a22420fbd0e1 Mon Sep 17 00:00:00 2001 From: wch2208 Date: Tue, 22 Oct 2024 20:44:30 +0900 Subject: [PATCH 15/36] 70 / Climbing Stairs / easy / 31m --- wch2208/70_Climbing_Stairs.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 wch2208/70_Climbing_Stairs.js diff --git a/wch2208/70_Climbing_Stairs.js b/wch2208/70_Climbing_Stairs.js new file mode 100644 index 0000000..e1c0971 --- /dev/null +++ b/wch2208/70_Climbing_Stairs.js @@ -0,0 +1,21 @@ +/** + * @param {number} n + * @return {number} + */ +var climbStairs = function (n) { + if (n === 1) return 1; + + let a = 1; + let b = 2; + + for (let i = 3; i <= n; i++) { + let temp = a + b; + a = b; + b = temp; + } + + return b; +}; + +// 48.73MB +// 31m From b792a83f2f40454dd28e42db8db60ee14aab3f4c Mon Sep 17 00:00:00 2001 From: wch2208 Date: Tue, 22 Oct 2024 21:54:41 +0900 Subject: [PATCH 16/36] 21 / Merge Two Sorted Lists / easy / 46m --- wch2208/21_Merge_Two_Sorted_Lists.js | 33 ++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 wch2208/21_Merge_Two_Sorted_Lists.js diff --git a/wch2208/21_Merge_Two_Sorted_Lists.js b/wch2208/21_Merge_Two_Sorted_Lists.js new file mode 100644 index 0000000..d5d65d2 --- /dev/null +++ b/wch2208/21_Merge_Two_Sorted_Lists.js @@ -0,0 +1,33 @@ +/** + * Definition for singly-linked list. + * function ListNode(val, next) { + * this.val = (val===undefined ? 0 : val) + * this.next = (next===undefined ? null : next) + * } + */ +/** + * @param {ListNode} list1 + * @param {ListNode} list2 + * @return {ListNode} + */ +var mergeTwoLists = function (list1, list2) { + // 문제 이해 + // 두 리스트의 값의 크기를 비교하면서 올바른 순서로 새로운 연결리스트를 구성해야한다. + // 기본 종료 조건: 하나의 리스트가 끝나면 다른 리스트를 반환 + if (list1 === null) return list2; + if (list2 === null) return list1; + + // 현재 노드를 비교하여 병합 리스트를 결정합니다. + if (list1.val < list2.val) { + // list1의 값이 작으면 list1을 선택하고 다음 노드들을 병합합니다. + list1.next = mergeTwoLists(list1.next, list2); + return list1; // 현재 노드를 반환하여 재귀적으로 연결됩니다. + } else { + // list2의 값이 작거나 같으면 list2를 선택하고 다음 노드들을 병합합니다. + list2.next = mergeTwoLists(list1, list2.next); + return list2; // 현재 노드를 반환하여 재귀적으로 연결됩니다. + } +}; + +// 51.82MB +// 46m From 70732014777e05eab13aa439661354719079c671 Mon Sep 17 00:00:00 2001 From: wch2208 Date: Tue, 22 Oct 2024 23:23:28 +0900 Subject: [PATCH 17/36] 48 / Rotate Image / medium / 48m --- wch2208/48_Rotate_Image.js | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 wch2208/48_Rotate_Image.js diff --git a/wch2208/48_Rotate_Image.js b/wch2208/48_Rotate_Image.js new file mode 100644 index 0000000..6391dff --- /dev/null +++ b/wch2208/48_Rotate_Image.js @@ -0,0 +1,22 @@ +/** + * @param {number[][]} matrix + * @return {void} Do not return anything, modify matrix in-place instead. + */ +var rotate = function (matrix) { + for (let i = 0; i < matrix.length; i++) { + for (let j = i + 1; j < matrix.length; j++) { + let temp = matrix[i][j]; + matrix[i][j] = matrix[j][i]; + matrix[j][i] = temp; + } + } + + for (let i = 0; i < matrix.length; i++) { + matrix[i].reverse(); + } + + return matrix; +}; + +// 48.76MB +// 48m From 9e62c8b1283a83d5246ae5ef66341192be24e35c Mon Sep 17 00:00:00 2001 From: wch2208 Date: Wed, 23 Oct 2024 00:31:59 +0900 Subject: [PATCH 18/36] 1046 / Last Stone Weight / easy / 39m --- wch2208/1046_Last_Stone_Weight.js | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 wch2208/1046_Last_Stone_Weight.js diff --git a/wch2208/1046_Last_Stone_Weight.js b/wch2208/1046_Last_Stone_Weight.js new file mode 100644 index 0000000..b339de1 --- /dev/null +++ b/wch2208/1046_Last_Stone_Weight.js @@ -0,0 +1,25 @@ +/** + * @param {number[]} stones + * @return {number} + */ +var lastStoneWeight = function (stones) { + stones.sort((a, b) => b - a); + + while (stones.length > 1) { + let max1 = stones.shift(); + let max2 = stones.shift(); + let newStone = max1 - max2; + let index = stones.findIndex(stone => stone < newStone); + + if (index === -1) { + stones.push(newStone); + } else { + stones.splice(index, 0, newStone); + } + } + + return stones.length === 1 ? stones[0] : 0; +}; + +// 49.44MB +// 39m From 4806bea58bc1fadc607f6c50a30d8817ef5e6671 Mon Sep 17 00:00:00 2001 From: wch2208 Date: Tue, 29 Oct 2024 20:15:17 +0900 Subject: [PATCH 19/36] 271 / Encode and Decode Strings / medium / 1hr --- wch2208/271_Encode_and_Decode_Strings.js | 41 ++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 wch2208/271_Encode_and_Decode_Strings.js diff --git a/wch2208/271_Encode_and_Decode_Strings.js b/wch2208/271_Encode_and_Decode_Strings.js new file mode 100644 index 0000000..1ae35f8 --- /dev/null +++ b/wch2208/271_Encode_and_Decode_Strings.js @@ -0,0 +1,41 @@ +class Solution { + /** + * @param {string[]} strs + * @returns {string} + */ + encode(strs) { + let encodedStrs = ""; + if (strs.length === 0) return encodedStrs; + + strs.forEach(str => { + encodedStrs += str.length + `#` + str; + }); + + return encodedStrs; + } + + /** + * @param {string} str + * @returns {string[]} + */ + decode(str) { + let decodedStr = []; + let i = 0; + + while (i < str.length) { + let j = i; + + while (str[j] !== `#`) { + j++; + } + + let length = parseInt(str.slice(i, j)); + i = j + 1; + + decodedStrs.push(str.slice(i, i + length)); + i += length; + } + } +} + +// time: 1hr From d164da775179a845944c2cde3eb1f624a584e1e9 Mon Sep 17 00:00:00 2001 From: wch2208 Date: Tue, 29 Oct 2024 21:13:46 +0900 Subject: [PATCH 20/36] 198 / House Robber / medium / 53m --- wch2208/198_House_Robber.js | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 wch2208/198_House_Robber.js diff --git a/wch2208/198_House_Robber.js b/wch2208/198_House_Robber.js new file mode 100644 index 0000000..9dd9448 --- /dev/null +++ b/wch2208/198_House_Robber.js @@ -0,0 +1,22 @@ +/** + * @param {number[]} nums + * @return {number} + */ +var rob = function (nums) { + if (nums.length === 1) return nums[0]; + + let dp = new Array(nums.length).fill(0); + dp[0] = nums[0]; + dp[1] = Math.max(nums[0], nums[1]); + + let i = 2; + while (i < nums.length) { + dp[i] = Math.max(dp[i - 1], nums[i] + dp[i - 2]); + i++; + } + + return dp[nums.length - 1]; +}; + +// time: 53m +// memory: 48.87MB From 4e804bb4773e166472b481b08ae5d4610784a8c8 Mon Sep 17 00:00:00 2001 From: wch2208 Date: Tue, 29 Oct 2024 22:15:51 +0900 Subject: [PATCH 21/36] 66 / Plus One / easy / 47m --- wch2208/66_Plus_One.js | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 wch2208/66_Plus_One.js diff --git a/wch2208/66_Plus_One.js b/wch2208/66_Plus_One.js new file mode 100644 index 0000000..d5dfc6f --- /dev/null +++ b/wch2208/66_Plus_One.js @@ -0,0 +1,22 @@ +/** + * @param {number[]} digits + * @return {number[]} + */ +var plusOne = function (digits) { + for (let i = digits.length - 1; i >= 0; i--) { + digits[i]++; + + if (digits[i] < 10) { + return digits; + } + + digits[i] = 0; + } + + digits.unshift(1); + + return digits; +}; + +// time: 47m 28s +// memory: 48.45MB From e367b45c65a8ef791cb846d7de0aad3a4460da8b Mon Sep 17 00:00:00 2001 From: wch2208 Date: Tue, 5 Nov 2024 19:19:55 +0900 Subject: [PATCH 22/36] 136 / Single Number / easy / 10m 41s --- wch2208/136._Single_Number.js | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 wch2208/136._Single_Number.js diff --git a/wch2208/136._Single_Number.js b/wch2208/136._Single_Number.js new file mode 100644 index 0000000..fbffffd --- /dev/null +++ b/wch2208/136._Single_Number.js @@ -0,0 +1,21 @@ +/** + * @param {number[]} nums + * @return {number} + */ +var singleNumber = function (nums) { + const map = new Map(); + nums.map(num => { + if (map.get(num) === undefined) { + map.set(num, 1); + } else { + map.set(num, map.get(num) + 1); + } + }); + + for ([num, val] of map) { + if (val === 1) return num; + } +}; + +// time: 10m 41s +// memory: 56.87MB From 77b37c4d78c1e7ece1bed7bd727da169f7c284b2 Mon Sep 17 00:00:00 2001 From: wch2208 Date: Tue, 5 Nov 2024 20:35:48 +0900 Subject: [PATCH 23/36] 110 / Balanced Binary Tree / easy / 50m --- wch2208/110._Balanced_Binary_Tree.js | 41 ++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 wch2208/110._Balanced_Binary_Tree.js diff --git a/wch2208/110._Balanced_Binary_Tree.js b/wch2208/110._Balanced_Binary_Tree.js new file mode 100644 index 0000000..777f869 --- /dev/null +++ b/wch2208/110._Balanced_Binary_Tree.js @@ -0,0 +1,41 @@ +/** + * 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 {TreeNode} root + * @return {boolean} + */ +var isBalanced = function (root) { + // 현재 노드의 높이를 구하는 함수 + const checkHeight = node => { + // 노드가 null이면 높이는 0 + if (!node) return 0; + + // 왼쪽 서브트리 높이 계산 + let leftHeight = checkHeight(node.left); + // 왼쪽 서브트리가 불균형인 경우 -1을 반환 + if (leftHeight === -1) return -1; + + // 오른쪽 서브트리 높이 계산 + let rightHeight = checkHeight(node.right); + // 오른쪽 서브트리가 불균형인 경우 -1을 반환 + if (rightHeight === -1) return -1; + + // 좌우 서브트리의 높이 차이가 1보다 크면 -1 반환 (불균형) + if (Math.abs(leftHeight - rightHeight) > 1) return -1; + + // 현재 노드의 높이 반환 (최대 서브트리 높이에 +1) + return Math.max(leftHeight, rightHeight) + 1; + }; + + // checkHeight가 -1을 반환하면 트리가 불균형이므로 false 반환 + return checkHeight(root) !== -1; +}; + +// time: 50m +// memory:54.18MB From d17498748cf050c4406ccec3598414f278d627fa Mon Sep 17 00:00:00 2001 From: wch2208 Date: Tue, 5 Nov 2024 21:46:20 +0900 Subject: [PATCH 24/36] 54 / Spiral Matrix / medium / 1hr --- wch2208/54_Spiral_Matrix.js | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 wch2208/54_Spiral_Matrix.js diff --git a/wch2208/54_Spiral_Matrix.js b/wch2208/54_Spiral_Matrix.js new file mode 100644 index 0000000..3450b02 --- /dev/null +++ b/wch2208/54_Spiral_Matrix.js @@ -0,0 +1,35 @@ +var spiralOrder = function (matrix) { + let answer = []; + + while (matrix.length > 0 && matrix[0].length > 0) { + // 전체 matrix가 비어있지 않은지 확인 + + // 오른쪽으로 이동 + answer = answer.concat(matrix.shift()); // 첫 번째 행을 가져와서 answer에 추가 + + // 아래로 이동 + for (let i = 0; i < matrix.length; i++) { + if (matrix[i].length > 0) { + // 행이 빈 배열인지 확인 + answer.push(matrix[i].pop()); + } + } + + // 왼쪽으로 이동 + if (matrix.length > 0) { + answer = answer.concat(matrix.pop().reverse()); // 마지막 행을 가져와 역순으로 추가 + } + + // 위로 이동 + for (let i = matrix.length - 1; i >= 0; i--) { + if (matrix[i].length > 0) { + answer.push(matrix[i].shift()); + } + } + } + + return answer; +}; + +//time: 1hr +//memory: 48.48MB From 0fbf63e3b5d30f4c951ee2ac1f83f50fa25924bc Mon Sep 17 00:00:00 2001 From: wch2208 Date: Tue, 5 Nov 2024 22:12:25 +0900 Subject: [PATCH 25/36] 973 / K Closest Points to Origin / medium / 48m --- wch2208/973_K_Closest_Points_to_Origin.js | 26 +++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 wch2208/973_K_Closest_Points_to_Origin.js diff --git a/wch2208/973_K_Closest_Points_to_Origin.js b/wch2208/973_K_Closest_Points_to_Origin.js new file mode 100644 index 0000000..39ba2fa --- /dev/null +++ b/wch2208/973_K_Closest_Points_to_Origin.js @@ -0,0 +1,26 @@ +/** + * @param {number[][]} points + * @param {number} k + * @return {number[][]} + */ +var kClosest = function (points, k) { + // 인덱스와 거리 정보를 가진 배열 생성 + const distance = points.map(([x, y], index) => ({ + index: index, + distance: x * x + y * y, + })); + // console.log(distance) + // [ { index: 0, distance: 10 }, { index: 1, distance: 8 } ] + + // distnace 작은 순서(오름차순)로 정렬 + distance.sort((a, b) => a.distance - b.distance); + // console.log(distance) + // [ { index: 1, distance: 8 }, { index: 0, distance: 10 } ] + + // k번째까지 자른 뒤 points에 해당 인덱스 값 접근해서 반환하기 + const answer = distance.slice(0, k).map(item => points[item.index]); + return answer; +}; + +// time: 48m +// memory: 64.38MB From af6c97bd801eece3dd8f5d7d52da677545f23182 Mon Sep 17 00:00:00 2001 From: wch2208 Date: Tue, 12 Nov 2024 20:00:25 +0900 Subject: [PATCH 26/36] 128 / Longest Consecutive Sequence / medium / 44m --- wch2208/128_Longest_Consecutive_Sequence.js | 35 +++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 wch2208/128_Longest_Consecutive_Sequence.js diff --git a/wch2208/128_Longest_Consecutive_Sequence.js b/wch2208/128_Longest_Consecutive_Sequence.js new file mode 100644 index 0000000..84a2e8a --- /dev/null +++ b/wch2208/128_Longest_Consecutive_Sequence.js @@ -0,0 +1,35 @@ +/** + * @param {number[]} nums + * @return {number} + */ +var longestConsecutive = function (nums) { + // 접근법: + // 시작점을 찾고 거기에서 +1 값이 존재하는지 확인하고 카운트업한다. + // Set 객체로 만들어서 has() 메서드로 조회하면 O(n)으로 조회할 수 있다. + + const set = new Set(nums); + let maxLength = 0; + + for (const value of set) { + // set.has(value - 1)가 false면 시작점이다. + if (!set.has(value - 1)) { + // 시작점을 찾았으면 현재 숫자와 카운트 초기화 + let currentNum = value; + let currentLength = 1; + + // set.has(currentNum + 1)이 true면 연속되는 수가 존재한다. + // currentNum +1로 업데이트하면서 연속되는 수를 계속 체크 + while (set.has(currentNum + 1)) { + currentNum++; + currentLength++; + } + + // maxLength에 최대값 업데이트 + maxLength = Math.max(maxLength, currentLength); + } + } + return maxLength; +}; + +//time: 44m +//memory: 73.56MB From d3fcbc1070d27dffd45a655ec5f98882c5a2a9c9 Mon Sep 17 00:00:00 2001 From: wch2208 Date: Tue, 12 Nov 2024 20:44:37 +0900 Subject: [PATCH 27/36] 371 / Sum of Two Integers / medium / 32m --- wch2208/371_Sum_of_Two_Integers.js | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 wch2208/371_Sum_of_Two_Integers.js diff --git a/wch2208/371_Sum_of_Two_Integers.js b/wch2208/371_Sum_of_Two_Integers.js new file mode 100644 index 0000000..14a839f --- /dev/null +++ b/wch2208/371_Sum_of_Two_Integers.js @@ -0,0 +1,19 @@ +/** + * @param {number} a + * @param {number} b + * @return {number} + */ +var getSum = function (a, b) { + while (b !== 0) { + // 캐리를 저장 + let carry = (a & b) << 1; + // 캐리를 제외한 덧셈 수행 + a = a ^ b; + // 다음 반복을 위해 b를 캐리값으로 업데이트 + b = carry; + } + return a; +}; + +// time: 32m +// memory: 48.80MB From 93904b5d4bb48e71ace702abfe3ac2106b6d74e8 Mon Sep 17 00:00:00 2001 From: wch2208 Date: Tue, 12 Nov 2024 21:45:40 +0900 Subject: [PATCH 28/36] 208 / Implement Trie (Prefix Tree) / medium / 42m --- wch2208/208_Implement_Trie_(Prefix Tree).js | 93 +++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 wch2208/208_Implement_Trie_(Prefix Tree).js diff --git a/wch2208/208_Implement_Trie_(Prefix Tree).js b/wch2208/208_Implement_Trie_(Prefix Tree).js new file mode 100644 index 0000000..33c6791 --- /dev/null +++ b/wch2208/208_Implement_Trie_(Prefix Tree).js @@ -0,0 +1,93 @@ +// Trie는 문자열을 저장하고 효율적으로 검색하기 위한 트리 자료구조이다. +// 각 노드는 문자를 나타내며, 루트에서 특정 노드까지의 경로가 하나의 문자열을 형성한다. +// 구성요소는 1. 자식 노드를 저장할 객체(children) 2. 현재 노드가 단어의 끝인지 표시하는 플래그(isEndOfWord) +// 루트 노드가 있어야 한다. 루트 노드는 시작점을 의미하며 초기값을 통일한다. + +var TrieNode = function () { + this.children = {}; + this.isEndOfWord = false; +}; + +var Trie = function () { + this.root = new TrieNode(); +}; + +/** + * @param {string} word + * @return {void} + */ +// 단어 추가 메서드이다. +// 입력된 단어의 각 문자를 순서대로 조회하면서 없으면 새로운 노드를 생성하고 있으면 기존 노드로 이동한다. +// 마지막 문자의 노드에 isEndOfWord를 true로 설정하여 단어의 끝임을 표시한다. +Trie.prototype.insert = function (word) { + let current = this.root; + + // 단어의 각 문자에 대해 + for (let char of word) { + // 현재 문자에 대한 노드가 없다면 새로 생성 + if (!current.children[char]) { + current.children[char] = new TrieNode(); + } + // 다음 노드로 이동 + current = current.children[char]; + } + // 단어의 끝임을 표시 + current.isEndOfWord = true; +}; + +/** + * @param {string} word + * @return {boolean} + */ +// 서치 메서드이다. +// 입력한 단어가 저장된 단어인지 참/거짓을 반환한다. +// 알파벳을 순서대로 순회하면서 중간에 경로가 끊기면 거짓을 반환한다. 저장된 단어가 없는 것. +// 마지막 문자까지 순회를 완료하면 해당 노드의 isEndOfWord 값을 반환한다. +// isEndOfWord가 참이면 그 경로가 완성된 단어라는 의미이고, 거짓이면 완성된 단어가 아니라는 의미이다. +Trie.prototype.search = function (word) { + let current = this.root; + + // 단어의 각 문자에 대해 + for (let char of word) { + // 현재 문자에 대한 노드가 없다면 false 반환 + if (!current.children[char]) { + return false; + } + current = current.children[char]; + } + // 마지막 노드가 단어의 끝인지 확인 + return current.isEndOfWord; +}; + +/** + * @param {string} prefix + * @return {boolean} + */ +// 입력된 문자열이 저장된 경로에 존재하는지 확인하는 메서드이다. +// prefix의 모든 문자가 경로상에 존재하면 true를 반환한다. +// 단어의 완성 여부(isEndOfWord)는 확인하지 않는다. +Trie.prototype.startsWith = function (prefix) { + let current = this.root; + + // prefix의 각 문자에 대해 + for (let char of prefix) { + // 현재 문자에 대한 노드가 없다면 false 반환 + if (!current.children[char]) { + return false; + } + current = current.children[char]; + } + // prefix의 모든 문자가 존재하면 true 반환 + return true; +}; + +/** + * Your Trie object will be instantiated and called as such: + * var obj = new Trie() + * obj.insert(word) + * var param_2 = obj.search(word) + * var param_3 = obj.startsWith(prefix) + */ + +//time: 42m +//memory: 67.80MB From d115dd08bb0679f9e6d00bf6e302c9b8979d1a00 Mon Sep 17 00:00:00 2001 From: wch2208 Date: Tue, 12 Nov 2024 23:30:51 +0900 Subject: [PATCH 29/36] 226 / Invert Binary Tree / easy / 29m --- wch2208/226_Invert_Binary_Tree.js | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 wch2208/226_Invert_Binary_Tree.js diff --git a/wch2208/226_Invert_Binary_Tree.js b/wch2208/226_Invert_Binary_Tree.js new file mode 100644 index 0000000..488b79e --- /dev/null +++ b/wch2208/226_Invert_Binary_Tree.js @@ -0,0 +1,30 @@ +/** + * 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 {TreeNode} root + * @return {TreeNode} + */ + +var invertTree = function (root) { + // 예제를 보면 트리를 뒤집어야한다 + // 재귀를 사용하는 경우는 노드의 끝까지 가서 마지막 함수가 완료되면 그 값을 받아서 상위 노드가 점차 풀이되는 방식이다. + // 수행할 로직은 레프트와 라이트를 교체하는 것 + + if (root === null) return null; + + [root.left, root.right] = [root.right, root.left]; + + invertTree(root.left); + invertTree(root.right); + + return root; +}; + +// time: 29m +// memory: 50.10MB From 013a803fd091d4e8810b01263cfa01cc886035b5 Mon Sep 17 00:00:00 2001 From: wch2208 Date: Tue, 12 Nov 2024 23:51:22 +0900 Subject: [PATCH 30/36] 543 / Diameter of Binary Tree / easy --- wch2208/543_Diameter_of_Binary_Tree.js | 43 ++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 wch2208/543_Diameter_of_Binary_Tree.js diff --git a/wch2208/543_Diameter_of_Binary_Tree.js b/wch2208/543_Diameter_of_Binary_Tree.js new file mode 100644 index 0000000..cde55e8 --- /dev/null +++ b/wch2208/543_Diameter_of_Binary_Tree.js @@ -0,0 +1,43 @@ +/** + * 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 {TreeNode} root + * @return {number} + */ + +// 지름은 임의의 두 노드 사이의 가장 긴 경로(간선의 개수)이며, +// 각 노드에서 좌우 서브트리의 높이 합 중 최대값이다. +// 높이를 구하고 추가로 지름도 업데이트해야한다. +var diameterOfBinaryTree = function (root) { + // 지름 초기화 + let maxDiameter = 0; + + // 높이 반환하는 함수 + const getHeight = node => { + // 빈 값 처리 + if (!node) return 0; + + // 좌측과 우측 높이 계산 + const leftHeight = getHeight(node.left); + const rightHeight = getHeight(node.right); + + // 지름 업데이트, 이전 업데이트의 지름과 현재 좌우의 높이를 더한 값(현재 지름) 중에 큰 값 + maxDiameter = Math.max(maxDiameter, leftHeight + rightHeight); + + // 현재 높이 반환 + // 둘 중 더 높은 값이 필요 + return Math.max(leftHeight, rightHeight) + 1; + }; + + getHeight(root); + return maxDiameter; +}; + +// time: 17m +// memory: 57.68MB From c6fa919367012c202e67b34317ef78d3343366fb Mon Sep 17 00:00:00 2001 From: wch2208 Date: Tue, 19 Nov 2024 20:49:57 +0900 Subject: [PATCH 31/36] 102 / Binary Tree Level Order Traversal / medium / 1h 27m --- .../102_Binary_Tree_Level_Order_Traversal.js | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 wch2208/102_Binary_Tree_Level_Order_Traversal.js diff --git a/wch2208/102_Binary_Tree_Level_Order_Traversal.js b/wch2208/102_Binary_Tree_Level_Order_Traversal.js new file mode 100644 index 0000000..3ce0c98 --- /dev/null +++ b/wch2208/102_Binary_Tree_Level_Order_Traversal.js @@ -0,0 +1,50 @@ +/** + * 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 {TreeNode} root + * @return {number[][]} + */ +var levelOrder = function (root) { + // 이 문제는 같은 레벨을 순회해야한다. + // BFS(너비 우선 탐색) 사용 + + // 빈 트리 처리 + if (!root) return []; + + // 초기화 result, queue + const result = []; + const queue = [root]; // TreeNode를 배열로 감싸서 배열 메서드(push, shift)를 사용할 수 있게 함 + + while (queue.length > 0) { + const levelSize = queue.length; // 현재 레벨에서 순회할 횟수 + const currentLevel = []; // 현재 레벨에 값들을 담을 배열 + + for (let i = 0; i < levelSize; i++) { + const node = queue.shift(); // 큐에서 가장 앞의 노드 추출 + + currentLevel.push(node.val); // 추출한 노드의 값을 현재 레벨 배열에 추가 + + // 다음 레벨 노드들을 큐에 추가 + if (node.left) { + queue.push(node.left); + } + if (node.right) { + queue.push(node.right); + } + } + + // for문이 끝나면 하나의 레벨 탐색이 끝난 것이므로 result에 추가 + result.push(currentLevel); + } + + return result; +}; + +// time: 1h 27m +// memory: 55.19MB From 05c4a75f876b5c031184510c1f0a139ff1be2290 Mon Sep 17 00:00:00 2001 From: wch2208 Date: Tue, 19 Nov 2024 21:41:52 +0900 Subject: [PATCH 32/36] 572 / Subtree of Another Tree / easy / 43m --- wch2208/572_Subtree_of_Another_Tree.js | 38 ++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 wch2208/572_Subtree_of_Another_Tree.js diff --git a/wch2208/572_Subtree_of_Another_Tree.js b/wch2208/572_Subtree_of_Another_Tree.js new file mode 100644 index 0000000..0114fbb --- /dev/null +++ b/wch2208/572_Subtree_of_Another_Tree.js @@ -0,0 +1,38 @@ +/** + * 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 {TreeNode} root + * @param {TreeNode} subRoot + * @return {boolean} + */ +var isSubtree = function (root, subRoot) { + if (!root) return false; + if (!subRoot) return true; // 서브 루트가 없으면 비교할 필요 없이 true + + // 현재 노드 비교 + if (isSameTree(root, subRoot)) return true; + + // 재귀호출: 왼쪽, 오른쪽 서브트리 확인 + // 둘 중 한 곳에서 서브트리와 일치하는 트리가 있으면 true + return isSubtree(root.left, subRoot) || isSubtree(root.right, subRoot); +}; + +function isSameTree(p, q) { + if (!p && !q) return true; // 둘 다 null이면 true + if (!p || !q) return false; // 하나만 null이면 false + + // 현재 노드 비교 + if (p.val !== q.val) return false; + + // 재귀 호출: 왼쪽과 오른쪽 트리 모두 같아야 함 + return isSameTree(p.left, q.left) && isSameTree(p.right, q.right); +} + +// time: 43m +// memory: 54.73MB From 6f82c0598f39164a5030bcbf5ea043f784c5264d Mon Sep 17 00:00:00 2001 From: wch2208 Date: Tue, 19 Nov 2024 22:27:05 +0900 Subject: [PATCH 33/36] 213 / House Robber II / medium / 41m --- wch2208/213_House_Robber_II.js | 48 ++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 wch2208/213_House_Robber_II.js diff --git a/wch2208/213_House_Robber_II.js b/wch2208/213_House_Robber_II.js new file mode 100644 index 0000000..8a12941 --- /dev/null +++ b/wch2208/213_House_Robber_II.js @@ -0,0 +1,48 @@ +/** + * @param {number[]} nums + * @return {number} + */ +var rob = function (nums) { + // 문제이해 + // 1. 인접한 집은 털 수 없는 경우, 최대로 많은 금액을 훔치면 얼마? (DP 계산) + // 추가 조건: 집이 원형으로 배치되서 첫 집과 마지막 집이 인접하다. + // 접근법 + // DP를 활용해서 최대값을 구하는 함수를 만든다. (1단계) + // 추가 조건을 고려한 추가 로직을 작성. (2단계) + // 2단계는 1단계 함수에 nums를 바꿔서 두 번 실행하고 비교한다. + // 왜냐하면 첫번째 집을 턴 경우는 마지막 집을 제거하면 되고 + // 첫번째 집을 안 턴 경우는 첫번째 집을 제외하고 DP를 계산하면 된다. + + // 예외 처리: 집이 1개인 경우 + if (nums.length === 1) return nums[0]; + + // dp로 최대값 구하는 함수 + const simpleRob = houses => { + // 예외 처리: 집이 1개인 경우 + if (houses.length === 1) return houses[0]; + + // dp 배열 생성 + let dp = new Array(houses.length); + + // 기저 조건 + dp[0] = houses[0]; + dp[1] = Math.max(houses[0], houses[1]); + + // for문으로 순회하면서 점화식 수행 + for (let i = 2; i < houses.length; i++) { + dp[i] = Math.max(houses[i] + dp[i - 2], dp[i - 1]); + } + + // 마지막 요소에 최대값이 담김 + return dp[dp.length - 1]; + }; + + // 첫집 턴 경우, 안 턴 경우 중 큰 값 + return Math.max( + simpleRob(nums.slice(0, nums.length - 1)), + simpleRob(nums.slice(1)) + ); +}; + +// time: 41m +// memory: 48.78MB From da7f2a83eac8cd4add73542cef89c44b98f84d27 Mon Sep 17 00:00:00 2001 From: wch2208 Date: Tue, 3 Dec 2024 19:48:58 +0900 Subject: [PATCH 34/36] 7 / reverse integer / medium / 18m --- wch2208/7_Reverse_Integer.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 wch2208/7_Reverse_Integer.js diff --git a/wch2208/7_Reverse_Integer.js b/wch2208/7_Reverse_Integer.js new file mode 100644 index 0000000..8cfc69e --- /dev/null +++ b/wch2208/7_Reverse_Integer.js @@ -0,0 +1,18 @@ +/** + * @param {number} x + * @return {number} + */ +var reverse = function (x) { + const isNegative = x < 0; + + const reversed = Math.abs(x).toString().split("").reverse().join(""); + + const result = Number(reversed); + + // 32비트 범위를 넘어가는지 확인 최소값보다 더 작거나 최대값보다 더 큰 경우 + if (result < Math.pow(-2, 31) || result > Math.pow(2, 31) - 1) return 0; + + return isNegative ? -result : result; +}; + +// time: 18m 43s From 9e93cb11a315f871dbdc1db0531292d45722d2ac Mon Sep 17 00:00:00 2001 From: wch2208 Date: Tue, 3 Dec 2024 21:52:43 +0900 Subject: [PATCH 35/36] 743 / Network Delay Time / medium / 1h 14m --- wch2208/743_Network_Delay_Time.js | 76 +++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 wch2208/743_Network_Delay_Time.js diff --git a/wch2208/743_Network_Delay_Time.js b/wch2208/743_Network_Delay_Time.js new file mode 100644 index 0000000..5848e44 --- /dev/null +++ b/wch2208/743_Network_Delay_Time.js @@ -0,0 +1,76 @@ +/** + * @param {number[][]} times + * @param {number} n + * @param {number} k + * @return {number} + */ +var networkDelayTime = function (times, n, k) { + // 문제이해: 숫자 리스트와 n, k가 입력된다. k부터 시작해서 모든 노드에 신호를 보내는데 걸리는 최소 시간을 구한다 모든 노드에 도달할 수 없다면 -1 + // times[i] = (ui, vi, wi) 이 형태를 보고 그래프 자료구조임을 파악할 수 있다. + // 시작점 하나 + 모든 노드까지의 최단 거리/시간 + 양의 가중치, 이 조건으로 그리디 알고리즘 중 다익스트라 알고리즘을 사용할 수 있다. + + // 1. 그래프 생성 + const graph = new Map(); + + for (let i = 1; i <= n; i++) { + graph.set(i, []); + } + // console.log(graph) + // Map(4) { 1 => [], 2 => [], 3 => [], 4 => [] } + + for (const [u, v, w] of times) { + graph.get(u).push([v, w]); + } + // console.log(graph) + // Map(3) { 1 => [], 2 => [ [ 1, 1 ], [ 3, 1 ] ], 3 => [ [ 4, 1 ] ] } + + // 2. 거리 배열 초기화 + const distances = new Array(n + 1).fill(Infinity); + distances[k] = 0; + + // console.log(distances) + // [ Infinity, Infinity, 0, Infinity, Infinity ] + + // 3. 방문 배열 초기화 + const visited = new Array(n + 1).fill(false); + // console.log(visited) + // [ false, false, false, false, false ] + + // 4. 다익스트라 알고리즘 구현 + for (let i = 1; i <= n; i++) { + // 4-1. 현재 최단 거리인 노드 찾기 + let minDist = Infinity; + let minNode = -1; + for (let node = 1; node <= n; node++) { + if (!visited[node] && distances[node] < minDist) { + minDist = distances[node]; + minNode = node; + } + } + + // 4-2. 도달할 수 없는 노드가 있는 경우 + if (minNode === -1) break; + + // 4-3. 노드 방문 처리 + visited[minNode] = true; + + // 4-4. 인접한 노드들의 거리 갱신 + for (const [nextNode, time] of graph.get(minNode)) { + const newDist = distances[minNode] + time; + if (newDist < distances[nextNode]) { + distances[nextNode] = newDist; + } + } + } + + // 5. 결과 계산 + let maxDist = 0; + for (let i = 1; i <= n; i++) { + if (distances[i] === Infinity) return -1; + maxDist = Math.max(maxDist, distances[i]); + } + + return maxDist; +}; + +// time: 1h 14m From 282e74df3266cd728c736f04b75116c9cf78613e Mon Sep 17 00:00:00 2001 From: wch2208 Date: Tue, 3 Dec 2024 22:45:54 +0900 Subject: [PATCH 36/36] 39 / Combination Sum / medium / 44m --- wch2208/39_Combination_Sum.js | 36 +++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 wch2208/39_Combination_Sum.js diff --git a/wch2208/39_Combination_Sum.js b/wch2208/39_Combination_Sum.js new file mode 100644 index 0000000..eab5510 --- /dev/null +++ b/wch2208/39_Combination_Sum.js @@ -0,0 +1,36 @@ +/** + * @param {number[]} candidates + * @param {number} target + * @return {number[][]} + */ +var combinationSum = function (candidates, target) { + const result = []; + + const findCombinations = (remaining, current, start) => { + // 종료조건 + if (remaining === 0) { + result.push([...current]); + return; + } + + if (remaining < 0) return; + + // 현재 단계에서 할 일 + for (let i = start; i < candidates.length; i++) { + // 1. 현재 숫자를 선택 + current.push(candidates[i]); + + // 2. 이 숫자를 선택한 상태에서 재귀 호출 + findCombinations(remaining - candidates[i], current, i); + + // 3. 백트래킹: 현재 숫자를 제거하고 다른 가능성 시도 + current.pop(); + } + }; + + findCombinations(target, [], 0); + + return result; +}; + +// time: 44m