Skip to content

Commit

Permalink
Merge branch 'feature/weekly-contest-150' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
ecgan committed Aug 18, 2019
2 parents 63b67c7 + 5a8a57f commit afa389e
Show file tree
Hide file tree
Showing 10 changed files with 352 additions and 2 deletions.
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,15 @@ Folder structure in this repository: https://<span></span>github.com/ecgan/leetc
|-----------:|:------|:-----------|:-------|
| 1 | [Two Sum](/problems/two-sum) | Easy | Array, hash table |
| 136 | [Single Number](/problems/single-number) | Easy | Hash table, bit manipulation |
| 349 | [Intersection of Two Arrays](/problems/intersection-of-two-arrays) | Easy | Hash Table, two pointers, binary search, sort, set |
| 349 | [Intersection of Two Arrays](/problems/intersection-of-two-arrays) | Easy | Hash table, two pointers, binary search, sort, set |
| 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 |
| 1153 | [String Transforms Into Another String](/problems/string-transforms-into-another-string) | Hard | Graph |
| 1154 | [Day of the Year](/problems/ordinal-number-of-date) | Easy | - |
| 1154 | [Day of the Year](/problems/ordinal-number-of-date) | Easy | Math |
| 1160 | [Find Words That Can Be Formed by Characters](/problems/find-words-that-can-be-formed-by-characters) | Easy | Array, hash table |
| 1161 | [Maximum Level Sum of a Binary Tree](/problems/maximum-level-sum-of-a-binary-tree) | Medium | Graph |
| 1162 | [As Far from Land as Possible](/problems/as-far-from-land-as-possible) | Medium | Breadth-first search, graph |

## Questions / Issues

Expand Down
15 changes: 15 additions & 0 deletions problems/as-far-from-land-as-possible/README.md
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.
115 changes: 115 additions & 0 deletions problems/as-far-from-land-as-possible/solution.js
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
45 changes: 45 additions & 0 deletions problems/as-far-from-land-as-possible/solution.test.js
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 problems/find-words-that-can-be-formed-by-characters/README.md
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 problems/find-words-that-can-be-formed-by-characters/solution.js
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
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)
})
15 changes: 15 additions & 0 deletions problems/maximum-level-sum-of-a-binary-tree/README.md
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.
52 changes: 52 additions & 0 deletions problems/maximum-level-sum-of-a-binary-tree/solution.js
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 problems/maximum-level-sum-of-a-binary-tree/solution.test.js
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)
})

0 comments on commit afa389e

Please sign in to comment.