diff --git a/docs/interview/experiences/21leetcodeA.md b/docs/interview/experiences/21leetcodeA.md index ff062eb..c5a9c70 100644 --- a/docs/interview/experiences/21leetcodeA.md +++ b/docs/interview/experiences/21leetcodeA.md @@ -865,6 +865,24 @@ function inorder(node) { ## 36.二分查找 +```js +function binarySearch(arr, target) { + let left = 0; + let right = arr.length - 1; + while (left <= right) { + let base = left + Math.floor(right - left / 2); + if (arr[base] == target) { + return base; + } else if (target > arr[base]) { + left = mid + 1; + } else { + right = mid - 1; + } + } + return -1; +} +``` + ## [37.用栈实现队列](https://leetcode.cn/problems/implement-queue-using-stacks/description/) ```js diff --git a/docs/interview/experiences/4beforeHandwriting.md b/docs/interview/experiences/4beforeHandwriting.md index a74fe17..7a3348a 100644 --- a/docs/interview/experiences/4beforeHandwriting.md +++ b/docs/interview/experiences/4beforeHandwriting.md @@ -1596,17 +1596,18 @@ camel('cppNName'); 输入: nums = [-1,0,3,5,9,12], target = 9 输出: 4 解释: 9 出现在 nums 中并且下标为 4 -```ts -function search(nums: number[], target: number): number { - let max = nums.length - 1; - let min = 0; - while (max >= min) { - if (nums[max] === target) { - return max; - } else if (target < nums[max]) { - max--; - } else if (target > nums[min]) { - min++; +```js +function search(nums, target) { + let end = nums.length - 1; + let start = 0; + while (start <= end) { + let base = start + end >= 1; + if (arr[base] == target) { + return base; + } else if (arr[base] > target) { + end = mid - 1; + } else { + start = mid + 1; } } return -1; diff --git a/docs/interview/experiences/practise/202403/0305.js b/docs/interview/experiences/practise/202403/0305.js index 7aa864b..f4c62fb 100644 --- a/docs/interview/experiences/practise/202403/0305.js +++ b/docs/interview/experiences/practise/202403/0305.js @@ -12,12 +12,33 @@ * 11.二叉树中的最大路径和 */ +/** + * +输入:amount = 5, coins = [1, 2, 5] +输出:4 +解释:有四种方式可以凑成总金额: +5=5 +5=2+2+1 +5=2+1+1+1 +5=1+1+1+1+1 + */ +var change = function (amount, coins) { + let dp = new Array(amount + 1).fill(0); + dp[0] = 1; + for (let coin of coins) { + for (let j = coin; j <= amount; j++) { + dp[j] += dp[j - coin]; + } + } + return dp[amount]; +}; + // 1/2 5总共有几种可能 function clim(n) { let dp = new Array(n + 1).fill(0); dp[1] = 1; dp[2] = 2; - for (let i = 2; i <= n; i++) { + for (let i = 3; i <= n; i++) { dp[i] = dp[i - 1] + dp[i - 2]; } return dp[n]; @@ -33,9 +54,10 @@ function clim(n) { */ var coinChange = function (coins, amount) { let dp = new Array(amount + 1).fill(Infinity); - for (let i = 1; i <= amount; i++) { - for (let item of coins) { - dp[i] += dp[i - (amount - item)]; + dp[0] = 0; + for (let coin of coins) { + for (let j = coin; j <= amount; j++) { + dp[j] = Math.min(dp[j], dp[j - coin] + 1); } } return dp[amount] == Infinity ? '-1' : dp[amount]; diff --git a/docs/interview/experiences/practise/202403/0306.js b/docs/interview/experiences/practise/202403/0306.js index ab2a367..93f71a4 100644 --- a/docs/interview/experiences/practise/202403/0306.js +++ b/docs/interview/experiences/practise/202403/0306.js @@ -5,7 +5,7 @@ * 4.Promise.finally * 5.reduce * 6.二叉树中的最大路径和 - * 7.对称二叉树 + * 7.对称二叉树/翻转二叉树 * 8.最大深度和最小深度 * 9.重排链表 * 10.最小路径和 @@ -13,7 +13,44 @@ * 12.数组转树 */ -function tryAgain(fn, time) {} +/** + * @param {TreeNode} root + * @return {TreeNode} + */ +var invertTree = function (root) { + if (!root) return null; + let temp = invertTree(root.left); + root.left = invertTree(root.right); + root.right = temp; + return root; +}; + +/** + * @param {TreeNode} root + * @return {boolean} + * 外侧 + * 里侧 + */ +var isSymmetric = function (root) { + if (root == null) return true; + const compare = (left, right) => { + // 确定终止条件 + if ((left == null && right != null) || (right == null && left != null)) { + return false; + } + if (left == null && right == null) { + return true; + } + if (left.val !== right.val) { + return false; + } + // 确定单层逻辑 + const outSide = compare(left.left, right.right); + const inner = compare(left.right, right.left); + return outSide && inner; + }; + return compare(root.left, root.right); +}; class Promise { static finally(cb) { diff --git a/docs/interview/experiences/practise/202403/0307.js b/docs/interview/experiences/practise/202403/0307.js index d2a4055..12c4207 100644 --- a/docs/interview/experiences/practise/202403/0307.js +++ b/docs/interview/experiences/practise/202403/0307.js @@ -1,8 +1,107 @@ /** - * 1.分饼干 + * 1.分饼干/分糖果 * 2.删除有序数组的重复项 * 3.二叉树直径 * 4.背包问题 * 5.括号生成 - * 6. + * 6.判断子序列 + * 7.不同的子序列 + * 8.编辑距离 + * 9.平衡二叉树 + * 10.二叉树的最近公共祖先 + * 11.二叉树的最大深度和最小深度 + * 12.重排链表 */ + +/** + * @param {number} n + * @return {string[]} + * 输入:n = 3 +输出:["((()))","(()())","(())()","()(())","()()()"] + */ +var generateParenthesis = function (n) { + let ans = []; + let dfs = (n, left, right) => { + if (left.length > right.length || right.length > n) return; + dfs(n); + }; + dfs(n, '(', ')'); + return ans; +}; + +/** + * +输入: g = [1,2,3], s = [1,1] +输出: 1 +你有三个孩子和两块小饼干,3个孩子的胃口值分别是:1,2,3。 +虽然你有两块小饼干,由于他们的尺寸都是1,你只能让胃口值是1的孩子满足。 +所以你应该输出1。 +输入: g = [1,2], s = [1,2,3] +输出: 2 +你有两个孩子和三块小饼干,2个孩子的胃口值分别是1,2。 +你拥有的饼干数量和尺寸都足以让所有孩子满足。 +所以你应该输出2. + */ +var findContentChildren = function (g, s) { + g.sort((a, b) => a - b); + s.sort((a, b) => a - b); + let count = 0; + let len = g.length - 1; + for (let i = len; i >= 0; i--) { + const last = s.slice(-1); + if (last >= g[i]) { + count++; + s.pop(); + } + } + return s; +}; +var findContentChildren = function (g, s) { + let count = 0; + let len = g.length - 1; + let sLen = s.length - 1; + for (let i = len; i >= 0; i--) { + if (s[sLen] >= g[i]) { + count++; + sLen--; + } + } + return s; +}; + +// weight 1/3/4 +// value 15/20/30 +function weightBag(values, weights, size) { + let len = weights.length; + // 包 横向 + // 物品纵向 + let dp = new Array(len).fill().map(() => new Array(size + 1).fill(0)); + // 初始化dp + for (let i = weight[0]; i <= size; i++) { + dp[0][i] = values[0]; + } + // 先遍历物品在遍历背包 + for (let i = 1; i < len; i++) { + for (let j = 0; j <= size; j++) { + // 背包塞不下物品 + if (j < weights[i]) { + dp[i][j] = dp[i - 1][j]; + } else { + // 背包塞得下物品 + dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - weight[i]] + values[i]); + } + } + } + return dp[len - 1][size]; +} + +import { useEffect, useCallback } from 'react'; +export function useEvent(handler) { + let handlerRef = useRef(); + useEffect(() => { + handlerRef.current = handler; + }); + return useCallback((...arg) => { + handlerRef.current(...arg); + }, []); +} diff --git a/docs/interview/experiences/practise/202403/0308.js b/docs/interview/experiences/practise/202403/0308.js index 68bdf29..ccc8bf0 100644 --- a/docs/interview/experiences/practise/202403/0308.js +++ b/docs/interview/experiences/practise/202403/0308.js @@ -1,3 +1,10 @@ /** * 1.每天都在写,到底记住了多少?离03月20日还剩两周,今天要做的就是反思回想 + * 2.不同路径 + * 3.从中序和后序遍历构造二叉树 + * 4.青蛙跳台阶问题 + * 5.二叉树的层次遍历 + * 6.寻找重复数 + * 7.复原IP地址 + * 8.检测循环依赖 */ diff --git a/src/Hooks/useToggle/index.md b/src/Hooks/useToggle/index.md new file mode 100644 index 0000000..6643c74 --- /dev/null +++ b/src/Hooks/useToggle/index.md @@ -0,0 +1,45 @@ +--- +title: useEvent +order: 6 +group: + title: Hooks + order: 1, +nav: + order: 3 + title: 'react' + path: /react +--- + +## Demo + +我最喜欢的自定义 hook 之一是 useToggle,这是一个友好的助手,其工作方式几乎与 useState 完全相同,但只能在 true 和 false 之间切换状态变量: + + + +## Code + +```ts +import React from 'react'; +import useToggle from './useToggle'; + +const MyApp = () => { + const [isDarkMode, toggleDarkMode] = useToggle(false); + return ; +}; +export default MyApp; +``` + +## Source code + +```ts +import { useCallback, useState } from 'react'; + +const useToggle = (initialValue: boolean) => { + const [value, setValue] = useState(initialValue); + const toggle = useCallback(() => { + setValue((v) => !v); + }, []); + return [value, toggle]; +}; +export default useToggle; +``` diff --git a/src/Hooks/useToggle/index.tsx b/src/Hooks/useToggle/index.tsx new file mode 100644 index 0000000..120a733 --- /dev/null +++ b/src/Hooks/useToggle/index.tsx @@ -0,0 +1,8 @@ +import React from 'react'; +import useToggle from './useToggle'; + +const MyApp = () => { + const [isDarkMode, toggleDarkMode] = useToggle(false); + return ; +}; +export default MyApp; diff --git a/src/Hooks/useToggle/useToggle.tsx b/src/Hooks/useToggle/useToggle.tsx new file mode 100644 index 0000000..2616104 --- /dev/null +++ b/src/Hooks/useToggle/useToggle.tsx @@ -0,0 +1,10 @@ +import { useCallback, useState } from 'react'; + +const useToggle = (initialValue: boolean) => { + const [value, setValue] = useState(initialValue); + const toggle = useCallback(() => { + setValue((v) => !v); + }, []); + return [value, toggle]; +}; +export default useToggle;