Skip to content

Commit

Permalink
update algorithms
Browse files Browse the repository at this point in the history
  • Loading branch information
ecmadao committed Feb 2, 2020
1 parent dd7c857 commit f6aa179
Show file tree
Hide file tree
Showing 20 changed files with 947 additions and 83 deletions.
2 changes: 2 additions & 0 deletions data-structure.md
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,8 @@ LeetCode 上相关题目:

1. [No.133 Clone Graph](./leetcode/JavaScript/No133.clone-graph.js)

### 并查集 Union Find

### 深度优先搜索 DFS/Depth-First-Search

深度优先搜索:**栈的形式储存待访问顶点,元素后入先出**
Expand Down
24 changes: 13 additions & 11 deletions leetcode/JavaScript/No141.linked-list-cycle.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,19 @@
/**
* @param {ListNode} head
* @return {boolean}
* 快慢双指针
*/
var hasCycle = function(head) {
var set = new Set();
var result = false;
while(head && head.next) {
if (set.has(head)) {
result = true;
break;
}
set.add(head);
head = head.next;
if (!head) return false

let fast = head
let slow = head
while (fast && slow) {
fast = fast.next
if (!fast) return false
fast = fast.next
slow = slow.next
if (fast === slow) return true
}
return result;
};
return false
}
50 changes: 29 additions & 21 deletions leetcode/JavaScript/No143.reorder-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,27 +25,35 @@
* @return {void} Do not return anything, modify head in-place instead.
*/
var reorderList = function(head) {
if (head && head.next && head.next.next) {
var arr = [];
var node = head;
if (!head || !head.next || !head.next.next) return

while (node) {
arr.push(node);
node = node.next;
}
var length = arr.length;
var index = length - 1;
var center = Math.ceil(length / 2);
const queue = []
let slow = head
let fast = head

node = head;
while (index >= center) {
var n = arr[index];
var next = node.next;
node.next = n;
n.next = next;
node = next;
index -= 1;
}
node.next = null;
// 寻找中间点,同时把前半段链表入队列
while (fast && fast.next && fast.next.next) {
fast = fast.next.next
queue.push(slow)
slow = slow.next
}
};

let point = slow.next
let pre = slow.next
if (fast.next) {
queue.push(slow)
} else {
pre = slow
}

while (queue.length) {
const node = queue.pop()
const next = point.next

point.next = node.next
node.next = point
pre.next = next

point = next
}
}
65 changes: 65 additions & 0 deletions leetcode/JavaScript/No254.factor-combinations.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/**
* Difficulty:
* Medium
*
* Desc:
* Numbers can be regarded as product of its factors. For example,
* 8 = 2 x 2 x 2;
* = 2 x 4.
* Write a function that takes an integer n and return all possible combinations of its factors.
*
* Note:
* 1. You may assume that n is always positive.
* 2. Factors should be greater than 1 and less than n.
*
* Example 1:
* Input: 1
* Output: []
*
* Example 2:
* Input: 37
* Output:[]
*
* Example 3:
* Input: 12
* Output:
* [
* [2, 6],
* [2, 2, 3],
* [3, 4]
* ]
*
* Example 4:
* Input: 32
* Output:
* [
* [2, 16],
* [2, 2, 8],
* [2, 2, 2, 4],
* [2, 2, 2, 2, 2],
* [2, 4, 4],
* [4, 8]
* ]
*
* 接收一个整数 n 并返回该整数所有的因子组合
* 1. 可以假定 n 为永远为正数。
* 2. 因子必须大于 1 并且小于 n
*/

/**
* @param {number} n
* @return {number[][]}
*/
var getFactors = function(n, start = 2) {
const results = []

for (let i = start; i * i <= n; i += 1) {
if (n % i !== 0) continue
results.push([n / i, i])
const factors = getFactors(n / i, i)
results.push(
...factors.map(factor => [...factor, i])
)
}
return results
}
26 changes: 18 additions & 8 deletions leetcode/JavaScript/No322.coin-change.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
*
* Note:
* You may assume that you have an infinite number of each kind of coin.
*
* 给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1
*/

/**
Expand Down Expand Up @@ -57,20 +59,28 @@ var coinChange = function(coins, amount) {
return find(coins.length - 1, amount);
};

/**
* @param {number[]} coins
* @param {number} amount
* @return {number}
*
* DP
*/
const coinChange_2 = (coins, amount) => {
const tmp = [0];
const tmp = [0]
coins.sort((c1, c2) => c1 - c2)

for (let i = 1; i <= amount; i += 1) {
if (!tmp[i]) tmp[i] = amount + 1;
tmp[i] = amount + 1

for (let j = 0; j < coins.length; j += 1) {
const coin = coins[j];
if (coin <= i) {
tmp[i] = Math.min(tmp[i], tmp[i - coin] + 1);
}
const coin = coins[j]
if (coin > i) break
tmp[i] = Math.min(tmp[i], tmp[i - coin] + 1)
}
}
return tmp[amount] > amount ? -1 : tmp[amount];
};
return tmp[amount] > amount ? -1 : tmp[amount]
}


// Test case
Expand Down
54 changes: 54 additions & 0 deletions leetcode/JavaScript/No375.guess-number-higher-or-lower-II.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/**
* Difficulty:
* Medium
*
* Desc:
* We are playing the Guess Game. The game is as follows:
* I pick a number from 1 to n. You have to guess which number I picked.
* Every time you guess wrong, I'll tell you whether the number I picked is higher or lower.
* However, when you guess a particular number x, and you guess wrong, you pay $x. You win the game when you guess the number I picked.
*
* Example:
* n = 10, I pick 8.
* First round: You guess 5, I tell you that it's higher. You pay $5.
* Second round: You guess 7, I tell you that it's higher. You pay $7.
* Third round: You guess 9, I tell you that it's lower. You pay $9.
* Game over. 8 is the number I picked.
* You end up paying $5 + $7 + $9 = $21.
*
* Given a particular n ≥ 1, find out how much money you need to have to guarantee a win.
*
* 玩一个猜数游戏,游戏规则如下:
* 从 1 到 n 之间选择一个数字,猜测选了哪个数字。
* 每次猜错,都会得知,猜的数字是大还是小
* 然而,当猜了数字 x 并且猜错了的时候,我们需要支付金额为 x 的现金。直到猜到选的数字,才算赢得了这个游戏。
*/

/**
* @param {number} n
* @return {number}
*/
var getMoneyAmount = function(n) {
const dp = []

for (let i = n; i >= 1; i -= 1) {
if (!dp[i]) dp[i] = []

for (let j = i; j <= n; j += 1) {
if (i === j) {
dp[i][j] = 0
} else {
dp[i][j] = Infinity
for (let x = i; x <= j; x += 1) {
const left = dp[i][x - 1] === undefined ? -Infinity : dp[i][x - 1]
const right = dp[x + 1] && dp[x + 1][j] !== undefined ? dp[x + 1][j] : -Infinity
dp[i][j] = Math.min(
dp[i][j], Math.max(left, right) + x
)
}
}
}
}

return dp[1][n]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/**
* Difficulty:
* Medium
*
* Desc:
* You are given a doubly linked list which in addition to the next and previous pointers,
* it could have a child pointer, which may or may not point to a separate doubly linked list.
* These child lists may have one or more children of their own, and so on, to produce a multilevel data structure, as shown in the example below.
*
* Flatten the list so that all the nodes appear in a single-level, doubly linked list. You are given the head of the first level of the list.
*
* Example 1:
* Input: head = [1,2,3,4,5,6,null,null,null,7,8,9,10,null,null,11,12]
* Output: [1,2,3,7,8,11,12,9,10,4,5,6]
*
* Example 2:
* Input: head = [1,2,null,3]
* Output: [1,3,2]
* Explanation:
* The input multilevel linked list is as follows:
* 1---2---NULL
* |
* 3---NULL
*
* Example3:
* Input: head = []
* Output: []
*
* 获得一个双向链表,除了下一个和前一个指针之外,它还有一个子指针,可能指向单独的双向链表。这些子列表可能有一个或多个自己的子项,依此类推,生成多级数据结构,如下面的示例所示。
* 扁平化列表,使所有结点出现在单级双链表中。返回列表第一级的头部。
*/

/**
* // Definition for a Node.
* function Node(val,prev,next,child) {
* this.val = val;
* this.prev = prev;
* this.next = next;
* this.child = child;
* };
*/
/**
* @param {Node} head
* @return {Node}
*/
var flatten = function(head) {
if (!head) return null

const queue = [head]
const result = new Node(null)
let current = result

while (queue.length) {
const node = queue.pop()

current.next = new Node(node.val)
current.next.prev = current.val === null ? null : current
current = current.next

if (node.next) queue.push(node.next)
if (node.child) queue.push(node.child)
}

return result.next
}
32 changes: 31 additions & 1 deletion leetcode/JavaScript/No451.sort-characters-by-frequency.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,34 @@ var frequencySort = function(s) {
results.push(str.repeat(tmp.get(str)));
}
return results.join('');
};
};

/**
* @param {string} s
* @return {string}
*/
var frequencySort_2 = function(s) {
const tmp = {}
const cache = {}

for (let i = 0; i < s.length; i += 1) {
const pre = tmp[s[i]]
const cur = (pre || 0) + 1

if (pre && cache[pre]) {
cache[pre].delete(s[i])
if (!cache[pre].size) delete cache[pre]
}
if (!cache[cur]) cache[cur] = new Set()
cache[cur].add(s[i])

tmp[s[i]] = cur
}

return Object.keys(cache).sort((a, b) => b - a).map((key) => {
return [...cache[key]].reduce((list, str) => {
list.push(Array.from({ length: key }, (_, i) => str).join(''))
return list
}, []).join('')
}).join('')
}
Loading

0 comments on commit f6aa179

Please sign in to comment.