├── README.md ├── src ├── style │ └── common │ │ ├── less │ │ ├── base.less │ │ ├── README.md │ │ ├── _utils.less │ │ └── _mixin.less │ │ └── scss │ │ ├── base.scss │ │ ├── _utils.scss │ │ └── _mixin.scss ├── leetcode │ ├── _96.ts │ ├── _104.ts │ ├── _509.ts │ ├── _206.ts │ ├── _7.ts │ ├── _344.ts │ ├── _118.ts │ ├── _119.ts │ ├── _21.ts │ ├── _141.ts │ ├── _203.ts │ ├── _144.ts │ ├── _offer_24.ts │ ├── _9.ts │ ├── _70.ts │ ├── _19.ts │ ├── _1.ts │ ├── _95.ts │ ├── _779.ts │ ├── weidigui.ts │ ├── _328.ts │ ├── _430.ts │ ├── _50.ts │ ├── _3.ts │ ├── _1189.ts │ ├── _142.ts │ ├── _2.ts │ ├── _61.ts │ ├── linkedList.ts │ ├── _234.ts │ ├── _160.ts │ ├── study.ts │ ├── _707.ts │ └── index.js ├── assets │ └── favicon │ │ └── favicon.ico ├── test.ts ├── style.less ├── global.d.ts ├── index.ts └── exp.ts ├── .gitignore ├── .gitattributes ├── index.html ├── tsconfig.json ├── webpack.dev.js ├── .babelrc ├── webpack.prod.js ├── webpack.config.js ├── package.json └── webpack.common.js /README.md: -------------------------------------------------------------------------------- 1 | # leet_code 2 | 学习 3 | -------------------------------------------------------------------------------- /src/style/common/less/base.less: -------------------------------------------------------------------------------- 1 | @import "./_utils.less"; -------------------------------------------------------------------------------- /src/style/common/less/README.md: -------------------------------------------------------------------------------- 1 | 这里是less的通用样式,mixin,和一些方法,同scss 2 | -------------------------------------------------------------------------------- /src/leetcode/_96.ts: -------------------------------------------------------------------------------- 1 | export default function numTrees(n: number) { 2 | }; 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules/ 3 | dist/ 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* -------------------------------------------------------------------------------- /src/assets/favicon/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/IFmiss/leet_code/master/src/assets/favicon/favicon.ico -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.js linguist-language=javascript 2 | *.css linguist-language=javascript 3 | *.html linguist-language=javascript -------------------------------------------------------------------------------- /src/style/common/scss/base.scss: -------------------------------------------------------------------------------- 1 | @import "node_modules/compass-mixins/lib/compass/css3"; 2 | @import './_utils'; 3 | @import './_mixin'; -------------------------------------------------------------------------------- /src/leetcode/_104.ts: -------------------------------------------------------------------------------- 1 | function maxDepth(root: TreeNode | null): number { 2 | return root 3 | ? Math.max(maxDepth(root.left), maxDepth(root.right)) + 1 4 | : 0 5 | }; 6 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | webpack 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "outDir": "./dist/", 4 | "strict": true, 5 | "sourceMap": true, 6 | "noImplicitAny": true, 7 | "module": "commonjs", 8 | "target": "es6", 9 | "jsx": "react", 10 | "allowJs": true, 11 | "experimentalDecorators": true 12 | } 13 | } -------------------------------------------------------------------------------- /src/leetcode/_509.ts: -------------------------------------------------------------------------------- 1 | let cache = new Map(); 2 | function fib(N: number): number { 3 | if (N == 0) return 0 4 | if (N == 1) return 1 5 | if (cache.has(N)) { 6 | return cache.get(N) 7 | } 8 | let ret = fib(N - 1) + fib(N - 2) 9 | cache.set(N, ret); 10 | return ret; 11 | } 12 | 13 | export default fib 14 | -------------------------------------------------------------------------------- /src/leetcode/_206.ts: -------------------------------------------------------------------------------- 1 | export default function reverseList(head: ListNode | null): ListNode | null { 2 | if (head === null || head.next === null) { 3 | return head; 4 | } 5 | 6 | const next = head.next; 7 | const reverseHead = reverseList(head.next); 8 | next.next = head; 9 | head.next = null; 10 | return reverseHead; 11 | }; -------------------------------------------------------------------------------- /src/leetcode/_7.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @description 给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。 3 | * 示例 1: 4 | * 输入: 123 5 | * 输出: 321 6 | * @param {*} x 7 | */ 8 | export default function _7 (x: number) { 9 | let resut = 0 10 | do { 11 | if (resut > 214748364 || resut < -214748364) return 0 12 | resut = resut * 10 + x % 10 13 | x = ~~(x / 10) 14 | } while (x) 15 | return resut 16 | } 17 | -------------------------------------------------------------------------------- /src/leetcode/_344.ts: -------------------------------------------------------------------------------- 1 | // ["h","e","l","l","o"] 2 | export default function reverseString(s: string[]): void { 3 | let len = s.length; 4 | const fn = (start: number, end: number, s: string[]) => { 5 | if (start > end) { 6 | return; 7 | } 8 | let tmp = s[start]; 9 | s[start] = s[end]; 10 | s[end] = tmp; 11 | fn(start + 1, end - 1, s); 12 | } 13 | 14 | fn(0, len - 1, s); 15 | }; -------------------------------------------------------------------------------- /src/leetcode/_118.ts: -------------------------------------------------------------------------------- 1 | function generate(numRows: number): number[][] { 2 | let wrap: number[][] = []; 3 | for (let i = 0; i < numRows; i++) { 4 | wrap[i] = [] 5 | for (let j = 0; j <= i; j ++) { 6 | if (j == 0 || j == i) { 7 | wrap[i].push(1) 8 | } else { 9 | const w = wrap[i - 1] 10 | wrap[i].push(w[j - 1] + w[j]) 11 | } 12 | } 13 | } 14 | return wrap 15 | }; 16 | 17 | export default generate 18 | -------------------------------------------------------------------------------- /src/leetcode/_119.ts: -------------------------------------------------------------------------------- 1 | function getRow(rowIndex: number): number[] { 2 | if (rowIndex == 0) return [1] 3 | if (rowIndex == 1) return [1, 1] 4 | 5 | const preArr = getRow(rowIndex - 1); 6 | 7 | const temp = [] 8 | for (let i = 0; i <= rowIndex; i++) { 9 | if (i < 1) { 10 | temp[i] = preArr[i] 11 | } else { 12 | temp[i] = preArr[i - 1] + (preArr[i] || 0) 13 | } 14 | } 15 | return temp 16 | }; 17 | 18 | export default getRow 19 | -------------------------------------------------------------------------------- /src/leetcode/_21.ts: -------------------------------------------------------------------------------- 1 | function mergeTwoLists(l1: ListNode | null, l2: ListNode | null): ListNode | null { 2 | // 如果 l1 到头了,直接拼l2的值 3 | if (l1 === null) { 4 | return l2; 5 | } 6 | 7 | // 如果 l2 到头了,拼接l1的值 8 | if (l2 === null) { 9 | return l1; 10 | } 11 | 12 | if (l1.val > l2.val) { 13 | l2.next = mergeTwoLists(l1, l2.next); 14 | return l2; 15 | } else { 16 | l1.next = mergeTwoLists(l1.next, l2); 17 | return l1; 18 | } 19 | }; -------------------------------------------------------------------------------- /webpack.dev.js: -------------------------------------------------------------------------------- 1 | const merge = require('webpack-merge'); 2 | const common = require('./webpack.common.js'); 3 | module.exports = merge(common, { 4 | devtool: 'inline-source-map', 5 | devServer: { 6 | // 当使用 HTML5 History API 时,任意的 404 响应都可能需要被替代为 index.html。通过传入以下启用: 7 | contentBase: "./", 8 | host: '0.0.0.0', 9 | // 端口号 10 | port: 2003, 11 | //当有编译器错误或警告时,在浏览器中显示全屏覆盖。默认禁用。如果您只想显示编译器错误: 12 | noInfo: true, 13 | // 配置端口号 14 | overlay: true, 15 | } 16 | }); -------------------------------------------------------------------------------- /src/leetcode/_141.ts: -------------------------------------------------------------------------------- 1 | // 141. 环形链表 2 | function hasCycle(head: ListNode | null): boolean { 3 | if (head === null || head.next === null) { 4 | return false 5 | }; 6 | 7 | let slow: ListNode | null = head; 8 | let fast: ListNode | null = head.next; 9 | 10 | while(slow !== fast) { 11 | // 无环 12 | if (fast === null || fast.next === null) return false; 13 | 14 | slow = (slow as ListNode).next; 15 | fast = fast.next.next; 16 | } 17 | 18 | return true; 19 | }; -------------------------------------------------------------------------------- /src/leetcode/_203.ts: -------------------------------------------------------------------------------- 1 | // 删除链表中等于给定值 val 的所有节点。 2 | 3 | // 示例: 4 | 5 | // 输入: 1->2->6->3->4->5->6, val = 6 6 | // 输出: 1->2->3->4->5 7 | 8 | function removeElements(head: ListNode | null, val: number): ListNode | null { 9 | let node = new ListNode(); 10 | node.next = head; 11 | let prev = node; 12 | while(prev.next) { 13 | if (prev.next.val === val) { 14 | prev.next = prev.next.next; 15 | } else { 16 | prev = prev.next; 17 | } 18 | } 19 | return node.next; 20 | }; 21 | -------------------------------------------------------------------------------- /src/leetcode/_144.ts: -------------------------------------------------------------------------------- 1 | // 二叉树前序 2 | // 给你二叉树的根节点 root ,返回它节点值的 前序 遍历。 3 | 4 | // 输入:root = [1,null,2,3] 5 | // 输出:[1,2,3] 6 | 7 | function preorderTraversal(root: TreeNode | null): number[] { 8 | let data: number[] = []; 9 | if (!root) { 10 | return data; 11 | } 12 | 13 | const qianxu = (root: TreeNode | null): void => { 14 | if (!root) { 15 | return; 16 | } 17 | data.push(root.val); 18 | qianxu(root.left); 19 | qianxu(root.right); 20 | } 21 | 22 | qianxu(root); 23 | return data; 24 | }; 25 | -------------------------------------------------------------------------------- /src/leetcode/_offer_24.ts: -------------------------------------------------------------------------------- 1 | // class ListNode { 2 | // val: number 3 | // next: ListNode | null 4 | // constructor(val?: number, next?: ListNode | null) { 5 | // this.val = (val===undefined ? 0 : val) 6 | // this.next = (next===undefined ? null : next) 7 | // } 8 | // } 9 | 10 | function reverseList(head: ListNode | null): ListNode | null { 11 | let prev = null 12 | while (head) { 13 | const next = head.next 14 | head.next = prev 15 | prev = head 16 | head = next 17 | } 18 | return prev 19 | } 20 | -------------------------------------------------------------------------------- /src/test.ts: -------------------------------------------------------------------------------- 1 | class Shape { 2 | area: number; 3 | color: string; 4 | constructor ( name: string, width: number, height: number ) { 5 | this.area = width * height; 6 | this.color = "pink"; 7 | }; 8 | 9 | shoutout() { 10 | return "I'm " + this.color + " with an area of " + this.area + " cm squared."; 11 | } 12 | } 13 | 14 | var square = new Shape("square", 30, 30); 15 | console.log( square.shoutout() ); 16 | console.log( 'Area of Shape: ' + square.area ); 17 | console.log( 'Color of Shape: ' + square.color ); 18 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["@babel/preset-env", { 4 | "modules": "commonjs", 5 | "loose": false 6 | }] 7 | ], 8 | "plugins":[ 9 | ["@babel/plugin-proposal-decorators", { "legacy": true }], 10 | ["@babel/plugin-proposal-class-properties", { "loose" : true }], 11 | [ 12 | "@babel/plugin-transform-runtime", 13 | { 14 | "absoluteRuntime": false, 15 | "corejs": false, 16 | "helpers": true, 17 | "regenerator": true, 18 | "useESModules": false 19 | } 20 | ] 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /src/leetcode/_9.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @description 判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。 3 | * 示例 1: 4 | * 输入: 121 5 | * 输出: true 6 | * 示例 2: 7 | * 输入: -121 8 | * 输出: false 9 | * 解释: 从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。 10 | * 示例 3: 11 | * 输入: 10 12 | * 输出: false 13 | * 解释: 从右向左读, 为 01 。因此它不是一个回文数。 14 | * @param {*} x 整数 15 | * @link https://leetcode-cn.com/problems/palindrome-number/ 16 | */ 17 | export default function _9 (x: number) { 18 | if (x < 0) return false 19 | let resut = 0; 20 | let t = x; 21 | do { 22 | resut = resut * 10 + x % 10; 23 | x = Math.floor(x / 10) 24 | } while (x) 25 | return resut === t 26 | } 27 | -------------------------------------------------------------------------------- /src/leetcode/_70.ts: -------------------------------------------------------------------------------- 1 | // 会超时 2 | export function climbStairs(n: number): number { 3 | // if (n === 1 || n === 2) return n; 4 | // return climbStairs(n - 1) + climbStairs(n - 2); 5 | 6 | const f = (n: number, ret: number, ret2: number): number => { 7 | if (n == 0) { 8 | return ret; 9 | } 10 | return f(n - 1, ret2, ret + ret2); 11 | } 12 | 13 | return f(n, 1, 1); 14 | }; 15 | 16 | // export function climbStairs(n: number): number { 17 | // let climbArray = []; 18 | // climbArray[1] = 1; 19 | // climbArray[2] = 2; 20 | // for (let k = 3; k <= n; k++) { 21 | // climbArray[k] = climbArray[k - 1] + climbArray[k - 2]; 22 | // } 23 | // return climbArray[n]; 24 | // } 25 | -------------------------------------------------------------------------------- /src/leetcode/_19.ts: -------------------------------------------------------------------------------- 1 | // 给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。 2 | 3 | // 进阶:你能尝试使用一趟扫描实现吗? 4 | 5 | // https://leetcode-cn.com/leetbook/read/linked-list/jf1cc/ 6 | 7 | function removeNthFromEnd(head: ListNode | null, n: number): ListNode | null { 8 | let fast = head, 9 | slow = head; 10 | 11 | while(--n && fast) { 12 | fast = fast?.next ?? null; 13 | } 14 | 15 | // 不存在直接返回null 16 | if(!fast?.next) return head?.next || null; 17 | 18 | // 否则存在的话 19 | fast = fast.next; 20 | 21 | // 顺位 第n之后 开始向后移动, 22 | while((fast && fast.next)) { 23 | fast = fast?.next || null; 24 | slow = slow?.next || null; 25 | } 26 | (slow as ListNode).next = slow?.next?.next as ListNode; 27 | return head; 28 | }; 29 | -------------------------------------------------------------------------------- /src/leetcode/_1.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @description 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。 3 | * 你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。 4 | * 示例: 5 | * 给定 nums = [2, 7, 11, 15], target = 9 6 | * 因为 nums[0] + nums[1] = 2 + 7 = 9 7 | * 所以返回 [0, 1] 8 | * @param {*} nums 数组 9 | * @param {*} target 目标相加的值 10 | * @link https://leetcode-cn.com/problems/two-sum/ 11 | */ 12 | 13 | export default function _1 (nums: Array, target: number) { 14 | const l = nums.length 15 | const m = new Map() 16 | for (let i = 0; i < l; i ++) { 17 | const r = target - nums[i] 18 | if (m.has(r)) { 19 | return [m.get(r), i] 20 | } else { 21 | m.set(nums[i], i) 22 | } 23 | } 24 | return [] 25 | } 26 | -------------------------------------------------------------------------------- /src/leetcode/_95.ts: -------------------------------------------------------------------------------- 1 | export default function generateTrees(n: number): Array { 2 | if (n === 0) return []; 3 | const getBSTnum = (start: number, n: number) => { 4 | if (start > n) return [null]; 5 | if (start === n) return [new TreeNode(start)]; 6 | 7 | const res = []; 8 | for (let i = start; i <= n; i++) { 9 | let leftBST = getBSTnum(start, i - 1); 10 | let rightBST = getBSTnum(i + 1, n); 11 | 12 | for (let leftV of leftBST) { 13 | for (let rightV of rightBST) { 14 | const root = new TreeNode(i); 15 | root.left = leftV; 16 | root.right = rightV; 17 | res.push(root); 18 | } 19 | } 20 | } 21 | return res; 22 | }; 23 | return getBSTnum(1, n); 24 | }; -------------------------------------------------------------------------------- /src/style.less: -------------------------------------------------------------------------------- 1 | @import "./style/common/less/base.less"; 2 | body,html{ 3 | margin: 0; 4 | padding: 0; 5 | height:100%; 6 | // background: #111010; 7 | } 8 | body{ 9 | // background: red; 10 | display: flex; 11 | width: 100%; 12 | height: 100%; 13 | align-items: center; 14 | justify-content: center; 15 | flex-direction: column; 16 | .title{ 17 | font-size: 42px; 18 | .colortext-l(#4facfe, #00f2fe); 19 | display: inline-block; 20 | margin-top: 0; 21 | } 22 | .disc{ 23 | font-size: 14px; 24 | padding: 6px 0; 25 | color: #f1f1f1; 26 | } 27 | .github-info{ 28 | margin-top: 40px; 29 | text-align: center; 30 | display: flex; 31 | justify-content: center; 32 | span{ 33 | color: #fff; 34 | font: 14px; 35 | font-size:14px; 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /src/leetcode/_779.ts: -------------------------------------------------------------------------------- 1 | // 在第一行我们写上一个 0。接下来的每一行,将前一行中的0替换为01,1替换为10。 2 | 3 | // 给定行数 N 和序数 K,返回第 N 行中第 K个字符。(K从1开始) 4 | 5 | 6 | // 例子: 7 | 8 | // 输入: N = 1, K = 1 9 | // 输出: 0 10 | 11 | // 输入: N = 2, K = 1 12 | // 输出: 0 13 | 14 | // 输入: N = 2, K = 2 15 | // 输出: 1 16 | 17 | // 输入: N = 4, K = 5 18 | // 输出: 1 19 | 20 | // 解释: 21 | // 第一行: 0 22 | // 第二行: 01 23 | // 第三行: 0110 24 | // 第四行: 01101001 25 | 26 | export default function kthGrammar(N: number, K: number): number { 27 | if (N === 1 || K === 1) return 0; 28 | if (K === 2) return 1; 29 | // 如果 K 是奇数,则 N,K 对应的值为父级(N-1,((K + 1)) / 2)的位置的值 30 | if (K % 2) { 31 | return kthGrammar(N-1, (K + 1) / 2); 32 | } else { 33 | // 偶数 34 | // 上一行为0 下一行为1 35 | // 上一行为1 下一行为0 36 | return kthGrammar(N-1, K / 2) === 0 ? 1 : 0; 37 | } 38 | }; 39 | -------------------------------------------------------------------------------- /src/leetcode/weidigui.ts: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | export function fact(n: number): number { 3 | if (n <= 0) { 4 | return 1; 5 | } else { 6 | return n * fact(n - 1); 7 | } 8 | } 9 | 10 | // export function add(n: number): number { 11 | // if (n === 1) return n; 12 | // return n + add(n - 1); 13 | // } 14 | 15 | export function add(n: number, ret: number): number { 16 | if (n === 0) { 17 | return n + ret; 18 | }; 19 | return add(n - 1, n + ret); 20 | } 21 | 22 | export function sum5(n: number, total = 0): number { 23 | if (n === 0 ) return total 24 | if (n % 5 !== 0) return sum5(n - 1, total) 25 | return sum5(n - 5, n + total) 26 | } 27 | 28 | export function sum5Old (n: number) { 29 | console.log(n) 30 | if (n <= 0) return 0 31 | if (n % 5 === 0) return n + sum5(n - 5) 32 | return sum5(n - 1) 33 | } 34 | -------------------------------------------------------------------------------- /src/leetcode/_328.ts: -------------------------------------------------------------------------------- 1 | // 328. 奇偶链表 2 | // 给定一个单链表,把所有的奇数节点和偶数节点分别排在一起。请注意,这里的奇数节点和偶数节点指的是节点编号的奇偶性,而不是节点的值的奇偶性。 3 | 4 | // 请尝试使用原地算法完成。你的算法的空间复杂度应为 O(1),时间复杂度应为 O(nodes),nodes 为节点总数。 5 | 6 | // 示例 1: 7 | 8 | // 输入: 1->2->3->4->5->NULL 9 | // 输出: 1->3->5->2->4->NULL 10 | // 示例 2: 11 | 12 | // 输入: 2->1->3->5->6->4->7->NULL 13 | // 输出: 2->3->6->7->1->5->4->NULL 14 | // 说明: 15 | 16 | // 应当保持奇数节点和偶数节点的相对顺序。 17 | // 链表的第一个节点视为奇数节点,第二个节点视为偶数节点,以此类推。 18 | 19 | function oddEvenList(head: ListNode | null): ListNode | null { 20 | if (head === null) return head; 21 | let old = head; 22 | let oushuHead = head.next; 23 | let oushu = oushuHead; 24 | while(oushu && oushu.next) { 25 | old.next = oushu?.next; 26 | old = old.next; 27 | oushu.next = old.next; 28 | oushu = oushu.next; 29 | } 30 | old.next = oushuHead; 31 | return head; 32 | }; -------------------------------------------------------------------------------- /src/leetcode/_430.ts: -------------------------------------------------------------------------------- 1 | // 多级双向链表中,除了指向下一个节点和前一个节点指针之外,它还有一个子链表指针,可能指向单独的双向链表。这些子列表也可能会有一个或多个自己的子项,依此类推,生成多级数据结构,如下面的示例所示。 2 | 3 | // 给你位于列表第一级的头节点,请你扁平化列表,使所有结点出现在单级双链表中。 4 | 5 | // 链接:https://leetcode-cn.com/problems/flatten-a-multilevel-doubly-linked-list 6 | 7 | function flatten(head: ChildListNode | null): ChildListNode | null { 8 | let current = head; 9 | while(current) { 10 | if (current.child) { 11 | let child = current.child; 12 | let next = current.next; 13 | 14 | current.next = child; 15 | current.child = null; 16 | child.prev = current; 17 | 18 | while (child.next) { 19 | child = child?.next; 20 | } 21 | 22 | child.next = next; 23 | 24 | if (next) { 25 | next.prev = child; 26 | } 27 | } 28 | // 顶层后移 29 | current = current.next; 30 | } 31 | return head; 32 | }; -------------------------------------------------------------------------------- /src/style/common/less/_utils.less: -------------------------------------------------------------------------------- 1 | @import "./_mixin.less"; 2 | // 浮动 3 | .right{ 4 | float: right; 5 | } 6 | 7 | .left{ 8 | float: left; 9 | } 10 | 11 | .center{ 12 | margin: 0 auto; 13 | float: none; 14 | } 15 | 16 | // 清除浮动 17 | .clear-both{ 18 | clear: both; 19 | height:1px; 20 | margin-top:-1px; 21 | overflow:hidden; 22 | &:before{ 23 | display:none; 24 | } 25 | &:after{ 26 | display:none; 27 | } 28 | } 29 | 30 | .block_area{ 31 | margin: 0 auto; 32 | position: relative; 33 | font-size: 14px; 34 | } 35 | 36 | // inline-block对齐 或者文本对齐 37 | .text-left{ 38 | text-align:left; 39 | } 40 | 41 | .text-right{ 42 | text-align:right; 43 | } 44 | 45 | .text-center{ 46 | text-align:center; 47 | } 48 | 49 | .text-bold{ 50 | font-weight:bold; 51 | } 52 | 53 | .activeB{ 54 | display: block; 55 | } 56 | 57 | .activeF{ 58 | display: flex; 59 | } 60 | 61 | .activeN{ 62 | display:none; 63 | } 64 | -------------------------------------------------------------------------------- /src/leetcode/_50.ts: -------------------------------------------------------------------------------- 1 | // 实现 `pow(x, n)` ,即计算 x 的 n 次幂函数。 2 | // **示例 1**: 3 | // ```code 4 | // 输入: 2.00000, 10 5 | // 输出: 1024.00000 6 | // ``` 7 | // **示例 2**: 8 | // ```code 9 | // 输入: 2.10000, 3 10 | // 输出: 9.26100 11 | // ``` 12 | // **示例 3**: 13 | // ```code 14 | // 输入: 2.00000, -2 15 | // 输出: 0.25000 16 | // 解释: 2-2 = 1/22 = 1/4 = 0.25 17 | // ``` 18 | // **说明**: 19 | // - -100.0 < x < 100.0 20 | // - n 是 32 位有符号整数,其数值范围是 [−2 的 31次方, 2 的31次方 − 1] 。 21 | 22 | export default function myPow(x: number, n: number): number { 23 | const fastPow = (x: number, n: number): number => { 24 | if (n === 0) { 25 | return 1; 26 | } 27 | 28 | const half = fastPow(x, Math.floor(n / 2)); 29 | if (n % 2 === 1) { 30 | // 基数 31 | return half * half * x; 32 | } else { 33 | return half * half; 34 | } 35 | } 36 | 37 | const ret = fastPow(x, Math.abs(n)); 38 | return n > 0 ? ret : 1 / ret; 39 | }; 40 | -------------------------------------------------------------------------------- /src/leetcode/_3.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @description 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。 3 | * 输入: "abcabcbb" 4 | * 输出: 3 5 | * 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。 6 | * 输入: "bbbbb" 7 | * 输出: 1 8 | * 解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。 9 | * 输入: "pwwkew" 10 | * 输出: 3 11 | * 解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。 12 | 请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。 13 | * @param {*} s 字符串 14 | * @link https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/ 15 | */ 16 | export default function _3 (s: string) { 17 | const l = s.length 18 | if (l === 1) { 19 | return 1; 20 | } 21 | const arrS = s.split(''); 22 | let maxLength = 0, selfJ = 0; 23 | for (let i = 0; i < l; i++) { 24 | for (let j = selfJ; j < i; j++) { 25 | maxLength = Math.max(maxLength, (i - j)) 26 | if (arrS[i] === arrS[j]) { 27 | selfJ = j + 1 28 | break 29 | } 30 | } 31 | } 32 | return Math.max(maxLength, l - selfJ) 33 | } 34 | -------------------------------------------------------------------------------- /src/leetcode/_1189.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @description 给你一个字符串 text,你需要使用 text 中的字母来拼凑尽可能多的单词 "balloon"(气球)。 3 | * 字符串 text 中的每个字母最多只能被使用一次。请你返回最多可以拼凑出多少个单词 "balloon" 4 | * 示例 1: 5 | * 输入:text = "nlaebolko" 6 | * 输出:1 7 | * 示例 2: 8 | * 输入:text = "loonbalxballpoon" 9 | * 输出:2 10 | * 示例 3: 11 | * 输入:text = "leetcode" 12 | * 输出: 0 13 | * 提示: 14 | * 1 <= text.length <= 10^4 15 | * text 全部由小写英文字母组成 16 | * @param {*} str 字符串 1 <= text.length <= 10^4 17 | * @link https://leetcode-cn.com/problems/palindrome-number/ 18 | */ 19 | export default function _1189 (str: string) { 20 | const s = 'balloon' 21 | if (str.length < s.length) return 0 22 | if (str.length === s.length && str !== s) return 0 23 | function getCount (s: string) { 24 | const re = "/[" + s + "]/g" 25 | return str.match(eval(re)) ? (str.match(eval(re))?.length || 0) : 0 26 | } 27 | return Math.min(getCount('b'), getCount('a'), ~~(getCount('l') / 2), ~~(getCount('o') / 2), getCount('n')) 28 | } 29 | -------------------------------------------------------------------------------- /webpack.prod.js: -------------------------------------------------------------------------------- 1 | const merge = require('webpack-merge'); 2 | const path = require('path'); 3 | const common = require('./webpack.common.js'); 4 | // css压缩打包相关 5 | var OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin'); 6 | 7 | // 打包清除dist目录 8 | const CleanWebpackPlugin = require('clean-webpack-plugin'); 9 | 10 | const resolve = function (dir) { 11 | return path.resolve(__dirname, dir); 12 | } 13 | module.exports = merge(common, { 14 | entry: { 15 | app: './src/index.ts' 16 | }, 17 | output: { 18 | path: resolve('dist'), 19 | publicPath: '', 20 | filename: 'js/[name]-[hash].js' 21 | }, 22 | plugins: [ 23 | // 清除 24 | new CleanWebpackPlugin(['dist'], { 25 | verbose: false 26 | }), 27 | 28 | // css 压缩 29 | new OptimizeCssAssetsPlugin({ 30 | assetNameRegExp: /\.optimize\.css$/g, 31 | cssProcessor: require('cssnano'), 32 | cssProcessorPluginOptions: { 33 | preset: ['default', { discardComments: { removeAll: true } }], 34 | }, 35 | canPrint: true 36 | }) 37 | ] 38 | }); -------------------------------------------------------------------------------- /src/leetcode/_142.ts: -------------------------------------------------------------------------------- 1 | // 先找到第一次相遇的位置,再用一个从头开始,与fast 或者 slow 一起 后移一位 2 | // 直到移动的位置,两个linkList 相等,说明这就是第一次进入环的元素 3 | function detectCycle(head: ListNode | null): ListNode | null { 4 | if (head === null || head.next === null) return null; 5 | 6 | let fast = head; 7 | let slow = head; 8 | 9 | // 如果有next 10 | while (fast && fast.next) { 11 | // fast -> 2 12 | fast = fast.next.next as ListNode; 13 | // slow -> 1 14 | slow = slow.next as ListNode; 15 | 16 | // 如果相等。slow 从新开始,与fast 同时每次移动一步 17 | if (fast === slow) { 18 | slow = head; 19 | while(slow !== fast) { 20 | slow = slow.next as ListNode; 21 | fast = fast.next as ListNode; 22 | } 23 | // 直到 slow 与 fast 相等 24 | return slow; 25 | } 26 | } 27 | return null; 28 | }; 29 | 30 | // function detectCycle(head: ListNode | null): ListNode | null { 31 | // while (head && head.next && !head.asd) { 32 | // head.asd = 1 33 | // head = head.next 34 | // } 35 | // if (head && head.asd) { 36 | // return head 37 | // } 38 | // return null 39 | // } 40 | -------------------------------------------------------------------------------- /src/global.d.ts: -------------------------------------------------------------------------------- 1 | declare class ListNode { 2 | val: number 3 | next: ListNode | null 4 | constructor(val?: number, next?: ListNode | null) { 5 | this.val = (val===undefined ? 0 : val) 6 | this.next = (next===undefined ? null : next) 7 | } 8 | } 9 | 10 | 11 | declare class ChildListNode { 12 | val: number 13 | prev: ChildListNode | null 14 | next: ChildListNode | null 15 | child: ChildListNode | null 16 | constructor(val?: number, prev? : ChildListNode, next? : ChildListNode, child? : ChildListNode) { 17 | this.val = (val===undefined ? 0 : val); 18 | this.prev = (prev===undefined ? null : prev); 19 | this.next = (next===undefined ? null : next); 20 | this.child = (child===undefined ? null : child); 21 | } 22 | } 23 | 24 | declare class TreeNode { 25 | val: number 26 | left: TreeNode | null 27 | right: TreeNode | null 28 | constructor(val?: number, left?: TreeNode | null, right?: TreeNode | null) { 29 | this.val = (val===undefined ? 0 : val) 30 | this.left = (left===undefined ? null : left) 31 | this.right = (right===undefined ? null : right) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/leetcode/_2.ts: -------------------------------------------------------------------------------- 1 | // 给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。 2 | 3 | // 请你将两个数相加,并以相同形式返回一个表示和的链表。 4 | 5 | // 你可以假设除了数字 0 之外,这两个数都不会以 0 开头。 6 | 7 | 8 | 9 | // 链接:https://leetcode-cn.com/leetbook/read/linked-list/fv6w7/ 10 | 11 | function addTwoNumbers(l1: ListNode | null, l2: ListNode | null): ListNode | null { 12 | if (!l1) return l2; 13 | if (!l2) return l1; 14 | // 创建新的 linkList 15 | let linkList = new ListNode(0); 16 | // link 用于next 移动赋值,更新 linkList 17 | let link = linkList; 18 | // 是否大于9 补1 19 | let isMoreThan9 = false; 20 | 21 | while(l1 || l2 || isMoreThan9) { 22 | // link.val = l1.val + l2.val + (isMoreThan9 ? 1 : 0); 23 | let val1 = ((l1 && l1.val) || 0); 24 | let val2 = ((l2 && l2.val) || 0); 25 | // 求值 26 | let sum: number = val1 + val2 + (isMoreThan9 ? 1 : 0); 27 | 28 | // 是否大于9 29 | isMoreThan9 = sum > 9; 30 | 31 | // 设置元素的值 32 | link.next = new ListNode(sum % 10); 33 | // 后移 34 | link = link.next; 35 | 36 | // 存在即后移 37 | l1 && (l1 = l1.next); 38 | l2 && (l2 = l2.next); 39 | } 40 | // 从第二个开始返回 41 | return linkList.next; 42 | }; 43 | -------------------------------------------------------------------------------- /src/leetcode/_61.ts: -------------------------------------------------------------------------------- 1 | // 旋转链表 2 | 3 | // 给定一个链表,旋转链表,将链表每个节点向右移动 k 个位置,其中 k 是非负数。 4 | 5 | // 示例 1: 6 | 7 | // 输入: 1->2->3->4->5->NULL, k = 2 8 | // 输出: 4->5->1->2->3->NULL 9 | // 解释: 10 | // 向右旋转 1 步: 5->1->2->3->4->NULL 11 | // 向右旋转 2 步: 4->5->1->2->3->NULL 12 | 13 | // 示例 2: 14 | 15 | // 输入: 0->1->2->NULL, k = 4 16 | // 输出: 2->0->1->NULL 17 | // 解释: 18 | // 向右旋转 1 步: 2->0->1->NULL 19 | // 向右旋转 2 步: 1->2->0->NULL 20 | // 向右旋转 3 步: 0->1->2->NULL 21 | // 向右旋转 4 步: 2->0->1->NULL 22 | 23 | function rotateRight(head: ListNode | null, k: number): ListNode | null { 24 | if (!head) return head; 25 | 26 | let length = 0; 27 | let caclL = head; 28 | while(caclL) { 29 | length ++; 30 | caclL = caclL.next as ListNode; 31 | } 32 | 33 | let pos = k % length; 34 | if (pos === 0) return head; 35 | let slow = head; 36 | let fast = head; 37 | while (pos > 0) { 38 | pos --; 39 | fast = fast.next as ListNode; 40 | } 41 | 42 | while (fast && fast.next) { 43 | slow = slow.next as ListNode; 44 | fast = fast.next; 45 | } 46 | 47 | let newHead = slow.next; 48 | slow.next = null; 49 | fast.next = head; 50 | return newHead; 51 | }; 52 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const dev = require('./webpack.dev') 2 | const prod = require('./webpack.prod') 3 | const chalk = require('chalk'); 4 | var os = require('os'); 5 | 6 | switch (process.env.NODE_ENV) { 7 | case 'development': 8 | module.exports = dev 9 | break 10 | case 'production': 11 | module.exports = prod 12 | break 13 | } 14 | 15 | // 获取Ip 16 | function getIPAdress() { 17 | let localIPAddress = ""; 18 | let interfaces = os.networkInterfaces(); 19 | for (let devName in interfaces) { 20 | let iface = interfaces[devName]; 21 | for (let i = 0; i < iface.length; i++) { 22 | let alias = iface[i]; 23 | if (alias.family === 'IPv4' && alias.address !== '127.0.0.1' && !alias.internal) { 24 | localIPAddress = alias.address; 25 | } 26 | } 27 | } 28 | localIp = localIPAddress; 29 | return localIPAddress; 30 | } 31 | 32 | // 打印返回信息 33 | if (process.env.NODE_ENV === 'development') { 34 | let host = dev.devServer.host ? dev.devServer.host : 'localhost' 35 | // getIPAdress 36 | if (host === '0.0.0.0') host = getIPAdress() 37 | const text = `server will start at: http://${host}:${dev.devServer.port}` 38 | console.log(chalk.green(text)) 39 | } -------------------------------------------------------------------------------- /src/leetcode/linkedList.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * 链表数据结构 3 | */ 4 | 5 | export class Node { 6 | val: T | null = null 7 | next: Node | null 8 | constructor(value: T) { 9 | this.val = value 10 | this.next = null 11 | } 12 | } 13 | 14 | export default class LinkedList { 15 | head: Node | null = null 16 | constructor() { 17 | this.head = new Node('header') 18 | } 19 | 20 | find = (item: T) => { 21 | let currentNode = this.head 22 | while (currentNode && currentNode.val != item) { 23 | currentNode = currentNode.next 24 | } 25 | return currentNode 26 | } 27 | 28 | insert = (value: T, item: T) => { 29 | // console.log('value', value) 30 | const newNode = new Node(value) 31 | const currentNode = this.find(item) 32 | console.log(currentNode) 33 | newNode.next = currentNode?.next || null 34 | currentNode && (currentNode.next = newNode) 35 | } 36 | } 37 | 38 | export function linkToArray (link: Node | null) { 39 | let arr: Array = [] 40 | const toArray = (item: Node | null) => { 41 | if (item == null) { 42 | return 43 | } 44 | 45 | if (item.val !== null) { 46 | arr.push(item.val) 47 | toArray(item.next) 48 | } 49 | } 50 | toArray(link || null) 51 | return arr 52 | } 53 | -------------------------------------------------------------------------------- /src/leetcode/_234.ts: -------------------------------------------------------------------------------- 1 | // 请判断一个链表是否为回文链表。 2 | 3 | // 示例 1: 4 | 5 | // 输入: 1->2 6 | // 输出: false 7 | // 示例 2: 8 | 9 | // 输入: 1->2->2->1 10 | // 输出: true 11 | // 进阶: 12 | // 你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题 13 | 14 | // function isPalindrome(head: ListNode | null): boolean { 15 | // if (!head) return false; 16 | // let stack = []; 17 | // let posHead = head; 18 | // while(posHead) { 19 | // stack.push(posHead.val); 20 | // posHead = posHead.next; 21 | // } 22 | 23 | // if (stack.length === 1) return true; 24 | 25 | // while(stack.length) { 26 | // if (stack.pop() === head.val) { 27 | // head = head.next; 28 | // } 29 | // return false; 30 | // } 31 | // return true; 32 | // }; 33 | 34 | function isPalindrome(head: ListNode | null): boolean { 35 | if(head === null || head.next === null) return true; 36 | let slow: ListNode = head; 37 | let fast: ListNode = head; 38 | let pre = null; 39 | let reverse = null; 40 | // 快指针先动直到结束 41 | while(fast && fast.next) { 42 | pre = slow; 43 | slow = slow.next as ListNode; 44 | fast = fast.next.next as ListNode; 45 | pre.next = reverse; 46 | reverse = pre; 47 | } 48 | if (fast) { 49 | slow = slow.next as ListNode; 50 | } 51 | 52 | while(slow) { 53 | if (slow.val !== reverse?.val) { 54 | return false; 55 | } 56 | slow = slow.next as ListNode; 57 | reverse = reverse?.next; 58 | } 59 | return true; 60 | } 61 | -------------------------------------------------------------------------------- /src/leetcode/_160.ts: -------------------------------------------------------------------------------- 1 | // 编写一个程序,找到两个单链表相交的起始节点。 2 | 3 | // https://leetcode-cn.com/leetbook/read/linked-list/jjbj2/ 4 | 5 | // 暴力法 6 | var getIntersectionNode = function(headA: ListNode | null, headB: ListNode | null): ListNode | null { 7 | if (!headA || !headB) return null; 8 | let currA = headA; 9 | while(currA) { 10 | // 遍历 b 11 | let currB = headB; 12 | while(currB) { 13 | if (currA === currB) { 14 | return currA; 15 | } 16 | currB = currB.next as ListNode; 17 | } 18 | currA = currA.next as ListNode; 19 | } 20 | return null 21 | }; 22 | 23 | // 哈希表 24 | var getIntersectionNode = function(headA: ListNode | null, headB: ListNode | null): ListNode | null { 25 | if (!headA || !headB) return null; 26 | let currA: ListNode | null = headA; 27 | let hash = new Map(); 28 | while(currA) { 29 | hash.set(currA, true); 30 | currA = currA.next; 31 | } 32 | 33 | let currB: ListNode | null = headB; 34 | while(currB) { 35 | if (hash.get(currB)) { 36 | return currB; 37 | } 38 | currB = currB.next; 39 | } 40 | return null; 41 | } 42 | 43 | // 双指针 44 | var getIntersectionNode = function(headA: ListNode | null, headB: ListNode | null): ListNode | null { 45 | if (!headA || !headB) return null; 46 | let currA: ListNode | null = headA; 47 | let currB: ListNode | null = headB; 48 | while(currA !== currB) { 49 | currA = currA === null ? headB : currA.next; 50 | currB = currB === null ? headA : currB.next; 51 | } 52 | return currA; 53 | } 54 | 55 | -------------------------------------------------------------------------------- /src/leetcode/study.ts: -------------------------------------------------------------------------------- 1 | import LinkedList, { Node } from "./linkedList"; 2 | 3 | /** 4 | * 编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 char[] 的形式给出。 5 | * 不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。 6 | * 你可以假设数组中的所有字符都是 ASCII 码表中的可打印字符。 7 | * 输入:["h","e","l","l","o"] 8 | * 输出:["o","l","l","e","h"] 9 | * 10 | * 输入:["H","a","n","n","a","h"] 11 | * 输出:["h","a","n","n","a","H"] 12 | */ 13 | export const reverseString = function(s: string[]) { 14 | const len = s.length 15 | let pos = 0 16 | let rightPos = len - 1 17 | while (pos < Math.ceil(len / 2)) { 18 | let target = s[pos] 19 | s[pos] = s[rightPos] 20 | s[rightPos] = target 21 | 22 | pos++ 23 | rightPos-- 24 | } 25 | return s 26 | }; 27 | 28 | /** 29 | * 给定 1->2->3->4, 你应该返回 2->1->4->3. 30 | */ 31 | // [1, 2, 3, 4] => [2, 1, 3, 4] 32 | 33 | // export const reverseTb = (arr: any[]) => { 34 | // let lk = new LinkedList() 35 | // const toLink = arr.reduce((item, current) => { 36 | // console.log('item, current', item, current) 37 | // lk.insert(current, item) 38 | // return item 39 | // }, lk.head.val) 40 | // console.log(toLink) 41 | // } 42 | 43 | export function swapPairs(head: Node | null) { 44 | if (head == null || head.next == null) { 45 | return head 46 | } 47 | 48 | const seconed = head.next 49 | head.next = swapPairs(seconed.next) 50 | seconed.next = head 51 | return seconed 52 | } 53 | 54 | 55 | 56 | let memo: any = {}; 57 | function fib(n: number): number { 58 | if (n == 0) return 0 59 | if (n == 1) return 1 60 | console.log(n, memo) 61 | if (memo[n]) return memo[n] 62 | memo[n] = fib(n - 1) + fib(n - 2) 63 | return memo[n]; 64 | }; 65 | 66 | export function fibArr(n: number): number { 67 | let arr = [0, 1]; 68 | for (let i = 2; i <= n; i++) { 69 | arr[i] = arr[i - 1] + arr[i - 2]; 70 | } 71 | return arr[n]; 72 | } 73 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "leet-code", 3 | "version": "1.0.0", 4 | "description": "leet-code", 5 | "main": "webpack.config.js", 6 | "dependencies": { 7 | "d-utils": "^3.0.0", 8 | "sha1": "^1.1.1" 9 | }, 10 | "scripts": { 11 | "test": "echo \"Error: no test specified\" && exit 1", 12 | "build": "cross-env NODE_ENV=production webpack --progress --mode production", 13 | "dev": "cross-env NODE_ENV=development webpack-dev-server --mode development --progress --colors", 14 | "watch": "webpack --colors --watch", 15 | "update": "yarn upgrade-interactive --latest" 16 | }, 17 | "keywords": [ 18 | "webpack", 19 | "webpack template", 20 | "template", 21 | "config" 22 | ], 23 | "author": "daiwei", 24 | "license": "ISC", 25 | "devDependencies": { 26 | "@babel/core": "^7.4.3", 27 | "@babel/plugin-proposal-class-properties": "^7.4.0", 28 | "@babel/plugin-proposal-decorators": "^7.4.0", 29 | "@babel/plugin-transform-runtime": "^7.4.3", 30 | "@babel/preset-env": "^7.4.3", 31 | "@babel/runtime": "^7.4.3", 32 | "@types/node": "^11.13.2", 33 | "atob": ">=2.1.0", 34 | "babel-loader": "^8.0.5", 35 | "babel-polyfill": "^6.26.0", 36 | "clean-webpack-plugin": "^1.0.0", 37 | "compass-mixins": "^0.12.10", 38 | "cross-env": "^5.2.0", 39 | "css-loader": "^0.28.10", 40 | "deep-extend": ">=0.5.1", 41 | "html-webpack-plugin": "^3.0.6", 42 | "less": "^3.9.0", 43 | "less-loader": "^4.1.0", 44 | "mini-css-extract-plugin": "^0.5.0", 45 | "optimize-css-assets-webpack-plugin": "^5.0.1", 46 | "postcss-loader": "^3.0.0", 47 | "randomatic": ">=3.0.0", 48 | "style-loader": "^0.20.3", 49 | "ts-loader": "^5.3.3", 50 | "typescript": "^3.2.4", 51 | "uglifyjs-webpack-plugin": "^2.1.1", 52 | "url-loader": "^1.0.1", 53 | "url-parse": ">=1.4.3", 54 | "webpack": "^4.29.0", 55 | "webpack-cli": "^3.2.1", 56 | "webpack-dev-server": ">=3.1.11", 57 | "webpack-merge": "^4.2.1" 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import './style.less'; 2 | // import './exp' 3 | import { fibArr, swapPairs } from './leetcode/study' 4 | import LinkedList, { linkToArray } from './leetcode/linkedList' 5 | import generate from './leetcode/_118' 6 | import getRow from './leetcode/_119' 7 | import fib from './leetcode/_509'; 8 | import { climbStairs } from './leetcode/_70'; 9 | import { add, fact, fact1, sum5, sum5Old } from './leetcode/weidigui'; 10 | import reverseString from './leetcode/_344'; 11 | import reverseList from './leetcode/_206'; 12 | import myPow from './leetcode/_50'; 13 | import kthGrammar from './leetcode/_779'; 14 | import generateTrees from './leetcode/_95'; 15 | import MyLinkedList from './leetcode/_707'; 16 | 17 | var obj = new MyLinkedList(); 18 | obj.addAtHead(7); 19 | console.log(JSON.stringify(obj)); 20 | obj.addAtHead(2); 21 | console.log(JSON.stringify(obj)); 22 | obj.addAtHead(1); 23 | console.log(JSON.stringify(obj)); 24 | obj.addAtIndex(3, 0); 25 | console.log(JSON.stringify(obj)); 26 | obj.deleteAtIndex(2); 27 | obj.addAtHead(6); 28 | obj.addAtTail(4) 29 | console.log(JSON.stringify(obj)); 30 | console.log(JSON.stringify(obj.get(4))) 31 | // obj.addAtHead(4); 32 | // obj.addAtIndex(5, 0); 33 | // obj.addAtHead(6); 34 | 35 | 36 | // console.log(JSON.stringify(obj)); 37 | // obj.addAtTail(3); 38 | // console.log(JSON.stringify(obj)); 39 | // obj.addAtIndex(1, 2); //链表变为1-> 2-> 3 40 | // console.log(JSON.stringify(obj)); 41 | // const crt = obj.get(1); //返回2 42 | // console.log('crt' + JSON.stringify(crt)); 43 | // obj.deleteAtIndex(1); //现在链表是1-> 3 44 | // const crt1 = obj.get(1); 45 | // console.log(JSON.stringify(obj)); 46 | // console.log('crt1' + JSON.stringify(crt1)); 47 | 48 | // console.log(reverseString(["h","e","l","l","o"])) 49 | // console.log(reverseString(["H","a","n","n","a","h"])) 50 | // console.log(reverseTb([1, 2, 3, 4])) 51 | console.log(kthGrammar(4, 4)); 52 | // console.log(generateTrees(3)); 53 | const link = new LinkedList() 54 | link.insert(1, link.head?.val || null) 55 | link.insert(2, 1) 56 | link.insert(3, 2) 57 | link.insert(4, 3) 58 | 59 | 60 | console.info('list', reverseList({ 61 | val: 1, 62 | next: { 63 | val: 2, 64 | next: { 65 | val: 3, 66 | next: { 67 | val: 4, 68 | next: null 69 | } 70 | } 71 | } 72 | })) 73 | 74 | 75 | linkToArray(swapPairs(link.head?.next || null)) 76 | 77 | // console.info('climbStairs', climbStairs(40)) 78 | // console.info('fact1', fact1(6, 1)); 79 | // console.info('fact', fact(6)); 80 | // console.info('add', add(6, 5)); 81 | 82 | // console.info('add', sum5(100000, 0)); 83 | // console.info('add', sum5Old(100000)); 84 | 85 | let s = ['a', 'b', 'c', 'd']; 86 | reverseString(s); 87 | console.info('ssss', s); 88 | 89 | // console.log(generate(5)) 90 | console.log('getRow(4)', getRow(3)) 91 | // console.log(fib(30)) -------------------------------------------------------------------------------- /src/style/common/scss/_utils.scss: -------------------------------------------------------------------------------- 1 | // 浮动 2 | .right{ 3 | float: right; 4 | } 5 | 6 | .left{ 7 | float: left; 8 | } 9 | 10 | .center{ 11 | margin: 0 auto; 12 | float: none; 13 | } 14 | 15 | // 清除浮动 16 | .clear-both{ 17 | clear: both; 18 | height:1px; 19 | margin-top:-1px; 20 | overflow:hidden; 21 | &:before{ 22 | display:none; 23 | } 24 | &:after{ 25 | display:none; 26 | } 27 | } 28 | 29 | .border-box{ 30 | @include box-sizing(border-box); 31 | } 32 | 33 | .content-wrap{ 34 | @include box-sizing(content-wrap); 35 | } 36 | 37 | .block_area{ 38 | margin: 0 auto; 39 | position: relative; 40 | font-size: 14px; 41 | } 42 | 43 | // inline-block对齐 或者文本对齐 44 | .text-left{ 45 | text-align:left; 46 | } 47 | 48 | .text-right{ 49 | text-align:right; 50 | } 51 | 52 | .text-center{ 53 | text-align:center; 54 | } 55 | 56 | .text-bold{ 57 | font-weight:bold; 58 | } 59 | 60 | .activeB{ 61 | display: block; 62 | } 63 | 64 | .activeF{ 65 | display: flex; 66 | } 67 | 68 | .activeN{ 69 | display:none; 70 | } 71 | 72 | 73 | @for $i from 0 through 30 { 74 | .padding-top-#{$i}{ 75 | padding-top: $i * 1px; 76 | } 77 | .padding-left-#{$i}{ 78 | padding-left: $i * 1px; 79 | } 80 | .padding-right-#{$i}{ 81 | padding-right: $i * 1px; 82 | } 83 | .padding-bottom-#{$i}{ 84 | padding-bottom: $i * 1px; 85 | } 86 | .padding-#{$i}{ 87 | padding: $i * 1px; 88 | } 89 | 90 | //-------------------- 91 | 92 | .margin-top-#{$i}{ 93 | margin-top: $i * 1px; 94 | } 95 | .margin-left-#{$i}{ 96 | margin-left: $i * 1px; 97 | } 98 | .margin-right-#{$i}{ 99 | margin-right: $i * 1px; 100 | } 101 | .margin-bottom-#{$i}{ 102 | margin-bottom: $i * 1px; 103 | } 104 | .margin-#{$i}{ 105 | padding: $i * 1px; 106 | } 107 | 108 | 109 | // ------------------- 110 | 111 | .text-indent-#{$i}{ 112 | text-indent: $i * 1px; 113 | } 114 | 115 | .border-r-#{$i}{ 116 | @include border-radius($i * 1px) 117 | } 118 | 119 | .m-padding-top-#{$i}{ 120 | padding-top: px75rem($i); 121 | } 122 | .m-padding-left-#{$i}{ 123 | padding-left: px75rem($i); 124 | } 125 | .m-padding-right-#{$i}{ 126 | padding-right: px75rem($i); 127 | } 128 | .m-padding-bottom-#{$i}{ 129 | padding-bottom: px75rem($i); 130 | } 131 | .m-padding-#{$i}{ 132 | padding: px75rem($i); 133 | } 134 | 135 | //-------------------- 136 | 137 | .m-margin-top-#{$i}{ 138 | margin-top: px75rem($i); 139 | } 140 | .m-margin-left-#{$i}{ 141 | margin-left: px75rem($i); 142 | } 143 | .m-margin-right-#{$i}{ 144 | margin-right: px75rem($i); 145 | } 146 | .m-margin-bottom-#{$i}{ 147 | margin-bottom: px75rem($i); 148 | } 149 | .m-margin-#{$i}{ 150 | padding: px75rem($i); 151 | } 152 | 153 | 154 | // ------------------- 155 | 156 | .m-text-indent-#{$i}{ 157 | text-indent: px75rem($i); 158 | } 159 | 160 | .m-border-r-#{$i}{ 161 | @include border-radius(px75rem($i)) 162 | } 163 | } 164 | 165 | @for $i from 10 through 50 { 166 | @if ($i % 2 == 0) { 167 | .m-size-#{$i}{ 168 | font-size: px75rem($i); 169 | } 170 | } 171 | } 172 | -------------------------------------------------------------------------------- /webpack.common.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); 3 | // MiniCssExtractPlugin 4 | const MiniCssExtractPlugin = require("mini-css-extract-plugin"); 5 | 6 | // HtmlWebpackPlugin 7 | const HtmlWebpackPlugin = require('html-webpack-plugin'); 8 | 9 | const resolve = function (dir) { 10 | return path.resolve(__dirname, dir); 11 | } 12 | 13 | const devMode = process.env.NODE_ENV === "development" 14 | 15 | module.exports = { 16 | plugins: [ 17 | new HtmlWebpackPlugin ({ 18 | filename: 'index.html', 19 | template: 'index.html', 20 | inject: true, 21 | favicon: 'src/assets/favicon/favicon.ico' 22 | }), 23 | 24 | new MiniCssExtractPlugin ({ 25 | filename: "css/[name]-[hash].css", 26 | chunkFilename: "css/[id].css" 27 | }) 28 | ], 29 | module: { 30 | unknownContextCritical : false, 31 | rules: [ 32 | { 33 | test: /\.(c)ss$/, 34 | use: [ 35 | devMode ? 'style-loader' : MiniCssExtractPlugin.loader, 36 | "css-loader", 37 | { 38 | loader:"postcss-loader", 39 | options: { 40 | plugins: (loader) => [ 41 | require('autoprefixer')() 42 | ] 43 | } 44 | }, 45 | "less-loader" 46 | ] 47 | }, 48 | { 49 | test: /\.less$/, 50 | use: [ 51 | devMode ? 'style-loader' : MiniCssExtractPlugin.loader, 52 | "css-loader", 53 | { 54 | loader:"postcss-loader", 55 | options: { 56 | plugins: (loader) => [ 57 | require('autoprefixer')() 58 | ] 59 | } 60 | }, 61 | "less-loader" 62 | ], 63 | }, 64 | { 65 | test: /\.styl$/, 66 | use: [ 67 | devMode ? 'style-loader' : MiniCssExtractPlugin.loader, 68 | "css-loader", 69 | { 70 | loader:"postcss-loader", 71 | options: { 72 | plugins: (loader) => [ 73 | require('autoprefixer')() 74 | ] 75 | } 76 | }, 77 | "stylus-loader" 78 | ] 79 | }, 80 | { 81 | test: /\.(ttf|eot|svg|woff|woff2)$/, 82 | use: [ 83 | { 84 | loader: 'url-loader' 85 | } 86 | ] 87 | }, 88 | { 89 | test: /\.js$/, 90 | exclude: /(node_modules)/, 91 | use: { 92 | loader: 'babel-loader' 93 | } 94 | }, 95 | { 96 | test: /\.ts$/, 97 | use: [ 98 | {loader: 'babel-loader',}, 99 | { 100 | loader: 'ts-loader', 101 | options: { 102 | // 加快编译速度 103 | transpileOnly: true, 104 | // 指定特定的ts编译配置,为了区分脚本的ts配置 105 | configFile: path.resolve(__dirname, './tsconfig.json') 106 | } 107 | } 108 | ] 109 | }, 110 | { 111 | test: /\.(png|jpg|gif)$/, 112 | use: [ 113 | { 114 | loader: 'url-loader', 115 | options: { 116 | limit: 8192 117 | } 118 | } 119 | ] 120 | }, 121 | ] 122 | }, 123 | resolve: { 124 | alias: { 125 | 'src': resolve('src'), 126 | 'assets': resolve('src/assets'), 127 | 'style': resolve('src/style') 128 | }, 129 | extensions: ['.ts', '.tsx', '.js'], 130 | modules: ['src' ,'node_modules'] 131 | }, 132 | optimization: { 133 | splitChunks: { 134 | chunks: "all", 135 | minSize: 30000, 136 | minChunks: 3, 137 | maxAsyncRequests: 5, 138 | maxInitialRequests: 3, 139 | name: true, 140 | cacheGroups: { 141 | default: { 142 | minChunks: 2, 143 | priority: -20, 144 | reuseExistingChunk: true, 145 | }, 146 | vendors: { 147 | test: /[\\/]node_modules[\\/]/, 148 | priority: -10 149 | } 150 | } 151 | }, 152 | minimizer: [ 153 | new UglifyJsPlugin({ 154 | test: /\.js(\?.*)?$/i, 155 | }), 156 | ] 157 | } 158 | }; -------------------------------------------------------------------------------- /src/leetcode/_707.ts: -------------------------------------------------------------------------------- 1 | // 设计链表的实现。您可以选择使用单链表或双链表。单链表中的节点应该具有两个属性:val 和 next。val 是当前节点的值,next 是指向下一个节点的指针/引用。如果要使用双向链表,则还需要一个属性 prev 以指示链表中的上一个节点。假设链表中的所有节点都是 0-index 的。 2 | 3 | // 在链表类中实现这些功能: 4 | 5 | // - get(index):获取链表中第 index 个节点的值。如果索引无效,则返回-1。 6 | // - addAtHead(val):在链表的第一个元素之前添加一个值为 val 的节点。插入后,新节点将成为链表的第一个节点。 7 | // - addAtTail(val):将值为 val 的节点追加到链表的最后一个元素。 8 | // - addAtIndex(index,val):在链表中的第 index 个节点之前添加值为 val  的节点。如果 index 等于链表的长度,则该节点将附加到链表的末尾。如果 index 大于链表长度,则不会插入节点。如果index小于0,则在头部插入节点。 9 | // - deleteAtIndex(index):如果索引 index 有效,则删除链表中的第 index 个节点。 10 | 11 | // **示例:** 12 | 13 | // ```code 14 | // MyLinkedList linkedList = new MyLinkedList(); 15 | // linkedList.addAtHead(1); 16 | // linkedList.addAtTail(3); 17 | // linkedList.addAtIndex(1,2); //链表变为1-> 2-> 3 18 | // linkedList.get(1); //返回2 19 | // linkedList.deleteAtIndex(1); //现在链表是1-> 3 20 | // linkedList.get(1); //返回3 21 | // ``` 22 | 23 | // **提示:** 24 | // - 所有val值都在 [1, 1000] 之内。 25 | // - 操作次数将在 [1, 1000] 之内。 26 | // - 请不要使用内置的 LinkedList 库。 27 | 28 | class NodePerte { 29 | val; 30 | next: NodePerte | null; 31 | constructor(val: number) { 32 | this.val = val; 33 | this.next = null; 34 | } 35 | } 36 | 37 | export default class MyLinkedList { 38 | head: NodePerte | null = null; 39 | tail: NodePerte | null = null; 40 | length: number = 0; 41 | constructor() {} 42 | 43 | get(index: number): number { 44 | let list = this.getList(index); 45 | return list ? list.val : -1; 46 | } 47 | 48 | getList(index: number): NodePerte | null { 49 | if (index > this.length || index < 0) return null; 50 | let pos = 0; 51 | let curList = this.head; 52 | while (pos < index) { 53 | curList = (curList as NodePerte).next; 54 | pos++; 55 | } 56 | return curList; 57 | } 58 | 59 | addAtHead(val: number): void { 60 | const lastHead = this.head; 61 | // 创建一个list node 节点 62 | const node = new NodePerte(val); 63 | node.next = lastHead; 64 | this.head = node; 65 | // 如果没有tail 相当于首次初始化添加head 66 | // tail 也就是 head 只是tail 的next 是null 67 | if (!this.tail) { 68 | this.tail = node; 69 | this.tail.next = null; 70 | } 71 | this.length ++; 72 | } 73 | 74 | addAtTail(val: number): void { 75 | const node = new NodePerte(val); 76 | const _lastTail = this.tail; 77 | this.tail = node; 78 | // 如果已经有过 tail,则在原来的tail后加一个 linkList 79 | if (_lastTail) { 80 | _lastTail.next = this.tail; 81 | } 82 | 83 | // 如果不存在head 则帮他添加 84 | if (!this.head) { 85 | this.head = node; 86 | this.head.next = null; 87 | } 88 | this.length ++; 89 | } 90 | 91 | addAtIndex(index: number, val: number): void { 92 | if (index === this.length) { 93 | return this.addAtTail(val); 94 | } 95 | if (index === 0) { 96 | return this.addAtHead(val); 97 | } 98 | if (index > 0 && index < this.length) { 99 | let prevList = this.getList(index - 1); 100 | const addList = new NodePerte(val); 101 | addList.next = prevList?.next ?? null; 102 | (prevList as NodePerte).next = addList; 103 | this.length ++; 104 | } 105 | } 106 | 107 | deleteAtIndex(index: number): void { 108 | if (index > 0 && index < this.length) { 109 | let prev = this.getList(index - 1); 110 | let curList = prev?.next; 111 | 112 | // prev 的next 则跳过 current ,直接连接current 的 next 上的linkList 113 | (prev as NodePerte).next = curList?.next || null; 114 | 115 | // 判断删除的是否是最后一个 116 | if (index === this.length - 1) { 117 | this.tail = prev; 118 | } 119 | this.length --; 120 | } else if (index === 0) { 121 | if (this.head) { 122 | this.head = this.head?.next; 123 | this.length --; 124 | } 125 | } 126 | } 127 | } 128 | 129 | /** 130 | * Your MyLinkedList object will be instantiated and called as such: 131 | * var obj = new MyLinkedList() 132 | * var param_1 = obj.get(index) 133 | * obj.addAtHead(val) 134 | * obj.addAtTail(val) 135 | * obj.addAtIndex(index,val) 136 | * obj.deleteAtIndex(index) 137 | */ -------------------------------------------------------------------------------- /src/style/common/less/_mixin.less: -------------------------------------------------------------------------------- 1 | .lineclamp (@height, @count) { 2 | height: @height; 3 | line-height: @height / @count; 4 | overflow:hidden; 5 | text-overflow:ellipsis; 6 | display:-webkit-box; 7 | -webkit-box-orient:vertical; 8 | -webkit-line-clamp: @count; 9 | word-wrap: break-word; 10 | } 11 | 12 | .textoneline(@height) when (@height = auto) { 13 | height: @height; 14 | line-height: initial; 15 | text-overflow: ellipsis; 16 | white-space: nowrap; 17 | overflow: hidden; 18 | } 19 | 20 | .textoneline(@height) when (@height = height) { 21 | height: @height; 22 | line-height: @height; 23 | text-overflow: ellipsis; 24 | white-space: nowrap; 25 | overflow: hidden; 26 | } 27 | 28 | // top left = > right bottom 29 | .colortext-lt (@color1, @color2) { 30 | position: relative; 31 | background: -webkit-linear-gradient(left top, @color1 , @color2); /* Safari 5.1 - 6.0 */ 32 | background: -o-linear-gradient(bottom right, @color1, @color2); /* Opera 11.1 - 12.0 */ 33 | background: -moz-linear-gradient(bottom right, @color1, @color2); /* Firefox 3.6 - 15 */ 34 | background: linear-gradient(to bottom right, @color1 , @color2); /* 标准的语法 */ 35 | -webkit-background-clip: text; 36 | -webkit-text-fill-color: transparent; 37 | } 38 | 39 | // left = > right 40 | .colortext-l (@color1, @color2) { 41 | position: relative; 42 | background: -webkit-linear-gradient(left, @color1 , @color2); /* Safari 5.1 - 6.0 */ 43 | background: -o-linear-gradient(right, @color1, @color2); /* Opera 11.1 - 12.0 */ 44 | background: -moz-linear-gradient(right, @color1, @color2); /* Firefox 3.6 - 15 */ 45 | background: linear-gradient(to right, @color1 , @color2); /* 标准的语法 */ 46 | -webkit-background-clip: text; 47 | -webkit-text-fill-color: transparent; 48 | } 49 | 50 | // 添加blur模糊效果 51 | // 如果不是绝对定位,父元素需要设置相对定位 52 | // @blur 为模糊的数值 53 | // @height 区域的高度 54 | // @position 为位置 默认50% 55 | .blur(@blur, @height, @position: 50%, @scale: 1.5) { 56 | position: absolute; 57 | top: 0; 58 | left: 0; 59 | right: 0; 60 | height: @height; 61 | background-repeat: no-repeat; 62 | background-size: cover; 63 | background-position: @position; 64 | -webkit-filter: blur(@blur); 65 | filter: blur(@blur); 66 | -webkit-transform: scale(@scale); 67 | transform: scale(@scale); 68 | overflow: hidden; 69 | &::before{ 70 | content: ''; 71 | position: absolute; 72 | left: 0; 73 | top: 0; 74 | right: 0; 75 | bottom: 0; 76 | z-index: 1; 77 | background: rgba(0,0,0,0.1); 78 | transition: all 0.3s; 79 | } 80 | &.draken{ 81 | &::before{ 82 | background: rgba(0,0,0,0.3); 83 | } 84 | } 85 | } 86 | 87 | .blur(@blur, @height, @position: 50%, @scale: 1.5) when (@height = auto) { 88 | bottom: 0; 89 | height: unset; 90 | } 91 | 92 | // 固定底部 93 | .fixfooterflex () { 94 | html{ 95 | height: 100%; 96 | } 97 | 98 | body{ 99 | display: flex; 100 | flex-direction: column; 101 | min-height: 100%; 102 | font-family: "Hiragino Sans GB","Century Gothic",system, Arial, Verdana, Tahoma,"微软雅黑"; 103 | position: relative; 104 | width: 100%; 105 | overflow-x: hidden; 106 | } 107 | 108 | header{ 109 | /* 我们希望 header 采用固定的高度,只占用必须的空间 */ 110 | /* 0 flex-grow, 0 flex-shrink, auto flex-basis */ 111 | flex: 0 0 auto; 112 | } 113 | 114 | .main_content{ 115 | /* 将 flex-grow 设置为1,该元素会占用所有的可使用空间 116 | 而其他元素该属性值为0,因此不会得到多余的空间*/ 117 | /* 1 flex-grow, 0 flex-shrink, auto flex-basis */ 118 | flex: 1 1 auto; 119 | background-color: #fff; 120 | position:relative; 121 | } 122 | 123 | footer{ 124 | /* 和 header 一样,footer 也采用固定高度*/ 125 | /* 0 flex-grow, 0 flex-shrink, auto flex-basis */ 126 | flex: 0 0 auto; 127 | } 128 | } 129 | 130 | // hr 线条和颜色 131 | .hr(@color, @name) { 132 | .hr-@{color} { 133 | width: 100%; 134 | height: 1px; 135 | background: @color; 136 | font-size: 0; 137 | margin: 0 auto; 138 | } 139 | @media (-webkit-min-device-pixel-ratio: 2),(min-device-pixel-ratio: 2) { 140 | transform: translate(0, 1 / 2 * 100'px'); 141 | } 142 | @media (-webkit-min-device-pixel-ratio: 3),(min-device-pixel-ratio: 3) { 143 | transform: translate(0, 1 / 2 * 100'px'); 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /src/style/common/scss/_mixin.scss: -------------------------------------------------------------------------------- 1 | //移动端通用样式 1rem 相当于100px算的 也就是 宽度 / 7.5的比例 2 | @function px75rem($px){ 3 | $rem : 100px; 4 | @return ($px * 1px / $rem) + rem; 5 | } 6 | 7 | // 多少行限制超出省略 8 | @mixin lineclamp($height, $count, $isrem: false) { 9 | @if($isrem == false) { 10 | height: px75rem($height); 11 | line-height: px75rem($height / $count); 12 | } @else { 13 | height: $height; 14 | line-height: $height / $count; 15 | } 16 | overflow:hidden; 17 | text-overflow:ellipsis; 18 | display:-webkit-box; 19 | -webkit-box-orient:vertical; 20 | -webkit-line-clamp: $count; 21 | word-wrap: break-word; 22 | } 23 | 24 | @mixin textoneline ($height: auto) { 25 | height: $height; 26 | @if($height == auto) { 27 | line-height: initial; 28 | } else { 29 | line-height:$height; 30 | } 31 | @include ellipsis(); 32 | } 33 | 34 | 35 | @mixin colortext-lt ($color1, $color2) { 36 | position: relative; 37 | @include background(linear-gradient(to bottom right, $color1, $color2)); 38 | -webkit-background-clip: text; 39 | -webkit-text-fill-color: transparent; 40 | } 41 | 42 | @mixin colortext-l ($color1, $color2) { 43 | position: relative; 44 | @include background(linear-gradient(to right, $color1, $color2)); 45 | -webkit-background-clip: text; 46 | -webkit-text-fill-color: transparent; 47 | } 48 | 49 | // 计算属性 50 | @mixin ccalc($pro, $all, $reduce) { 51 | #{$pro}: calc(#{$all} - #{$reduce}); 52 | } 53 | 54 | // footer header content充满body 55 | @mixin fixfooter($headerH, $footerH) { 56 | body,html{ 57 | min-height: unset!important; 58 | height: 100%!important; 59 | } 60 | .custom_header{ 61 | height: $headerH; 62 | @include box-sizing(border-box); 63 | position: relative; 64 | } 65 | .custom_footer{ 66 | height: $footerH; 67 | @include box-sizing(border-box); 68 | position: relative; 69 | } 70 | .custom_content{ 71 | position: relative; 72 | background-color: #f0f0f0; 73 | min-height: calc(100% - #{$headerH} - #{$footerH}); 74 | } 75 | } 76 | 77 | @mixin fixfooterflex () { 78 | html{ 79 | height: 100%; 80 | } 81 | 82 | body{ 83 | display: flex; 84 | flex-direction: column; 85 | min-height: 100%; 86 | // font-family: "Hiragino Sans GB","Century Gothic",system, Arial, Verdana, Tahoma,"微软雅黑"; 87 | font-family: $font; 88 | position: relative; 89 | width: 100%; 90 | overflow-x: hidden; 91 | } 92 | 93 | header{ 94 | /* 我们希望 header 采用固定的高度,只占用必须的空间 */ 95 | /* 0 flex-grow, 0 flex-shrink, auto flex-basis */ 96 | flex: 0 0 auto; 97 | } 98 | 99 | .main_content{ 100 | /* 将 flex-grow 设置为1,该元素会占用所有的可使用空间 101 | 而其他元素该属性值为0,因此不会得到多余的空间*/ 102 | /* 1 flex-grow, 0 flex-shrink, auto flex-basis */ 103 | flex: 1 1 auto; 104 | background-color: $color_bg; 105 | position:relative; 106 | } 107 | 108 | footer{ 109 | /* 和 header 一样,footer 也采用固定高度*/ 110 | /* 0 flex-grow, 0 flex-shrink, auto flex-basis */ 111 | flex: 0 0 auto; 112 | } 113 | } 114 | 115 | @mixin colorplaceholder($color) { 116 | ::-webkit-input-placeholder { /* WebKit browsers */ 117 | color: $color; 118 | } 119 | :-moz-placeholder { /* Mozilla Firefox 4 to 18 */ 120 | color: $color; 121 | opacity: 1; 122 | } 123 | ::-moz-placeholder { /* Mozilla Firefox 19+ */ 124 | color: $color; 125 | opacity: 1; 126 | } 127 | :-ms-input-placeholder { /* Internet Explorer 10+ */ 128 | color: $color; 129 | } 130 | } 131 | 132 | // 字体文字颜色的mixin 133 | @mixin colortext($color, $name) { 134 | .color-#{$name}{ 135 | color: $color; 136 | } 137 | } 138 | 139 | // hr 线条和颜色 140 | @mixin hr($color, $name) { 141 | .hr-#{$name}{ 142 | width: 100%; 143 | height: 1px; 144 | background: $color; 145 | font-size: 0; 146 | margin: 0 auto; 147 | } 148 | @media (-webkit-min-device-pixel-ratio: 2),(min-device-pixel-ratio: 2) { 149 | @include translate(0, 1 / 2 * 100'px'); 150 | } 151 | @media (-webkit-min-device-pixel-ratio: 3),(min-device-pixel-ratio: 3) { 152 | @include translate(0, 1 / 2 * 100'px'); 153 | } 154 | } 155 | 156 | // fixed布局铺面全屏 157 | @mixin fixedfull() { 158 | position: fixed; 159 | right: 0; 160 | top: 0; 161 | left: 0; 162 | bottom: 0; 163 | } 164 | 165 | // 不同背景图片使用不同的尺寸 166 | @mixin bgimage($url, $type: png, $hasmedia: false){ 167 | @if($hasmedia == true){ 168 | @media (-webkit-min-device-pixel-ratio: 2),(min-device-pixel-ratio: 2) { 169 | background-image: url($url + "@2x." + $type) 170 | } 171 | @media (-webkit-min-device-pixel-ratio: 3),(min-device-pixel-ratio: 3) { 172 | background-image: url($url + "@3x." + $type) 173 | } 174 | } 175 | background-image: url($url + "." + $type) 176 | } 177 | 178 | -------------------------------------------------------------------------------- /src/leetcode/index.js: -------------------------------------------------------------------------------- 1 | import { fnTime } from 'd-utils/lib/decoratorUtils' 2 | 3 | export default class LeetCode { 4 | /** 5 | * @description 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。 6 | * 你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。 7 | * 示例: 8 | * 给定 nums = [2, 7, 11, 15], target = 9 9 | * 因为 nums[0] + nums[1] = 2 + 7 = 9 10 | * 所以返回 [0, 1] 11 | * @param {*} nums 数组 12 | * @param {*} target 目标相加的值 13 | * @link https://leetcode-cn.com/problems/two-sum/ 14 | */ 15 | 16 | @fnTime 17 | static _1 (nums, target) { 18 | const l = nums.length 19 | const m = new Map() 20 | for (let i = 0; i < l; i ++) { 21 | const r = target - nums[i] 22 | if (m.has(r)) { 23 | return [m.get(r), i] 24 | } else { 25 | m.set(nums[i], i) 26 | } 27 | } 28 | return [] 29 | } 30 | 31 | /** 32 | * @description 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。 33 | * 输入: "abcabcbb" 34 | * 输出: 3 35 | * 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。 36 | * 输入: "bbbbb" 37 | * 输出: 1 38 | * 解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。 39 | * 输入: "pwwkew" 40 | * 输出: 3 41 | * 解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。 42 | 请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。 43 | * @param {*} s 字符串 44 | * @link https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/ 45 | */ 46 | @fnTime 47 | static _3 (s) { 48 | const l = s.length 49 | if (l === 1) { 50 | return 1; 51 | } 52 | const arrS = s.split(''); 53 | let maxLength = 0, selfJ = 0; 54 | for (let i = 0; i < l; i++) { 55 | for (let j = selfJ; j < i; j++) { 56 | maxLength = Math.max(maxLength, (i - j)) 57 | if (arrS[i] === arrS[j]) { 58 | selfJ = j + 1 59 | break 60 | } 61 | } 62 | } 63 | return Math.max(maxLength, l - selfJ) 64 | } 65 | 66 | /** 67 | * @description 给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。 68 | * 示例 1: 69 | * 输入: 123 70 | * 输出: 321 71 | * @param {*} x 72 | */ 73 | @fnTime 74 | static _7 (x) { 75 | let resut = 0 76 | do { 77 | if (resut > 214748364 || resut < -214748364) return 0 78 | resut = resut * 10 + x % 10 79 | x = ~~(x / 10) 80 | } while (x) 81 | return resut 82 | } 83 | 84 | /** 85 | * @description 判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。 86 | * 示例 1: 87 | * 输入: 121 88 | * 输出: true 89 | * 示例 2: 90 | * 输入: -121 91 | * 输出: false 92 | * 解释: 从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。 93 | * 示例 3: 94 | * 输入: 10 95 | * 输出: false 96 | * 解释: 从右向左读, 为 01 。因此它不是一个回文数。 97 | * @param {*} x 整数 98 | * @link https://leetcode-cn.com/problems/palindrome-number/ 99 | */ 100 | @fnTime 101 | static _9 (x) { 102 | if (x < 0) return false 103 | let resut = 0; 104 | let t = x; 105 | do { 106 | resut = resut * 10 + x % 10; 107 | x = Math.floor(x / 10) 108 | } while (x) 109 | return resut === t 110 | } 111 | 112 | /** 113 | * @description 给你一个字符串 text,你需要使用 text 中的字母来拼凑尽可能多的单词 "balloon"(气球)。 114 | * 字符串 text 中的每个字母最多只能被使用一次。请你返回最多可以拼凑出多少个单词 "balloon" 115 | * 示例 1: 116 | * 输入:text = "nlaebolko" 117 | * 输出:1 118 | * 示例 2: 119 | * 输入:text = "loonbalxballpoon" 120 | * 输出:2 121 | * 示例 3: 122 | * 输入:text = "leetcode" 123 | * 输出: 0 124 | * 提示: 125 | * 1 <= text.length <= 10^4 126 | * text 全部由小写英文字母组成 127 | * @param {*} str 字符串 1 <= text.length <= 10^4 128 | * @link https://leetcode-cn.com/problems/palindrome-number/ 129 | */ 130 | @fnTime 131 | static _1189 (str) { 132 | const s = 'balloon' 133 | if (str.length < s.length) return 0 134 | if (str.length === s.length && str !== s) return 0 135 | function getCount (s) { 136 | const re = "/[" + s + "]/g" 137 | return str.match(eval(re)) ? str.match(eval(re)).length : 0 138 | } 139 | return Math.min(getCount('b'), getCount('a'), ~~(getCount('l') / 2), ~~(getCount('o') / 2), getCount('n')) 140 | } 141 | 142 | /** 143 | * 面试题 10.01. 合并排序的数组 144 | */ 145 | // let A = [1,2,3,0,0,0], 146 | // m = 3, 147 | // B = [2,5,6], 148 | // n = 3 149 | // let mergeSortArray = (A, m, B, n) => { 150 | // if (m === 0) return B 151 | // if (n === 0) return A 152 | // let i = 0; 153 | // let j = 0; 154 | // let r = [] 155 | // while (i < m && j < n) { 156 | // if (A[i] > B[j]) { 157 | // r.push(B[j]) 158 | // j ++ 159 | // } else { 160 | // r.push(A[i]) 161 | // i ++ 162 | // } 163 | // } 164 | 165 | // while (j < m) { 166 | // r.push(B[j]) 167 | // j++ 168 | // } 169 | 170 | // while (i < n) { 171 | // r.push(A[i]) 172 | // i++ 173 | // } 174 | // console.log(r) 175 | // } 176 | // mergeSortArray([1,2,3,0,0,0], 3, [2,5,6], 3) 177 | } -------------------------------------------------------------------------------- /src/exp.ts: -------------------------------------------------------------------------------- 1 | import { LogUtils } from '@dw/d-utils' 2 | const Exp1 = /\bhi\b/ 3 | // \b 匹配单词的开始或结束 4 | LogUtils.logInfo(Exp1.test('hi')) 5 | LogUtils.logInfo(Exp1.test('hi2')) 6 | LogUtils.logError('', '--------------------------------------') 7 | const Exp2 = /\bhi\b.\bLucy\b/ 8 | LogUtils.logInfo(Exp2.test('hi Lucy')) 9 | LogUtils.logInfo(Exp2.test('hi aaa Lucy')) 10 | 11 | // 匹配字符长度 12 | // ^匹配你 要用来查找的字符串的开头,$匹配结尾。 13 | LogUtils.logInfo(/^\d{5,12}$/.test('11111')) 14 | LogUtils.logError('', '--------------------------------------') 15 | // w 匹配一个单字字符(字母、数字或者下划线)等价于[A-Za-z0-9_] 16 | LogUtils.logInfo(/\w/.test('aaaaa')) // true 17 | LogUtils.logInfo(/\w/.test('111')) // true 18 | LogUtils.logInfo(/\w/.test('z')) // true 19 | LogUtils.logInfo(/\w/.test('_')) // true 20 | // 匹配一个非单字字符。等价于[^A-Za-z0-9_] 21 | LogUtils.logInfo(/\W/.test('_')) // false 22 | LogUtils.logError('', '--------------------------------------') 23 | // 匹配字符串的开始用在[]括号里面表示排除,/^A/ 并不会匹配 "an A" 中的 'A',但是会匹配 "An E" 中的 'A'。 24 | LogUtils.logInfo(/\W/.test('a&&')) // true 25 | LogUtils.logInfo(/^\W/.test('a&&')) // false 26 | LogUtils.logInfo(/^\W/.test('&a&&')) // true 27 | LogUtils.logError('', '--------------------------------------') 28 | LogUtils.logInfo(/[^\w]/.test('a')) // true 相当于 /\W/ 29 | LogUtils.logInfo(/[^\W]/.test('a')) // true 30 | // $ 匹配字符串的结束。例如,/t$/ 并不会匹配 "eater" 中的 't',但是会匹配 "eat" 中的 't'。 QQ号必须为5位到12位数字时,可以使用:^\d{5,12}$ 31 | LogUtils.logInfo(/[^\W]$/.test('a_&')) // false 32 | LogUtils.logInfo(/[^\W]$/.test('a&_')) // true 33 | 34 | LogUtils.logError('', '--------------------------------------') 35 | // s 代表任意空白符(换行符,制表符,空格) 36 | LogUtils.logInfo(/\s/.test(' ')) // true 37 | 38 | 39 | // d 匹配一个数字,等价于[0-9] 40 | LogUtils.logInfo(/\d/.test(' ')) // false 41 | LogUtils.logInfo(/\d/.test('1111')) // true 42 | // D 匹配一个数字,等价于[^0-9] 43 | LogUtils.logInfo(/\d/.test('1111')) // false 44 | LogUtils.logError('', '--------------------------------------') 45 | 46 | // () 代表一个组 如果想要重复多个字符该怎么办?你可以用小括号来指定子表达式(也叫做分组) 47 | LogUtils.logInfo(/(\d{1,3}\.){3}\d{1,3}/.test('222.222.222.1')) // true 48 | LogUtils.logInfo([/\w.+/.test('test.i.ng'), /[a-z.]+/.test('test.i.ng')]) // true 49 | LogUtils.logInfo(/\w{3,5}/.test('___')) // true 50 | LogUtils.logInfo(/\d{3,5}/.test('___')) // true 51 | LogUtils.logError('', '--------------------------------------') 52 | // i 忽略大小写 53 | LogUtils.logInfo(/a/.test('aaaaaa')) // true 54 | LogUtils.logInfo(/a/.test('AAAAAA')) // false 55 | LogUtils.logInfo(/a/i.test('AAAAAA')) // true 56 | LogUtils.logError('', '--------------------------------------') 57 | // g 执行全局匹配 58 | LogUtils.logInfo(/a/.test('vvvvva')) // true 59 | const Exp3 = /a/g 60 | const str = 'aaaaaaaa' 61 | LogUtils.logInfo(Exp3.test(str)) // true 62 | LogUtils.logWarning(Exp3.lastIndex) 63 | LogUtils.logInfo(Exp3.test(str)) // true 64 | LogUtils.logWarning(Exp3.lastIndex) 65 | LogUtils.logInfo(Exp3.test(str)) // true 66 | LogUtils.logWarning(Exp3.lastIndex) 67 | LogUtils.logInfo(Exp3.test(str)) // true 68 | LogUtils.logWarning(Exp3.lastIndex) 69 | LogUtils.logError('', '--------------------------------------') 70 | // 71 | const str1 = 'daiwei' 72 | LogUtils.logInfo(/d(?=a)/.test(str1)) 73 | LogUtils.logInfo(/d(?=i|a)/.test(str1)) 74 | 75 | const num = '021-121121' 76 | LogUtils.logInfo(/\(?0\d{2}[)-]?\d{6}/.test(num)) 77 | 78 | // 6-12 数字 字母 下划线 79 | const pwd = 'Daiwei__12' 80 | LogUtils.logInfo(/^\w{6,12}$/.test(pwd)) 81 | LogUtils.logError('', '--------------------------------------') 82 | const str2 = 'Hi RegExp I love you so much Hi Hi hi' 83 | const Exp4 = /\bhi\b/gi 84 | const Exp5 = /\bhi\b.*\bmuch\b/gi 85 | LogUtils.logInfo(Exp4.test(str2)) 86 | LogUtils.logInfo(Exp4.lastIndex) 87 | LogUtils.logInfo(Exp4.test(str2)) 88 | LogUtils.logInfo(Exp4.lastIndex) 89 | LogUtils.logInfo(Exp4.test(str2)) 90 | LogUtils.logInfo(Exp4.lastIndex) 91 | LogUtils.logInfo(Exp4.test(str2)) 92 | LogUtils.logInfo(Exp4.lastIndex) 93 | LogUtils.logInfo(str2.match(Exp4)) 94 | LogUtils.logInfo(Exp5.test(str2)) 95 | LogUtils.logInfo(str2.match(Exp5)) 96 | LogUtils.logError('', '--------------------------------------') 97 | 98 | // 匹配手机号 0123-88752314 99 | const Exp6 = /^0\d{3}-\d{8}$/g 100 | LogUtils.logInfo(Exp6.test('0123-45678910')) 101 | LogUtils.logInfo(Exp6.test('0123-456789101')) 102 | LogUtils.logInfo(Exp6.test('10123-456789101')) 103 | LogUtils.logInfo('0123-45678910'.match(Exp6)) 104 | LogUtils.logInfo('0123-456789101'.match(Exp6)) 105 | LogUtils.logInfo('10123-456789101'.match(Exp6)) 106 | LogUtils.logError('', '--------------------------------------') 107 | 108 | // 清除字符串首尾表达式 109 | const str3 = ' this is space ' 110 | const Exp7 = /(^\s*) | (\s*$)/g 111 | // 去除所有空格 112 | const Exp8 = /(\s)/g 113 | LogUtils.logInfo(str3) 114 | LogUtils.logInfo(str3.replace(Exp7, '')) 115 | LogUtils.logInfo(str3.replace(Exp8, '')) 116 | LogUtils.logError('', '--------------------------------------') 117 | 118 | // 匹配一个邮箱。 185098535@qq.com 119 | const Exp9 = /\S*@\S*\.\S*/ 120 | const str4 = '18509535@qq.com' 121 | LogUtils.logInfo(Exp9.test(str4)) 122 | LogUtils.logError('', '--------------------------------------') 123 | 124 | // 练习只能是汉字 125 | const Exp10 = /^[\u4e00-\u9fa5]*$/g 126 | const str5 = '戴伟' 127 | LogUtils.logInfo(Exp10.test(str5)) 128 | LogUtils.logInfo('JavaScript'.search(/a(.)a/)) 129 | 130 | --------------------------------------------------------------------------------