-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'feature/weekly-contest-150' into develop
- Loading branch information
Showing
10 changed files
with
352 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# As Far from Land as Possible | ||
|
||
LeetCode #: [1162](https://leetcode.com/problems/as-far-from-land-as-possible/) | ||
|
||
Difficulty: Medium | ||
|
||
Topic: Breadth-First Search, Graph. | ||
|
||
## Complexity Analysis | ||
|
||
Assume `n` is the total number of cells in the input array. | ||
|
||
### Time complexity: O(n) | ||
|
||
The solution will go through all the `n` cells twice. The first time is to get the initial list of lands. The second time is to perform breadth-first search based on the list of lands to get the maximum distance. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
/** | ||
* Convert land's adjacent waters into new lands, and return the new lands. This will mutate values in the input array. | ||
* @param {*} input | ||
* @param {*} land | ||
*/ | ||
const getAdjacentLands = (input, land) => { | ||
const nextLands = [] | ||
|
||
if (land.row - 1 >= 0) { | ||
if (input[land.row - 1] && input[land.row - 1][land.col] === 0) { | ||
input[land.row - 1][land.col] = 1 | ||
nextLands.push({ row: land.row - 1, col: land.col }) | ||
} | ||
} | ||
|
||
if (land.row + 1 < input.length) { | ||
if (input[land.row + 1] && input[land.row + 1][land.col] === 0) { | ||
input[land.row + 1][land.col] = 1 | ||
nextLands.push({ row: land.row + 1, col: land.col }) | ||
} | ||
} | ||
|
||
if (land.col - 1 >= 0) { | ||
if (input[land.row][land.col - 1] === 0) { | ||
input[land.row][land.col - 1] = 1 | ||
nextLands.push({ row: land.row, col: land.col - 1 }) | ||
} | ||
} | ||
|
||
const maxCol = input[land.row].length | ||
if (land.col + 1 < maxCol) { | ||
if (input[land.row][land.col + 1] === 0) { | ||
input[land.row][land.col + 1] = 1 | ||
nextLands.push({ row: land.row, col: land.col + 1 }) | ||
} | ||
} | ||
|
||
return nextLands | ||
} | ||
|
||
/** | ||
* Perform breadth-first search through the input array, converting 0 to 1 while calculating the distance from the original lands. This will mutate values in the input array. | ||
* @param {*} input Array. | ||
* @param {*} lands Current lands. Array of { row, col }. | ||
* @param {Number} distance Current distance of lands. | ||
*/ | ||
const getDistance = (input, lands, distance) => { | ||
const nextLands = [] | ||
|
||
for (const land of lands) { | ||
const tempNextLands = getAdjacentLands(input, land) | ||
nextLands.push(...tempNextLands) | ||
} | ||
|
||
if (nextLands.length === 0) { | ||
return distance | ||
} | ||
|
||
const nextDistance = distance + 1 | ||
|
||
return getDistance(input, nextLands, nextDistance) | ||
} | ||
|
||
/** | ||
* Iterare through all cells in input[row][col] and returns { lands[{row, col}], hasLand, hasWater }. | ||
* @param {*} input | ||
*/ | ||
const getInitialInfo = (input) => { | ||
const lands = [] | ||
let hasLand = false | ||
let hasWater = false | ||
|
||
for (let i = 0; i < input.length; i++) { | ||
const eli = input[i] | ||
|
||
for (let j = 0; j < eli.length; j++) { | ||
const elj = eli[j] | ||
|
||
if (elj === 1) { | ||
hasLand = true | ||
|
||
lands.push({ | ||
row: i, | ||
col: j | ||
}) | ||
} | ||
|
||
if (elj === 0) { | ||
hasWater = true | ||
} | ||
} | ||
} | ||
|
||
return { | ||
lands, | ||
hasLand, | ||
hasWater | ||
} | ||
} | ||
|
||
const maxDistance = (input) => { | ||
const { lands, hasLand, hasWater } = getInitialInfo(input) | ||
|
||
if (!hasWater) { | ||
return -1 | ||
} | ||
|
||
if (!hasLand) { | ||
return -1 | ||
} | ||
|
||
return getDistance(input, lands, 0) | ||
} | ||
|
||
module.exports = maxDistance |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
const maxDistance = require('./solution') | ||
|
||
test('Example 1', () => { | ||
const input = [[1, 0, 1], [0, 0, 0], [1, 0, 1]] | ||
|
||
const result = maxDistance(input) | ||
|
||
expect(result).toBe(2) | ||
}) | ||
|
||
test('Example 2', () => { | ||
const input = [[1, 0, 0], [0, 0, 0], [0, 0, 0]] | ||
|
||
const result = maxDistance(input) | ||
|
||
expect(result).toBe(4) | ||
}) | ||
|
||
test('All water', () => { | ||
const input = [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] | ||
|
||
const result = maxDistance(input) | ||
|
||
expect(result).toBe(-1) | ||
}) | ||
|
||
test('All land', () => { | ||
const input = [[1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1], [1, 1, 1, 1]] | ||
|
||
const result = maxDistance(input) | ||
|
||
expect(result).toBe(-1) | ||
}) | ||
|
||
test('One land in the middle', () => { | ||
const input = [ | ||
[0, 0, 0], | ||
[0, 1, 0], | ||
[0, 0, 0] | ||
] | ||
|
||
const result = maxDistance(input) | ||
|
||
expect(result).toBe(4) | ||
}) |
23 changes: 23 additions & 0 deletions
23
problems/find-words-that-can-be-formed-by-characters/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# Find Words That Can Be Formed by Characters | ||
|
||
LeetCode #: [1160](https://leetcode.com/problems/find-words-that-can-be-formed-by-characters/) | ||
|
||
Difficulty: Easy | ||
|
||
Topics: Array, hash table. | ||
|
||
## Explanation | ||
|
||
This solution makes use of JavaScript [Map](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) objects as hashtable to store the counts of characters. | ||
|
||
## Complexity Analysis | ||
|
||
Assume `m` is the total number of characters in all the word in `words`, and `n` is the total number of characters in `chars`. | ||
|
||
### Time complexity: O(m+n) | ||
|
||
In the worst case, the solution will go through all the `m` and `n` characters once. | ||
|
||
### Space complexity: O(m+n) | ||
|
||
In the worst case, the size of the hash tables would be `m` and `n`. |
52 changes: 52 additions & 0 deletions
52
problems/find-words-that-can-be-formed-by-characters/solution.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
/** | ||
* Check if the word is within charMap. | ||
* @param {*} word | ||
* @param {*} charMap | ||
*/ | ||
const isWordInCharMap = (word, charMap) => { | ||
const wMap = new Map() | ||
const ws = word.split('') | ||
|
||
for (const w of ws) { | ||
if (wMap.has(w)) { | ||
wMap.set(w, wMap.get(w) + 1) | ||
} else { | ||
wMap.set(w, 1) | ||
} | ||
|
||
if ( | ||
(!charMap.get(w)) || | ||
(wMap.get(w) > charMap.get(w)) | ||
) { | ||
return false | ||
} | ||
} | ||
|
||
return true | ||
} | ||
|
||
/** | ||
* @param {string[]} words | ||
* @param {string} chars | ||
* @return {number} | ||
*/ | ||
const countCharacters = function (words, chars) { | ||
const charMap = new Map() | ||
chars.split('').forEach((c) => { | ||
if (charMap.has(c)) { | ||
charMap.set(c, charMap.get(c) + 1) | ||
} else { | ||
charMap.set(c, 1) | ||
} | ||
}) | ||
|
||
const length = words.reduce((acc, cur) => { | ||
return isWordInCharMap(cur, charMap) | ||
? acc + cur.length | ||
: acc | ||
}, 0) | ||
|
||
return length | ||
} | ||
|
||
module.exports = countCharacters |
19 changes: 19 additions & 0 deletions
19
problems/find-words-that-can-be-formed-by-characters/solution.test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
const countCharacters = require('./solution') | ||
|
||
test('Example 1', () => { | ||
const words = ['cat', 'bt', 'hat', 'tree'] | ||
const chars = 'atach' | ||
|
||
const result = countCharacters(words, chars) | ||
|
||
expect(result).toBe(6) | ||
}) | ||
|
||
test('Example 2', () => { | ||
const words = ['hello', 'world', 'leetcode'] | ||
const chars = 'welldonehoneyr' | ||
|
||
const result = countCharacters(words, chars) | ||
|
||
expect(result).toBe(10) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# Maximum Level Sum of a Binary Tree | ||
|
||
LeetCode #: [1161](https://leetcode.com/problems/maximum-level-sum-of-a-binary-tree/) | ||
|
||
Difficulty: Medium | ||
|
||
Topic: Binary Tree, Graph. | ||
|
||
## Complexity Analysis | ||
|
||
Assume `n` is the number of nodes in the `root` tree. | ||
|
||
### Time complexity: O(n) | ||
|
||
The solution will go through all the `n` nodes once. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
/** | ||
* Definition for a binary tree node. | ||
* function TreeNode(val) { | ||
* this.val = val; | ||
* this.left = this.right = null; | ||
* } | ||
*/ | ||
|
||
/** | ||
* @param {TreeNode} root | ||
* @return {number} | ||
*/ | ||
const maxLevelSum = function (root) { | ||
let maxSum = Number.MIN_SAFE_INTEGER | ||
let maxSumLevel = 0 | ||
|
||
const nodeQueue = [root] | ||
let currentLevel = 1 | ||
let currentLevelNodeCount = 1 | ||
let currentLevelSum = 0 | ||
|
||
while (nodeQueue.length > 0) { | ||
const node = nodeQueue.shift() | ||
|
||
currentLevelSum += node.val | ||
|
||
if (node.left) { | ||
nodeQueue.push(node.left) | ||
} | ||
|
||
if (node.right) { | ||
nodeQueue.push(node.right) | ||
} | ||
|
||
currentLevelNodeCount -= 1 | ||
|
||
if (currentLevelNodeCount === 0) { | ||
if (currentLevelSum > maxSum) { | ||
maxSum = currentLevelSum | ||
maxSumLevel = currentLevel | ||
} | ||
|
||
currentLevel += 1 | ||
currentLevelSum = 0 | ||
currentLevelNodeCount = nodeQueue.length | ||
} | ||
} | ||
|
||
return maxSumLevel | ||
} | ||
|
||
module.exports = maxLevelSum |
11 changes: 11 additions & 0 deletions
11
problems/maximum-level-sum-of-a-binary-tree/solution.test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
const leettree = require('leettree') | ||
const maxLevelSum = require('./solution') | ||
|
||
test('Example 1', () => { | ||
const array = [1, 7, 0, 7, -8, null, null] | ||
const root = leettree.deserialize(array) | ||
|
||
const result = maxLevelSum(root) | ||
|
||
expect(result).toBe(2) | ||
}) |