Skip to content

Commit

Permalink
feat(algorithm): add greedy
Browse files Browse the repository at this point in the history
  • Loading branch information
len.liu committed Aug 31, 2021
1 parent 0feb806 commit 5ead964
Show file tree
Hide file tree
Showing 8 changed files with 238 additions and 3 deletions.
1 change: 1 addition & 0 deletions interview/algorithm/README.md
Expand Up @@ -27,3 +27,4 @@
贪心得到结果是一个可以接受的解,不一定总是得到最优的解
[硬币找零](./greedy/coin.js)
[饼干与小孩](./greedy/cookie.js)
[买卖股票的最佳时机](./greedy/shares.js)
3 changes: 2 additions & 1 deletion interview/algorithm/greedy/shares.js
Expand Up @@ -18,7 +18,8 @@ var maxProfit = function(prices, fee) {
min = prices[i]
} else if ((t = prices[i] - min - fee) > 0) {
r += t
min = prices[i] - fee
// TODO
min = prices[i] - fee
}
i++
}
Expand Down
69 changes: 69 additions & 0 deletions interview/algorithm/structer/tree/treeSum.js
@@ -0,0 +1,69 @@
// 对于给定的二叉树,判断是否存在一条完整路径(从根节点开始,到叶节点结束的连线),其路径上节点的值之和为target,输出布尔值。
// **举例:下面的树,是否存在一条完整路径,该路径上各个节点之和target=7?

(() => {
//用多维数组代表题中示例的树,这个数组是按“前序遍历”后排序
let arrSouce = [6, [2, [-1], [3]], [3, [0]]];

/**
* 定义二叉树的结点。根结点和树的数据结构一样,
* 因此只需要定义一个结点(Node)的数据结构即可
*/
class Node {
/**
* 构造函数
* @param {Number} value 当前结点的值
* @param {Node} left 左子结点
* @param {Node} right 右子结点
*/
constructor(value, left, right) {
if (value != undefined) {
this.value = value;
if (left != undefined) this.left = left;
if (right != undefined) this.right = right;
}
}
}

/**
* 创建一个树
* @param {Array} arr 一个代表二叉树的多维数组
*/
function makeBTree(arr) {
if (arr) {
if (arr.length == 1) {
return new Node(arr[0]);
}
//递归,创建二叉树
return new Node(arr[0], makeBTree(arr[1]), makeBTree(arr[2]));
}
}

//创建示例中的二叉树,简洁多了!
let bTree = makeBTree(arrSouce);

/**
* 主逻辑函数,与第一种解法里代码一样
* @param {Node} node 树的结点
* @param {Number} target 题目要求的目标值
*/
function hasPathSum(node, target) {
//若根节点无子结点
if (!node.left && !node.right) {
//直接判断根结点额值是否等于target
return node.value == target;
}
//若有子结点
else {
//如有左结点 左侧递归
if (!!node.left)
return hasPathSum(node.left, /*关键*/ target - node.value);
//如有右结点 右侧递归
if (!!node.right)
return hasPathSum(node.right, /*关键*/ target - node.value);
}
}

console.log(hasPathSum(bTree, 7)); //>> true
})();

4 changes: 4 additions & 0 deletions interview/css/width.md
@@ -0,0 +1,4 @@
1. 某 div 不设置宽度,那么 width 默认为 auto.
2. 某子元素 div 的 width 为 100%(或者设置为等于父元素宽度的具体值,比如父元素 width 为 100px,
子元素 width 也设置为 100px),则此子元素的宽度 = 父元素 width 值(不包括父元素边框,内边距)+子元素的边框、内边距宽度
3. 某个 div 的 width 不设置,或者设置为 auto, 子元素的宽度会包含在父元素内,子元素边框、内边距都在不会叠加到子元素的长度上
140 changes: 140 additions & 0 deletions interview/function/promise1.js
@@ -0,0 +1,140 @@
const PENDING = 'PENDING';
const FULFILLED = 'FULFILLED';
const REJECTED = 'REJECTED';

const resolvePromise = (promise2, x, resolve, reject) => {
// 自己等待自己完成是错误的实现,用一个类型错误,结束掉 promise Promise/A+ 2.3.1
if (promise2 === x) {
return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
}
// Promise/A+ 2.3.3.3.3 只能调用一次
let called;
// 后续的条件要严格判断 保证代码能和别的库一起使用
if ((typeof x === 'object' && x != null) || typeof x === 'function') {
try {
// 为了判断 resolve 过的就不用再 reject 了(比如 reject 和 resolve 同时调用的时候) Promise/A+ 2.3.3.1
let then = x.then;
if (typeof then === 'function') {
// 不要写成 x.then,直接 then.call 就可以了 因为 x.then 会再次取值,Object.defineProperty Promise/A+ 2.3.3.3
then.call(x, y => { // 根据 promise 的状态决定是成功还是失败
if (called) return;
called = true;
// 递归解析的过程(因为可能 promise 中还有 promise) Promise/A+ 2.3.3.3.1
resolvePromise(promise2, y, resolve, reject);
}, r => {
// 只要失败就失败 Promise/A+ 2.3.3.3.2
if (called) return;
called = true;
reject(r);
});
} else {
// 如果 x.then 是个普通值就直接返回 resolve 作为结果 Promise/A+ 2.3.3.4
resolve(x);
}
} catch (e) {
// Promise/A+ 2.3.3.2
if (called) return;
called = true;
reject(e)
}
} else {
// 如果 x 是个普通值就直接返回 resolve 作为结果 Promise/A+ 2.3.4
resolve(x)
}
}

class Promise {
constructor(executor) {
this.status = PENDING;
this.value = undefined;
this.reason = undefined;
this.onResolvedCallbacks = [];
this.onRejectedCallbacks= [];

let resolve = (value) => {
if(this.status === PENDING) {
this.status = FULFILLED;
this.value = value;
this.onResolvedCallbacks.forEach(fn=>fn());
}
}

let reject = (reason) => {
if(this.status === PENDING) {
this.status = REJECTED;
this.reason = reason;
this.onRejectedCallbacks.forEach(fn=>fn());
}
}

try {
executor(resolve,reject)
} catch (error) {
reject(error)
}
}

then(onFulfilled, onRejected) {
//解决 onFufilled,onRejected 没有传值的问题
//Promise/A+ 2.2.1 / Promise/A+ 2.2.5 / Promise/A+ 2.2.7.3 / Promise/A+ 2.2.7.4
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : v => v;
//因为错误的值要让后面访问到,所以这里也要跑出个错误,不然会在之后 then 的 resolve 中捕获
onRejected = typeof onRejected === 'function' ? onRejected : err => { throw err };
// 每次调用 then 都返回一个新的 promise Promise/A+ 2.2.7
let promise2 = new Promise((resolve, reject) => {
if (this.status === FULFILLED) {
//Promise/A+ 2.2.2
//Promise/A+ 2.2.4 --- setTimeout
setTimeout(() => {
try {
//Promise/A+ 2.2.7.1
let x = onFulfilled(this.value);
// x可能是一个proimise
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
//Promise/A+ 2.2.7.2
reject(e)
}
}, 0);
}

if (this.status === REJECTED) {
//Promise/A+ 2.2.3
setTimeout(() => {
try {
let x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e)
}
}, 0);
}

if (this.status === PENDING) {
this.onResolvedCallbacks.push(() => {
setTimeout(() => {
try {
let x = onFulfilled(this.value);
resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e)
}
}, 0);
});

this.onRejectedCallbacks.push(()=> {
setTimeout(() => {
try {
let x = onRejected(this.reason);
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e)
}
}, 0);
});
}
});

return promise2;
}
}
18 changes: 18 additions & 0 deletions interview/functional/partial.md
Expand Up @@ -102,3 +102,21 @@ function bindFirstArg(fn, a) {
};
}
```
#### 偏函数是固定一个函数的一个或多个参数,然后返回一个新函数
```js
//入参函数
function add(a,b){
return a + b;
}
//生产偏函数的工厂
function partial(fn,a){
return function(b){
return fn(a,b);
}
}
var parAdd = partial(add,1);//变量parAdd接受返回的新函数
console.log(parAdd(2));//在调用的时候传入剩余的参数
console.log(parAdd(3));//在调用的时候传入剩余的参数
console.log(parAdd(4));//在调用的时候传入剩余的参数
console.log(parAdd(5));//在调用的时候传入剩余的参数
```
2 changes: 1 addition & 1 deletion remember/interview.md
Expand Up @@ -2,7 +2,7 @@

https://juejin.cn/post/6844903577220349959

[hard](https://github.com/coffe1891/frontend-hard-mode-interview)
[hard-前端内参](https://github.com/coffe1891/frontend-hard-mode-interview)
[33](https://github.com/stephentian/33-js-concepts)
[real](https://i-want-offer.github.io/FE-Essay/)
[collection](https://github.com/LiangJunrong/document-library)
4 changes: 3 additions & 1 deletion tools/github-collection/frame-work.md
Expand Up @@ -61,4 +61,6 @@ Isometric Sass

#### framework
[solid](https://github.com/solid/solid)
[google/Lit/web component]()
[google/Lit/web component]()

[markmap](https://github.com/dundalek/markmap)

0 comments on commit 5ead964

Please sign in to comment.