diff --git a/README.md b/README.md index b4a2e24..f92a40b 100644 --- a/README.md +++ b/README.md @@ -49,10 +49,18 @@ The listing below is sorted based on LeetCode #. If you are interested to see my |-----------:|:------|:-----------|:-------| | 1 | [Two Sum](/problems/two-sum) | Easy | Array, hash table | | 35 | [Search Insert Position](/problems/search-insert-position) | Easy | Array, binary search | +| 53 | [Maximum Subarray](/problems/maximum-subarray) | Easy | Array, Divide and Conquer, Dynamic Programming | +| 70 | [Climbing Stairs](/problems/climbing-stairs) | Easy | Dynamic Programming | +| 121 | [Best Time to Buy and Sell Stock](/problems/best-time-to-buy-and-sell-stock) | Easy | Array, Dynamic Programming | | 136 | [Single Number](/problems/single-number) | Easy | Hash table, bit manipulation | | 189 | [Rotate Array](/problems/rotate-array) | Easy | Array | +| 198 | [House Robber](/problems/house-robber) | Easy | Dynamic Programming | +| 303 | [Range Sum Query - Immutable](/problems/range-sum-query-immutable) | Easy | Dynamic Programming | | 349 | [Intersection of Two Arrays](/problems/intersection-of-two-arrays) | Easy | Hash table, two pointers, binary search, sort, set | | 350 | [Intersection of Two Arrays II](/problems/intersection-of-two-arrays-ii) | Easy | Hash Table, two pointers, binary search, sort | +| 392 | [Is Subsequence](/problems/is-subsequence) | Easy | Binary Search, Dynamic Programming, Greedy | +| 746 | [Min Cost Climbing Stairs](/problems/min-cost-climbing-stairs) | Easy | Array, Dynamic Programming | +| 1025 | [Divisor Game](/problems/divisor-game) | Easy | Math, Dynamic Programming | | 1144 | [Decrease Elements To Make Array Zigzag](/problems/decrease-elements-to-make-array-zigzag) | Medium | Array | | 1145 | [Binary Tree Coloring Game](/problems/binary-tree-coloring-game/) | Medium | Tree, depth-first search | | 1150 | [Check If a Number Is Majority Element in a Sorted Array](/problems/is-a-a-majority-element) | Easy | Array, binary search | diff --git a/package-lock.json b/package-lock.json index 3627601..e5268b8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "leetcode", - "version": "1.21.0", + "version": "1.22.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index cbca99b..0376ffb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "leetcode", - "version": "1.21.0", + "version": "1.22.0", "description": "My solutions for LeetCode problems.", "main": "index.js", "scripts": { diff --git a/problems/best-time-to-buy-and-sell-stock/README.md b/problems/best-time-to-buy-and-sell-stock/README.md new file mode 100644 index 0000000..e754d77 --- /dev/null +++ b/problems/best-time-to-buy-and-sell-stock/README.md @@ -0,0 +1,33 @@ +# Best Time to Buy and Sell Stock + +LeetCode #: [121](https://leetcode.com/problems/best-time-to-buy-and-sell-stock/) + +Difficulty: Easy + +Topics: Array, dynamic programming. + +## Problem + +Say you have an array for which the `i`th element is the price of a given stock on day `i`. + +If you were only permitted to complete at most one transaction (i.e., buy one and sell one share of the stock), design an algorithm to find the maximum profit. + +Note that you cannot sell a stock before you buy one. + +Example 1: + +```text +Input: [7,1,5,3,6,4] +Output: 5 +Explanation: +Buy on day 2 (price = 1) and sell on day 5 (price = 6), profit = 6-1 = 5. +Not 7-1 = 6, as selling price needs to be larger than buying price. +``` + +Example 2: + +```text +Input: [7,6,4,3,1] +Output: 0 +Explanation: In this case, no transaction is done, i.e. max profit = 0. +``` diff --git a/problems/best-time-to-buy-and-sell-stock/maxProfit.js b/problems/best-time-to-buy-and-sell-stock/maxProfit.js new file mode 100644 index 0000000..fe6934b --- /dev/null +++ b/problems/best-time-to-buy-and-sell-stock/maxProfit.js @@ -0,0 +1,24 @@ +/** + * @param {number[]} prices + * @return {number} + */ +const maxProfit = (prices) => { + let curProfit = 0 + let posBuyDay = 0 + + for (let i = 1; i < prices.length; i++) { + const curPrice = prices[i] + + if (curPrice < prices[posBuyDay]) { + posBuyDay = i + } + + if (curPrice - prices[posBuyDay] > curProfit) { + curProfit = curPrice - prices[posBuyDay] + } + } + + return curProfit +} + +module.exports = maxProfit diff --git a/problems/best-time-to-buy-and-sell-stock/maxProfit.test.js b/problems/best-time-to-buy-and-sell-stock/maxProfit.test.js new file mode 100644 index 0000000..b443b4e --- /dev/null +++ b/problems/best-time-to-buy-and-sell-stock/maxProfit.test.js @@ -0,0 +1,17 @@ +const maxProfit = require('./maxProfit') + +test('Example 1', () => { + const prices = [7, 1, 5, 3, 6, 4] + + const result = maxProfit(prices) + + expect(result).toBe(5) +}) + +test('Example 2', () => { + const prices = [7, 6, 4, 3, 1] + + const result = maxProfit(prices) + + expect(result).toBe(0) +}) diff --git a/problems/climbing-stairs/README.md b/problems/climbing-stairs/README.md new file mode 100644 index 0000000..50a1682 --- /dev/null +++ b/problems/climbing-stairs/README.md @@ -0,0 +1,36 @@ +# Climbing Stairs + +LeetCode #: [70](https://leetcode.com/problems/climbing-stairs/) + +Difficulty: Easy + +Topics: Dynamic Programming. + +## Problem + +You are climbing a stair case. It takes `n` steps to reach to the top. + +Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top? + +Note: Given `n` will be a positive integer. + +Example 1: + +```text +Input: 2 +Output: 2 +Explanation: There are two ways to climb to the top. +1. 1 step + 1 step +2. 2 steps +``` + +Example 2: + +```text +Input: 3 +Output: 3 +Explanation: There are three ways to climb to the top. +1. 1 step + 1 step + 1 step +2. 1 step + 2 steps +3. 2 steps + 1 step +``` diff --git a/problems/climbing-stairs/climbStairs.js b/problems/climbing-stairs/climbStairs.js new file mode 100644 index 0000000..c1aeccf --- /dev/null +++ b/problems/climbing-stairs/climbStairs.js @@ -0,0 +1,22 @@ +/** + * @param {number} n + * @return {number} + */ +const climbStairs = (n) => { + if (n === 1) return 1 + if (n === 2) return 2 + + let dist2 = 1 + let dist1 = 2 + let cur = 0 + for (let i = 3; i <= n; i++) { + cur = dist1 + dist2 + + dist2 = dist1 + dist1 = cur + } + + return cur +} + +module.exports = climbStairs diff --git a/problems/climbing-stairs/climbStairs.test.js b/problems/climbing-stairs/climbStairs.test.js new file mode 100644 index 0000000..7b8f044 --- /dev/null +++ b/problems/climbing-stairs/climbStairs.test.js @@ -0,0 +1,41 @@ +const climbStairs = require('./climbStairs') + +test('Example 1', () => { + const n = 2 + + const result = climbStairs(n) + + expect(result).toBe(2) +}) + +test('Example 2', () => { + const n = 3 + + const result = climbStairs(n) + + expect(result).toBe(3) +}) + +test('n=1 should return 1', () => { + const n = 1 + + const result = climbStairs(n) + + expect(result).toBe(1) +}) + +test('n=4 should return 5', () => { + const n = 4 + + const result = climbStairs(n) + + expect(result).toBe(5) +}) + +test('n=5 should return 8', () => { + const n = 5 + + const result = climbStairs(n) + + expect(result).toBe(8) +}) diff --git a/problems/divisor-game/README.md b/problems/divisor-game/README.md new file mode 100644 index 0000000..cad96be --- /dev/null +++ b/problems/divisor-game/README.md @@ -0,0 +1,45 @@ +# Divisor Game + +LeetCode #: [1025](https://leetcode.com/problems/divisor-game/) + +Difficulty: Easy + +Topic: Math, Dynamic Programming. + +## Problem + +Alice and Bob take turns playing a game, with Alice starting first. + +Initially, there is a number `N` on the chalkboard. On each player's turn, that player makes a move consisting of: + +- Choosing any `x` with `0 < x < N` and `N % x == 0`. +- Replacing the number `N` on the chalkboard with `N - x`. + +Also, if a player cannot make a move, they lose the game. + +Return `True` if and only if Alice wins the game, assuming both players play optimally. + +Example 1: + +```text +Input: 2 +Output: true +Explanation: Alice chooses 1, and Bob has no more moves. +``` + +Example 2: + +```text +Input: 3 +Output: false +Explanation: Alice chooses 1, Bob chooses 1, and Alice has no more moves. +``` + +Note: + +- `1 <= N <= 1000` + +## Solution Reference + +- [Solution by bupt_wc](https://leetcode.com/problems/divisor-game/discuss/274566/just-return-N-2-0-(proof)) +- [Solution by lee215](https://leetcode.com/problems/divisor-game/discuss/274606/JavaC%2B%2BPython-return-N-2-0) diff --git a/problems/divisor-game/divisorGame.js b/problems/divisor-game/divisorGame.js new file mode 100644 index 0000000..b49f58d --- /dev/null +++ b/problems/divisor-game/divisorGame.js @@ -0,0 +1,9 @@ +/** + * @param {number} N + * @return {boolean} + */ +const divisorGame = (N) => { + return N % 2 === 0 +} + +module.exports = divisorGame diff --git a/problems/divisor-game/divisorGame.test.js b/problems/divisor-game/divisorGame.test.js new file mode 100644 index 0000000..3023174 --- /dev/null +++ b/problems/divisor-game/divisorGame.test.js @@ -0,0 +1,17 @@ +const divisorGame = require('./divisorGame') + +test('Example 1', () => { + const N = 2 + + const result = divisorGame(N) + + expect(result).toBe(true) +}) + +test('Example 2', () => { + const N = 3 + + const result = divisorGame(N) + + expect(result).toBe(false) +}) diff --git a/problems/house-robber/README.md b/problems/house-robber/README.md new file mode 100644 index 0000000..613f574 --- /dev/null +++ b/problems/house-robber/README.md @@ -0,0 +1,33 @@ +# House Robber + +LeetCode #: [198](https://leetcode.com/problems/house-robber/) + +Difficulty: Easy + +Topics: Dynamic Programming. + +## Problem + +You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security system connected and it will automatically contact the police if two adjacent houses were broken into on the same night. + +Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police. + +Example 1: + +```text +Input: [1,2,3,1] +Output: 4 +Explanation: +Rob house 1 (money = 1) and then rob house 3 (money = 3). +Total amount you can rob = 1 + 3 = 4. +``` + +Example 2: + +```text +Input: [2,7,9,3,1] +Output: 12 +Explanation: +Rob house 1 (money = 2), rob house 3 (money = 9) and rob house 5 (money = 1). +Total amount you can rob = 2 + 9 + 1 = 12. +``` diff --git a/problems/house-robber/rob.js b/problems/house-robber/rob.js new file mode 100644 index 0000000..a904b25 --- /dev/null +++ b/problems/house-robber/rob.js @@ -0,0 +1,21 @@ +const rob = (nums) => { + if (nums.length === 0) return 0 + if (nums.length === 1) return nums[0] + + let amountP2 = nums[0] + let amountP1 = Math.max(nums[0], nums[1]) + + for (let i = 2; i < nums.length; i++) { + const cur = Math.max( + amountP2 + nums[i], + amountP1 + ) + + amountP2 = amountP1 + amountP1 = cur + } + + return Math.max(amountP2, amountP1) +} + +module.exports = rob diff --git a/problems/house-robber/rob.test.js b/problems/house-robber/rob.test.js new file mode 100644 index 0000000..531b95d --- /dev/null +++ b/problems/house-robber/rob.test.js @@ -0,0 +1,57 @@ +const rob = require('./rob') + +test('Example 1', () => { + const nums = [1, 2, 3, 1] + + const result = rob(nums) + + expect(result).toBe(4) +}) + +test('Example 2', () => { + const nums = [2, 7, 9, 3, 1] + + const result = rob(nums) + + expect(result).toBe(12) +}) + +test('[3, 100, 3, 100, 3] should return 200', () => { + const nums = [3, 100, 3, 100, 3] + + const result = rob(nums) + + expect(result).toBe(200) +}) + +test('[3, 100, 3, 3, 100] should return 200', () => { + const nums = [3, 100, 3, 3, 100] + + const result = rob(nums) + + expect(result).toBe(200) +}) + +test('[2, 1, 1, 2] should return 4', () => { + const nums = [2, 1, 1, 2] + + const result = rob(nums) + + expect(result).toBe(4) +}) + +test('[] should return 0', () => { + const nums = [] + + const result = rob(nums) + + expect(result).toBe(0) +}) + +test('[10] should return 10', () => { + const nums = [10] + + const result = rob(nums) + + expect(result).toBe(10) +}) diff --git a/problems/is-subsequence/README.md b/problems/is-subsequence/README.md new file mode 100644 index 0000000..89e6cec --- /dev/null +++ b/problems/is-subsequence/README.md @@ -0,0 +1,37 @@ +# Is Subsequence + +LeetCode #: [392](https://leetcode.com/problems/is-subsequence/) + +Difficulty: Easy + +Topic: Binary Search, Dynamic Programming, Greedy. + +## Problem + +Given a string `s` and a string `t`, check if `s` is subsequence of `t`. + +You may assume that there is only lower case English letters in both `s` and `t`. `t` is potentially a very long (length ~= 500,000) string, and `s` is a short string (<=100). + +A subsequence of a string is a new string which is formed from the original string by deleting some (can be none) of the characters without disturbing the relative positions of the remaining characters. (ie, `"ace"` is a subsequence of `"abcde"` while `"aec"` is not). + +Example 1: + +```text +s = "abc", t = "ahbgdc" + +Return true. +``` + +Example 2: + +```text +s = "axc", t = "ahbgdc" + +Return false. +``` + +Follow up: + +If there are lots of incoming S, say S1, S2, ... , Sk where k >= 1B, and you want to check one by one to see if T has its subsequence. In this scenario, how would you change your code? + +*See [follow up solution](/follow-up-solution) for my answer to this follow up question.* diff --git a/problems/is-subsequence/follow-up-solution/README.md b/problems/is-subsequence/follow-up-solution/README.md new file mode 100644 index 0000000..27d7c03 --- /dev/null +++ b/problems/is-subsequence/follow-up-solution/README.md @@ -0,0 +1,7 @@ +# Is Subsequence - Follow Up Solution + +This alternative solution can be used for the follow up question: + +> If there are lots of incoming S, say S1, S2, ... , Sk where k >= 1B, and you want to check one by one to see if T has its subsequence. In this scenario, how would you change your code? + +The solution loops through all the characters in T once to generate a map object indicating the positions of each character. The positions are stored in an array, naturally sorted. Then for each S, we can use binary search on the positions array to quickly determine whether it is a subsequence or not. diff --git a/problems/is-subsequence/follow-up-solution/isSubsequence.js b/problems/is-subsequence/follow-up-solution/isSubsequence.js new file mode 100644 index 0000000..91c2111 --- /dev/null +++ b/problems/is-subsequence/follow-up-solution/isSubsequence.js @@ -0,0 +1,51 @@ +const sortedIndex = require('lodash/sortedIndex') + +const getMap = (t) => { + const map = new Array(26) + + for (let i = 0; i < t.length; i++) { + const charCodeIdx = t[i].charCodeAt(0) - 97 + + if (map[charCodeIdx] === undefined) { + map[charCodeIdx] = [] + } + + map[charCodeIdx].push(i) + } + + return map +} + +const _isSubsequence = (s, map) => { + let ptr = 0 + for (let i = 0; i < s.length; i++) { + const charCodeIdx = s[i].charCodeAt(0) - 97 + const charPositions = map[charCodeIdx] + + if (charPositions === undefined) { + return false + } + + const foundIndex = sortedIndex(charPositions, ptr) + if (foundIndex === charPositions.length) { + return false + } + + ptr = charPositions[foundIndex] + 1 + } + + return true +} + +/** + * @param {string} s + * @param {string} t + * @return {boolean} + */ +const isSubsequence = (s, t) => { + const map = getMap(t) + + return _isSubsequence(s, map) +} + +module.exports = isSubsequence diff --git a/problems/is-subsequence/follow-up-solution/isSubsequence.test.js b/problems/is-subsequence/follow-up-solution/isSubsequence.test.js new file mode 100644 index 0000000..3542b6b --- /dev/null +++ b/problems/is-subsequence/follow-up-solution/isSubsequence.test.js @@ -0,0 +1,37 @@ +const isSubsequence = require('./isSubsequence') + +test('Example 1', () => { + const s = 'abc' + const t = 'ahbgdc' + + const result = isSubsequence(s, t) + + expect(result).toBe(true) +}) + +test('Example 2', () => { + const s = 'axc' + const t = 'ahbgdc' + + const result = isSubsequence(s, t) + + expect(result).toBe(false) +}) + +test('s=agc, returns true', () => { + const s = 'agc' + const t = 'ahbagdca' + + const result = isSubsequence(s, t) + + expect(result).toBe(true) +}) + +test('s=gac, c cannot be found after g and a, returns false', () => { + const s = 'gac' + const t = 'ahbagdca' + + const result = isSubsequence(s, t) + + expect(result).toBe(false) +}) diff --git a/problems/is-subsequence/isSubsequence.js b/problems/is-subsequence/isSubsequence.js new file mode 100644 index 0000000..1e02827 --- /dev/null +++ b/problems/is-subsequence/isSubsequence.js @@ -0,0 +1,22 @@ +/** + * @param {string} s + * @param {string} t + * @return {boolean} + */ +const isSubsequence = (s, t) => { + let fromIndex = 0 + for (let i = 0; i < s.length; i++) { + const char = s[i] + + const foundIndex = t.indexOf(char, fromIndex) + if (foundIndex === -1) { + return false + } + + fromIndex = foundIndex + 1 + } + + return true +} + +module.exports = isSubsequence diff --git a/problems/is-subsequence/isSubsequence.test.js b/problems/is-subsequence/isSubsequence.test.js new file mode 100644 index 0000000..3542b6b --- /dev/null +++ b/problems/is-subsequence/isSubsequence.test.js @@ -0,0 +1,37 @@ +const isSubsequence = require('./isSubsequence') + +test('Example 1', () => { + const s = 'abc' + const t = 'ahbgdc' + + const result = isSubsequence(s, t) + + expect(result).toBe(true) +}) + +test('Example 2', () => { + const s = 'axc' + const t = 'ahbgdc' + + const result = isSubsequence(s, t) + + expect(result).toBe(false) +}) + +test('s=agc, returns true', () => { + const s = 'agc' + const t = 'ahbagdca' + + const result = isSubsequence(s, t) + + expect(result).toBe(true) +}) + +test('s=gac, c cannot be found after g and a, returns false', () => { + const s = 'gac' + const t = 'ahbagdca' + + const result = isSubsequence(s, t) + + expect(result).toBe(false) +}) diff --git a/problems/maximum-subarray/README.md b/problems/maximum-subarray/README.md new file mode 100644 index 0000000..6f598e4 --- /dev/null +++ b/problems/maximum-subarray/README.md @@ -0,0 +1,29 @@ +# Maximum Subarray + +LeetCode #: [53](https://leetcode.com/problems/maximum-subarray/) + +Difficulty: Easy + +Topics: Array, Divide and Conquer, Dynamic Programming. + +## Problem + +Given an integer array `nums`, find the contiguous subarray (containing at least one number) which has the largest sum and return its sum. + +Example: + +```text +Input: [-2,1,-3,4,-1,2,1,-5,4], +Output: 6 +Explanation: [4,-1,2,1] has the largest sum = 6. +``` + +## Solution Explanation + +This problem is solved with [Kadane's algorithm](https://en.wikipedia.org/wiki/Maximum_subarray_problem#Kadane's_algorithm) that has O(n) time complexity. + +## Complexity Analysis + +Time complexity: O(n) + +Space complexity: O(1) diff --git a/problems/maximum-subarray/maxSubArray.js b/problems/maximum-subarray/maxSubArray.js new file mode 100644 index 0000000..bff0b3c --- /dev/null +++ b/problems/maximum-subarray/maxSubArray.js @@ -0,0 +1,13 @@ +const maxSubArray = (nums) => { + let curMax = nums[0] + let max = nums[0] + + for (let i = 1; i < nums.length; i++) { + curMax = Math.max(curMax + nums[i], nums[i]) + max = Math.max(max, curMax) + } + + return max +} + +module.exports = maxSubArray diff --git a/problems/maximum-subarray/maxSubArray.test.js b/problems/maximum-subarray/maxSubArray.test.js new file mode 100644 index 0000000..4a68ea2 --- /dev/null +++ b/problems/maximum-subarray/maxSubArray.test.js @@ -0,0 +1,17 @@ +const maxSubArray = require('./maxSubArray') + +test('Example 1', () => { + const nums = [-2, 1, -3, 4, -1, 2, 1, -5, 4] + + const result = maxSubArray(nums) + + expect(result).toBe(6) +}) + +test('Example 2', () => { + const nums = [-3, 2, 4, -3] + + const result = maxSubArray(nums) + + expect(result).toBe(6) +}) diff --git a/problems/min-cost-climbing-stairs/README.md b/problems/min-cost-climbing-stairs/README.md new file mode 100644 index 0000000..417080b --- /dev/null +++ b/problems/min-cost-climbing-stairs/README.md @@ -0,0 +1,34 @@ +# Min Cost Climbing Stairs + +LeetCode #: [746](https://leetcode.com/problems/min-cost-climbing-stairs/) + +Difficulty: Easy + +Topics: Dynamic Programming. + +## Problem + +On a staircase, the `i`-th step has some non-negative cost `cost[i]` assigned (0 indexed). + +Once you pay the cost, you can either climb one or two steps. You need to find minimum cost to reach the top of the floor, and you can either start from the step with index 0, or the step with index 1. + +Example 1: + +```text +Input: cost = [10, 15, 20] +Output: 15 +Explanation: Cheapest is start on cost[1], pay that cost and go to the top. +``` + +Example 2: + +```text +Input: cost = [1, 100, 1, 1, 1, 100, 1, 1, 100, 1] +Output: 6 +Explanation: Cheapest is start on cost[0], and only step on 1s, skipping cost[3]. +``` + +Note: + +1. `cost` will have a length in the range `[2, 1000]`. +2. Every `cost[i]` will be an integer in the range `[0, 999]`. diff --git a/problems/min-cost-climbing-stairs/minCostClimbingStairs.js b/problems/min-cost-climbing-stairs/minCostClimbingStairs.js new file mode 100644 index 0000000..ee7a230 --- /dev/null +++ b/problems/min-cost-climbing-stairs/minCostClimbingStairs.js @@ -0,0 +1,39 @@ +const getCalculateCost = (cost, stepMinCostMap) => { + const calculateCost = (dest) => { + if (dest === 1) { + return 0 + } + + if (dest === 2) { + return Math.min(cost[0], cost[1]) + } + + if (!stepMinCostMap.has(dest - 2)) { + stepMinCostMap.set(dest - 2, calculateCost(dest - 2)) + } + + if (!stepMinCostMap.has(dest - 1)) { + stepMinCostMap.set(dest - 1, calculateCost(dest - 1)) + } + + const last2step = stepMinCostMap.get(dest - 2) + cost[dest - 2] + const last1step = stepMinCostMap.get(dest - 1) + cost[dest - 1] + + const result = Math.min(last2step, last1step) + + return result + } + + return calculateCost +} + +const minCostClimbingStairs = (cost) => { + const stepMinCostMap = new Map() + const calculateCost = getCalculateCost(cost, stepMinCostMap) + + const result = calculateCost(cost.length) + + return result +} + +module.exports = minCostClimbingStairs diff --git a/problems/min-cost-climbing-stairs/minCostClimbingStairs.test.js b/problems/min-cost-climbing-stairs/minCostClimbingStairs.test.js new file mode 100644 index 0000000..8e9a5db --- /dev/null +++ b/problems/min-cost-climbing-stairs/minCostClimbingStairs.test.js @@ -0,0 +1,17 @@ +const minCostClimbingStairs = require('./minCostClimbingStairs') + +test('Example 1', () => { + const cost = [10, 15, 20] + + const result = minCostClimbingStairs(cost) + + expect(result).toBe(15) +}) + +test('Example 2', () => { + const cost = [1, 100, 1, 1, 1, 100, 1, 1, 100, 1] + + const result = minCostClimbingStairs(cost) + + expect(result).toBe(6) +}) diff --git a/problems/range-sum-query-immutable/NumArray.js b/problems/range-sum-query-immutable/NumArray.js new file mode 100644 index 0000000..4cdcc51 --- /dev/null +++ b/problems/range-sum-query-immutable/NumArray.js @@ -0,0 +1,22 @@ +/** + * @param {number[]} nums + */ +const NumArray = function (nums) { + this.prefixSum = [0] + + for (let i = 0; i < nums.length; i++) { + const curSum = this.prefixSum[this.prefixSum.length - 1] + nums[i] + this.prefixSum.push(curSum) + } +} + +/** + * @param {number} i + * @param {number} j + * @return {number} + */ +NumArray.prototype.sumRange = function (i, j) { + return this.prefixSum[j + 1] - this.prefixSum[i] +} + +module.exports = NumArray diff --git a/problems/range-sum-query-immutable/NumArray.test.js b/problems/range-sum-query-immutable/NumArray.test.js new file mode 100644 index 0000000..f2189be --- /dev/null +++ b/problems/range-sum-query-immutable/NumArray.test.js @@ -0,0 +1,15 @@ +const NumArray = require('./NumArray') + +test('Example 1', () => { + const nums = [-2, 0, 3, -5, 2, -1] + const numArray = new NumArray(nums) + + const result1 = numArray.sumRange(0, 2) + expect(result1).toBe(1) + + const result2 = numArray.sumRange(2, 5) + expect(result2).toBe(-1) + + const result3 = numArray.sumRange(0, 5) + expect(result3).toBe(-3) +}) diff --git a/problems/range-sum-query-immutable/README.md b/problems/range-sum-query-immutable/README.md new file mode 100644 index 0000000..9d62d05 --- /dev/null +++ b/problems/range-sum-query-immutable/README.md @@ -0,0 +1,26 @@ +# Range Sum Query - Immutable + +LeetCode #: [303](https://leetcode.com/problems/range-sum-query-immutable/) + +Difficulty: Easy + +Topic: Dynamic Programming. + +## Problem + +Given an integer array `nums`, find the sum of the elements between indices `i` and `j` (`i ≤ j`), inclusive. + +Example: + +```text +Given nums = [-2, 0, 3, -5, 2, -1] + +sumRange(0, 2) -> 1 +sumRange(2, 5) -> -1 +sumRange(0, 5) -> -3 +``` + +Note: + +- You may assume that the array does not change. +- There are many calls to `sumRange` function.