├── .gitignore ├── .vscode └── launch.json ├── README.md ├── leetcode ├── 1-two-sum.js ├── 10-regular-expression-matching.js ├── 100.相同的树.js ├── 101.对称二叉树.js ├── 104.二叉树的最大深度.js ├── 107.二叉树的层次遍历-ii.js ├── 108.将有序数组转换为二叉搜索树.js ├── 11-container-with-most-water.js ├── 110.平衡二叉树.js ├── 111.二叉树的最小深度.js ├── 112.路径总和.js ├── 118.杨辉三角.js ├── 119.杨辉三角-ii.js ├── 12-integer-to-roman.js ├── 121.买卖股票的最佳时机.js ├── 122.买卖股票的最佳时机-ii.js ├── 125.验证回文串.js ├── 13-roman-to-integer.js ├── 136.只出现一次的数字.js ├── 14-longest-common-prefix.js ├── 141.环形链表.js ├── 15-three-sum.js ├── 155.最小栈.js ├── 16-three-sum-closest.js ├── 160.相交链表.js ├── 167.两数之和-ii-输入有序数组.js ├── 168.excel表列名称.js ├── 169.求众数.js ├── 17-letter-combinations-of-a-phone-number.js ├── 171.excel表列序号.js ├── 172.阶乘后的零.js ├── 18-four-sum.js ├── 189.旋转数组.js ├── 19-remove-nth-node-from-end-of-list.js ├── 190.颠倒二进制位.js ├── 191.位-1-的个数.js ├── 198.打家劫舍.js ├── 2-add-two-numbers.js ├── 20-valid-parentheses.js ├── 21-merge-two-sorted-lists.js ├── 22-generate-parentheses.js ├── 23-merge-k-sorted-lists.js ├── 24-swap-nodes-in-pairs.js ├── 25-reverse-nodes-in-k-group.js ├── 26-remove-duplicates-from-sorted-array.js ├── 27-remove-element.js ├── 28-implement-str-str.js ├── 29-divide-two-integers.js ├── 30-substring-with-concatenation-of-all-words.js ├── 31.下一个排列.js ├── 32.最长有效括号.js ├── 33.搜索旋转排序数组.js ├── 34.在排序数组中查找元素的第一个和最后一个位置.js ├── 35.搜索插入位置.js ├── 36.有效的数独.js ├── 37.解数独.js ├── 38.外观数列.js ├── 38.报数.js ├── 4-find-median-sorted-arrays.js ├── 5-longest-palindrome.js ├── 53.最大子序和.js ├── 58.最后一个单词的长度.js ├── 6-zig-zag-conversion.js ├── 66.加一.js ├── 67.二进制求和.js ├── 69.x-的平方根.js ├── 7-reverse-integer.js ├── 70.爬楼梯.js ├── 8-string-to-integer-atoi.js ├── 83.删除排序链表中的重复元素.js ├── 846-hand-of-straights.js ├── 847-shortest-path-visiting-all-nodes.js ├── 848-shifting-letters.js ├── 853-car-fleet.js ├── 854-k-similar-strings.js ├── 856-score-of-parentheses.js ├── 88.合并两个有序数组.js ├── 9-palindrome-number.js └── top-interview-questions │ ├── array-and-strings │ ├── 3-longest-substring-without-repeating-characters.js │ ├── 334-increasing-triplet-subsequence.js │ ├── group-anagrams.js │ ├── longest-palindromic-substring.js │ ├── set-matrix-zeroes.js │ └── three-sum.js │ ├── dynamic-programming │ ├── coin-change.js │ ├── jump-game.js │ ├── longest-increasing-subsequence.js │ └── unique-paths.js │ ├── linked-list │ ├── add-two-numbers.js │ ├── intersection-of-two-linked-lists.js │ └── odd-even-list.js │ ├── math │ ├── divide-two-integers.js │ ├── excel-sheet-column-number.js │ ├── factorial-trailing-zeroes.js │ ├── fraction-to-recurring-decimal.js │ ├── happy-number.js │ ├── pow.js │ └── sqrt.js │ ├── others │ ├── evaluate-reverse-polish-notation.js │ ├── majority-element.js │ ├── sum-of-two-integers.js │ └── task-scheduler.js │ ├── sorting-and-searching │ ├── find-peak-element.js │ ├── sort-colors.js │ ├── the-kth-largest-elementIn-the-array.js │ └── top-k-frequent-elements.js │ └── trees-and-graphs │ ├── construct-binary-tree-from-preorder-and-inorder-traversal.js │ ├── inordertraversal.js │ └── populating-next-right-pointers-in-each-node.js ├── nowcoder ├── a-test-driven-js-assessment │ ├── alter-context.js │ ├── alter-objects.js │ ├── and.js │ ├── append.js │ ├── args-as-array.js │ ├── base10.js │ ├── call-it.js │ ├── capture-three-numbers.js │ ├── concat.js │ ├── contains-number.js │ ├── contains-repeating-letter.js │ ├── convert-to-binary.js │ ├── count.js │ ├── create-module.js │ ├── curry-it.js │ ├── curtail.js │ ├── duplicates.js │ ├── ends-with-vowel.js │ ├── find-all-occurrences.js │ ├── function-function.js │ ├── functions.js │ ├── globals.js │ ├── identity.js │ ├── indexOf.js │ ├── insert.js │ ├── is-usd.js │ ├── iterate.js │ ├── make-closures.js │ ├── matches-pattern.js │ ├── multiply.js │ ├── or.js │ ├── parse2Int.js │ ├── partial-using-arguments.js │ ├── partial.js │ ├── prepend.js │ ├── process-control.js │ ├── remove-without-copy.js │ ├── remove.js │ ├── speak.js │ ├── square.js │ ├── sum.js │ ├── timer.js │ ├── truncate.js │ ├── use-arguments.js │ └── value-at-bit.js ├── front-end-challenge │ ├── bind-this.js │ ├── common-parent-node.js │ ├── css-style2-dom-style.js │ ├── date-format.js │ ├── fibonacci.js │ ├── get-url-param.js │ ├── is-available-email.js │ ├── namespace.js │ ├── rgb2hex.js │ ├── str-length.js │ ├── string-count.js │ └── uniq.js └── jz-offer │ ├── a-stack-containing-the-min-function.js │ ├── add.js │ ├── binary-search-tree-and-doubly-linked-list.js │ ├── clockwise-print-matrix.js │ ├── clone-complex-chain.js │ ├── delete-duplication.js │ ├── duplicate.js │ ├── entry-node-of-loop.js │ ├── fibonacci.js │ ├── find-continuous-sequence.js │ ├── find-first-common-node.js │ ├── find-greatest-sum-of-sub-array.js │ ├── find-kth-to-tail.js │ ├── find-numbers-with-sum.js │ ├── find-nums-appear-once.js │ ├── find-path.js │ ├── find.js │ ├── first-appearing-once.js │ ├── first-not-repeating-char.js │ ├── format-date.js │ ├── get-least-numbers-solution.js │ ├── get-median-of-steam.js │ ├── get-next.js │ ├── get-number-of-k.js │ ├── get-ugly-number-solution.js │ ├── has-path.js │ ├── inverse-pairs.js │ ├── is-balanced-solution.js │ ├── is-continuous.js │ ├── is-numeric.js │ ├── is-symmetrical.js │ ├── jump-floor-2.js │ ├── jump-floor.js │ ├── k-th-node.js │ ├── last-remaining-solution.js │ ├── left-rotate-string.js │ ├── match.js │ ├── max-in-windows.js │ ├── merging-two-sorted-lists.js │ ├── more-than-half-num-solution.js │ ├── moving-count.js │ ├── multiply.js │ ├── number-of1-between1-and-n-solution.js │ ├── number-of1.js │ ├── permutation.js │ ├── power.js │ ├── print-binary-tree-from-top-to-bottom.js │ ├── print-list-from-tail-to-head.js │ ├── print-min-number.js │ ├── print-serial-line.js │ ├── print-with-z.js │ ├── re-construct-binary-tree.js │ ├── rect-cover.js │ ├── reorder-array.js │ ├── repeated-number-in-array.js │ ├── replace-space.js │ ├── reverse-list.js │ ├── reverse-sentence.js │ ├── serialize-and-deserialize-tree.js │ ├── stacks-and-queues.js │ ├── str-to-int.js │ ├── sum-solution.js │ ├── the-mirror-of-the-two-forked-tree.js │ ├── the-sequence-of-the-stack-push-and-pop.js │ ├── the-smallest-number-of-rotating-arrays.js │ ├── the-substructure-of-a-tree.js │ ├── tree-depth.js │ └── verify-squence-of-BST.js └── others ├── SAIMAWANG.js ├── TEST.js ├── array-remove-repeat-item.js ├── average-value-of-different-number-system.js ├── control.js ├── cvte1.js ├── cvte2.js ├── cvte3.js ├── jd1.js ├── jd2.js ├── lucky-number.js ├── maximum-mapping.js ├── paintCount.js ├── parsing-string-into-integer.js ├── purchase-order.js ├── render-array-to-tree.js ├── security-scheme.js ├── sf1.js ├── sf2.js ├── tenxun1.js ├── tenxun2.js ├── tenxun3.js ├── the-lucky-number-k.js ├── xunlei1.js └── xunlei2.js /.gitignore: -------------------------------------------------------------------------------- 1 | # debug 2 | .vscode/ -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // 使用 IntelliSense 了解相关属性。 3 | // 悬停以查看现有属性的描述。 4 | // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | 8 | { 9 | "type": "node", 10 | "request": "launch", 11 | "name": "启动程序", 12 | "program": "${workspaceFolder}\\leetcode\\198.打家劫舍.js" 13 | } 14 | ] 15 | } -------------------------------------------------------------------------------- /leetcode/1-two-sum.js: -------------------------------------------------------------------------------- 1 | // No.1 两数之和 2 | 3 | // 给定一个整数数组和一个目标值,找出数组中和为目标值的两个数。 4 | 5 | // 你可以假设每个输入只对应一种答案,且同样的元素不能被重复利用。 6 | 7 | // 示例: 8 | 9 | // 给定 nums = [2, 7, 11, 15], target = 9 10 | 11 | // 因为 nums[0] + nums[1] = 2 + 7 = 9 12 | // 所以返回 [0, 1] 13 | 14 | /** 15 | * @param {number[]} nums 16 | * @param {number} target 17 | * @return {number[]} 18 | */ 19 | var twoSum = function(nums, target) { 20 | let obj = {}; 21 | for (let i = 0, len = nums.length; i < len; i++) { 22 | let sub = target - nums[i]; 23 | if (obj[sub] != null) { 24 | return [obj[sub], i]; 25 | } 26 | obj[nums[i]] = i; 27 | } 28 | }; 29 | -------------------------------------------------------------------------------- /leetcode/100.相同的树.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=100 lang=javascript 3 | * 4 | * [100] 相同的树 5 | * 6 | * https://leetcode-cn.com/problems/same-tree/description/ 7 | * 8 | * algorithms 9 | * Easy (51.07%) 10 | * Total Accepted: 15.3K 11 | * Total Submissions: 29.8K 12 | * Testcase Example: '[1,2,3]\n[1,2,3]' 13 | * 14 | * 给定两个二叉树,编写一个函数来检验它们是否相同。 15 | * 16 | * 如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。 17 | * 18 | * 示例 1: 19 | * 20 | * 输入: 1 1 21 | * ⁠ / \ / \ 22 | * ⁠ 2 3 2 3 23 | * 24 | * ⁠ [1,2,3], [1,2,3] 25 | * 26 | * 输出: true 27 | * 28 | * 示例 2: 29 | * 30 | * 输入: 1 1 31 | * ⁠ / \ 32 | * ⁠ 2 2 33 | * 34 | * ⁠ [1,2], [1,null,2] 35 | * 36 | * 输出: false 37 | * 38 | * 39 | * 示例 3: 40 | * 41 | * 输入: 1 1 42 | * ⁠ / \ / \ 43 | * ⁠ 2 1 1 2 44 | * 45 | * ⁠ [1,2,1], [1,1,2] 46 | * 47 | * 输出: false 48 | * 49 | * 50 | */ 51 | /** 52 | * Definition for a binary tree node. 53 | * function TreeNode(val) { 54 | * this.val = val; 55 | * this.left = this.right = null; 56 | * } 57 | */ 58 | /** 59 | * @param {TreeNode} p 60 | * @param {TreeNode} q 61 | * @return {boolean} 62 | */ 63 | var isSameTree = function(p, q) { 64 | if (p === null || q === null) return p === q; 65 | if (p.val === q.val) 66 | return isSameTree(p.left, q.left) && isSameTree(p.right, q.right); 67 | return false; 68 | }; 69 | -------------------------------------------------------------------------------- /leetcode/104.二叉树的最大深度.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=104 lang=javascript 3 | * 4 | * [104] 二叉树的最大深度 5 | * 6 | * https://leetcode-cn.com/problems/maximum-depth-of-binary-tree/description/ 7 | * 8 | * algorithms 9 | * Easy (66.99%) 10 | * Total Accepted: 31.7K 11 | * Total Submissions: 47.1K 12 | * Testcase Example: '[3,9,20,null,null,15,7]' 13 | * 14 | * 给定一个二叉树,找出其最大深度。 15 | * 16 | * 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。 17 | * 18 | * 说明: 叶子节点是指没有子节点的节点。 19 | * 20 | * 示例: 21 | * 给定二叉树 [3,9,20,null,null,15,7], 22 | * 23 | * ⁠ 3 24 | * ⁠ / \ 25 | * ⁠ 9 20 26 | * ⁠ / \ 27 | * ⁠ 15 7 28 | * 29 | * 返回它的最大深度 3 。 30 | * 31 | */ 32 | /** 33 | * Definition for a binary tree node. 34 | * function TreeNode(val) { 35 | * this.val = val; 36 | * this.left = this.right = null; 37 | * } 38 | */ 39 | /** 40 | * @param {TreeNode} root 41 | * @return {number} 42 | */ 43 | var maxDepth = function(root) { 44 | if (!root) return 0; 45 | return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1; 46 | }; 47 | -------------------------------------------------------------------------------- /leetcode/108.将有序数组转换为二叉搜索树.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=108 lang=javascript 3 | * 4 | * [108] 将有序数组转换为二叉搜索树 5 | * 6 | * https://leetcode-cn.com/problems/convert-sorted-array-to-binary-search-tree/description/ 7 | * 8 | * algorithms 9 | * Easy (60.68%) 10 | * Total Accepted: 13.3K 11 | * Total Submissions: 21.8K 12 | * Testcase Example: '[-10,-3,0,5,9]' 13 | * 14 | * 将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树。 15 | * 16 | * 本题中,一个高度平衡二叉树是指一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1。 17 | * 18 | * 示例: 19 | * 20 | * 给定有序数组: [-10,-3,0,5,9], 21 | * 22 | * 一个可能的答案是:[0,-3,9,-10,null,5],它可以表示下面这个高度平衡二叉搜索树: 23 | * 24 | * ⁠ 0 25 | * ⁠ / \ 26 | * ⁠ -3 9 27 | * ⁠ / / 28 | * ⁠-10 5 29 | * 30 | * 31 | */ 32 | /** 33 | * Definition for a binary tree node. 34 | * function TreeNode(val) { 35 | * this.val = val; 36 | * this.left = this.right = null; 37 | * } 38 | */ 39 | /** 40 | * @param {number[]} nums 41 | * @return {TreeNode} 42 | */ 43 | var sortedArrayToBST = function(nums) { 44 | if (nums.length === 0) return null; 45 | let core = (nums, start, end) => { 46 | if (start > end) { 47 | return null; 48 | } 49 | let mid = start + ((end - start) >> 1); 50 | let node = new TreeNode(nums[mid]); 51 | node.left = core(nums, start, mid - 1); 52 | node.right = core(nums, mid + 1, end); 53 | return node; 54 | }; 55 | return core(nums, 0, nums.length - 1); 56 | }; 57 | 58 | // // test 59 | // function TreeNode(val) { 60 | // this.val = val; 61 | // this.left = this.right = null; 62 | // } 63 | // let arr = [-10, -3, 0, 5, 9]; 64 | // console.log(sortedArrayToBST(arr)); 65 | -------------------------------------------------------------------------------- /leetcode/11-container-with-most-water.js: -------------------------------------------------------------------------------- 1 | // No.11 盛最多水的容器 2 | 3 | // 给定 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) 。 4 | // 在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。 5 | // 找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。 6 | 7 | // 说明:你不能倾斜容器,且 n 的值至少为 2。 8 | 9 | // 8 #______________#______ 10 | // 7 #| # |# 11 | // 6 #| # # |# 12 | // 5 #| # # # |# 13 | // 4 #| # # # # |# 14 | // 3 #| # # # # # |# 15 | // 2 #| # # # # # # |# 16 | // 1 __#__#|__#__#__#__#__#__#__|#__________ 17 | 18 | // 图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下, 19 | // 容器能够容纳水(表示为虚线圈起部分)的最大值为 49。 20 | 21 | // 示例: 22 | 23 | // 输入: [1,8,6,2,5,4,8,3,7] 24 | // 输出: 49 25 | 26 | /** 27 | * @param {number[]} height 28 | * @return {number} 29 | */ 30 | var maxArea = function(height) { 31 | let [max, volume, l, r] = [0, 0, 0, height.length - 1]; 32 | while (l < r) { 33 | if (height[l] < height[r]) { 34 | volume = height[l] * (r - l); 35 | l++; 36 | } else { 37 | volume = height[r] * (r - l); 38 | r--; 39 | } 40 | max = max < volume ? volume : max; 41 | } 42 | return max; 43 | }; 44 | -------------------------------------------------------------------------------- /leetcode/110.平衡二叉树.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=110 lang=javascript 3 | * 4 | * [110] 平衡二叉树 5 | * 6 | * https://leetcode-cn.com/problems/balanced-binary-tree/description/ 7 | * 8 | * algorithms 9 | * Easy (46.22%) 10 | * Total Accepted: 11.1K 11 | * Total Submissions: 24K 12 | * Testcase Example: '[3,9,20,null,null,15,7]' 13 | * 14 | * 给定一个二叉树,判断它是否是高度平衡的二叉树。 15 | * 16 | * 本题中,一棵高度平衡二叉树定义为: 17 | * 18 | * 19 | * 一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过1。 20 | * 21 | * 22 | * 示例 1: 23 | * 24 | * 给定二叉树 [3,9,20,null,null,15,7] 25 | * 26 | * ⁠ 3 27 | * ⁠ / \ 28 | * ⁠ 9 20 29 | * ⁠ / \ 30 | * ⁠ 15 7 31 | * 32 | * 返回 true 。 33 | * 34 | * 示例 2: 35 | * 36 | * 给定二叉树 [1,2,2,3,3,null,null,4,4] 37 | * 38 | * ⁠ 1 39 | * ⁠ / \ 40 | * ⁠ 2 2 41 | * ⁠ / \ 42 | * ⁠ 3 3 43 | * ⁠ / \ 44 | * ⁠4 4 45 | * 46 | * 47 | * 返回 false 。 48 | * 49 | */ 50 | /** 51 | * Definition for a binary tree node. 52 | * function TreeNode(val) { 53 | * this.val = val; 54 | * this.left = this.right = null; 55 | * } 56 | */ 57 | /** 58 | * @param {TreeNode} root 59 | * @return {boolean} 60 | */ 61 | var isBalanced = function(root) { 62 | return check(root) >= 0; 63 | }; 64 | 65 | function check (root) { 66 | if (!root) return 1; 67 | let leftHeight = check(root.left); 68 | if (leftHeight === -1) return -1; 69 | let rightHeight = check(root.right); 70 | if (rightHeight === -1) return -1; 71 | if(Math.abs(leftHeight - rightHeight) > 1) return -1 72 | return (1 + Math.max(leftHeight, rightHeight)) 73 | } 74 | 75 | -------------------------------------------------------------------------------- /leetcode/111.二叉树的最小深度.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=111 lang=javascript 3 | * 4 | * [111] 二叉树的最小深度 5 | * 6 | * https://leetcode-cn.com/problems/minimum-depth-of-binary-tree/description/ 7 | * 8 | * algorithms 9 | * Easy (37.04%) 10 | * Total Accepted: 11.7K 11 | * Total Submissions: 31.6K 12 | * Testcase Example: '[3,9,20,null,null,15,7]' 13 | * 14 | * 给定一个二叉树,找出其最小深度。 15 | * 16 | * 最小深度是从根节点到最近叶子节点的最短路径上的节点数量。 17 | * 18 | * 说明: 叶子节点是指没有子节点的节点。 19 | * 20 | * 示例: 21 | * 22 | * 给定二叉树 [3,9,20,null,null,15,7], 23 | * 24 | * ⁠ 3 25 | * ⁠ / \ 26 | * ⁠ 9 20 27 | * ⁠ / \ 28 | * ⁠ 15 7 29 | * 30 | * 返回它的最小深度  2. 31 | * 32 | */ 33 | /** 34 | * Definition for a binary tree node. 35 | * function TreeNode(val) { 36 | * this.val = val; 37 | * this.left = this.right = null; 38 | * } 39 | */ 40 | /** 41 | * @param {TreeNode} root 42 | * @return {number} 43 | */ 44 | var minDepth = function(root) { 45 | if (!root) return 0; 46 | let [L, R] = [minDepth(root.left), minDepth(root.right)]; 47 | return 1 + (Math.min(L, R) || Math.max(L, R)); 48 | }; 49 | 50 | -------------------------------------------------------------------------------- /leetcode/112.路径总和.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=112 lang=javascript 3 | * 4 | * [112] 路径总和 5 | * 6 | * https://leetcode-cn.com/problems/path-sum/description/ 7 | * 8 | * algorithms 9 | * Easy (44.80%) 10 | * Total Accepted: 11.8K 11 | * Total Submissions: 26.3K 12 | * Testcase Example: '[5,4,8,11,null,13,4,7,2,null,null,null,1]\n22' 13 | * 14 | * 给定一个二叉树和一个目标和,判断该树中是否存在根节点到叶子节点的路径,这条路径上所有节点值相加等于目标和。 15 | * 16 | * 说明: 叶子节点是指没有子节点的节点。 17 | * 18 | * 示例: 19 | * 给定如下二叉树,以及目标和 sum = 22, 20 | * 21 | * ⁠ 5 22 | * ⁠ / \ 23 | * ⁠ 4 8 24 | * ⁠ / / \ 25 | * ⁠ 11 13 4 26 | * ⁠ / \ \ 27 | * ⁠ 7 2 1 28 | * 29 | * 30 | * 返回 true, 因为存在目标和为 22 的根节点到叶子节点的路径 5->4->11->2。 31 | * 32 | */ 33 | /** 34 | * Definition for a binary tree node. 35 | * function TreeNode(val) { 36 | * this.val = val; 37 | * this.left = this.right = null; 38 | * } 39 | */ 40 | /** 41 | * @param {TreeNode} root 42 | * @param {number} sum 43 | * @return {boolean} 44 | */ 45 | var hasPathSum = function(root, sum) { 46 | if (!root) return false; 47 | let sub = sum - root.val; 48 | if (!root.left && !root.right) return sub === 0; 49 | return hasPathSum(root.left, sub) || hasPathSum(root.right, sub); 50 | }; 51 | -------------------------------------------------------------------------------- /leetcode/118.杨辉三角.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=118 lang=javascript 3 | * 4 | * [118] 杨辉三角 5 | * 6 | * https://leetcode-cn.com/problems/pascals-triangle/description/ 7 | * 8 | * algorithms 9 | * Easy (59.90%) 10 | * Total Accepted: 17.4K 11 | * Total Submissions: 28.8K 12 | * Testcase Example: '5' 13 | * 14 | * 给定一个非负整数 numRows,生成杨辉三角的前 numRows 行。 15 | * 16 | * 17 | * 18 | * 在杨辉三角中,每个数是它左上方和右上方的数的和。 19 | * 20 | * 示例: 21 | * 22 | * 输入: 5 23 | * 输出: 24 | * [ 25 | * ⁠ [1], 26 | * ⁠ [1,1], 27 | * ⁠ [1,2,1], 28 | * ⁠ [1,3,3,1], 29 | * ⁠[1,4,6,4,1] 30 | * ] 31 | * 32 | */ 33 | /** 34 | * @param {number} numRows 35 | * @return {number[][]} 36 | */ 37 | var generate = function(numRows) { 38 | const res = []; 39 | for (let i = 0; i < numRows; i++) { 40 | res[i] = [1]; 41 | res[i - 1] && res[i - 1].reduce((pre, cur) => { 42 | res[i].push(pre + cur); 43 | return cur; 44 | }) && res[i].push(1); 45 | } 46 | return res; 47 | }; 48 | 49 | // console.log(generate(5)) 50 | -------------------------------------------------------------------------------- /leetcode/119.杨辉三角-ii.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=119 lang=javascript 3 | * 4 | * [119] 杨辉三角 II 5 | * 6 | * https://leetcode-cn.com/problems/pascals-triangle-ii/description/ 7 | * 8 | * algorithms 9 | * Easy (54.04%) 10 | * Total Accepted: 10.6K 11 | * Total Submissions: 19.7K 12 | * Testcase Example: '3' 13 | * 14 | * 给定一个非负索引 k,其中 k ≤ 33,返回杨辉三角的第 k 行。 15 | * 16 | * 17 | * 18 | * 在杨辉三角中,每个数是它左上方和右上方的数的和。 19 | * 20 | * 示例: 21 | * 22 | * 输入: 3 23 | * 输出: [1,3,3,1] 24 | * 25 | * 26 | * 进阶: 27 | * 28 | * 你可以优化你的算法到 O(k) 空间复杂度吗? 29 | * 30 | */ 31 | /** 32 | * @param {number} rowIndex 33 | * @return {number[]} 34 | */ 35 | var getRow = function(rowIndex) { 36 | const res = [1]; 37 | for (let i = 1; i < rowIndex + 1; i++) { 38 | for (let j = i; j > 0; j--) { 39 | !res[j] && (res[j] = 0); 40 | res[j] += res[j - 1]; 41 | } 42 | } 43 | return res; 44 | }; 45 | 46 | // console.log(getRow(3)); 47 | 48 | -------------------------------------------------------------------------------- /leetcode/121.买卖股票的最佳时机.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=121 lang=javascript 3 | * 4 | * [121] 买卖股票的最佳时机 5 | * 6 | * https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock/description/ 7 | * 8 | * algorithms 9 | * Easy (48.08%) 10 | * Total Accepted: 31.8K 11 | * Total Submissions: 65.6K 12 | * Testcase Example: '[7,1,5,3,6,4]' 13 | * 14 | * 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。 15 | * 16 | * 如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润。 17 | * 18 | * 注意你不能在买入股票前卖出股票。 19 | * 20 | * 示例 1: 21 | * 22 | * 输入: [7,1,5,3,6,4] 23 | * 输出: 5 24 | * 解释: 在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。 25 | * ⁠ 注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格。 26 | * 27 | * 28 | * 示例 2: 29 | * 30 | * 输入: [7,6,4,3,1] 31 | * 输出: 0 32 | * 解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。 33 | * 34 | * 35 | */ 36 | /** 37 | * @param {number[]} prices 38 | * @return {number} 39 | */ 40 | var maxProfit = function(prices) { 41 | let [dayProfit, profit] = [0, 0]; 42 | for (let i = 1, len = prices.length; i < len; i++) { 43 | dayProfit = Math.max(0, dayProfit += prices[i] - prices[i - 1]); 44 | profit = Math.max(dayProfit, profit); 45 | } 46 | return profit; 47 | }; 48 | 49 | -------------------------------------------------------------------------------- /leetcode/122.买卖股票的最佳时机-ii.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=122 lang=javascript 3 | * 4 | * [122] 买卖股票的最佳时机 II 5 | * 6 | * https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii/description/ 7 | * 8 | * algorithms 9 | * Easy (51.38%) 10 | * Total Accepted: 41.2K 11 | * Total Submissions: 79.9K 12 | * Testcase Example: '[7,1,5,3,6,4]' 13 | * 14 | * 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。 15 | * 16 | * 设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。 17 | * 18 | * 注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。 19 | * 20 | * 示例 1: 21 | * 22 | * 输入: [7,1,5,3,6,4] 23 | * 输出: 7 24 | * 解释: 在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。 25 | * 随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6-3 = 3 。 26 | * 27 | * 28 | * 示例 2: 29 | * 30 | * 输入: [1,2,3,4,5] 31 | * 输出: 4 32 | * 解释: 在第 1 天(股票价格 = 1)的时候买入,在第 5 天 (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 33 | * 。 34 | * 注意你不能在第 1 天和第 2 天接连购买股票,之后再将它们卖出。 35 | * 因为这样属于同时参与了多笔交易,你必须在再次购买前出售掉之前的股票。 36 | * 37 | * 38 | * 示例 3: 39 | * 40 | * 输入: [7,6,4,3,1] 41 | * 输出: 0 42 | * 解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。 43 | * 44 | */ 45 | /** 46 | * @param {number[]} prices 47 | * @return {number} 48 | */ 49 | var maxProfit = function(prices) { 50 | let profit = 0; 51 | for (let i = 1, len = prices.length; i < len; i++) { 52 | let dayProfit = prices[i] - prices[i - 1]; 53 | if (dayProfit > 0) { 54 | profit += dayProfit; 55 | } 56 | } 57 | return profit; 58 | }; 59 | 60 | -------------------------------------------------------------------------------- /leetcode/125.验证回文串.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=125 lang=javascript 3 | * 4 | * [125] 验证回文串 5 | * 6 | * https://leetcode-cn.com/problems/valid-palindrome/description/ 7 | * 8 | * algorithms 9 | * Easy (38.05%) 10 | * Total Accepted: 26K 11 | * Total Submissions: 67.9K 12 | * Testcase Example: '"A man, a plan, a canal: Panama"' 13 | * 14 | * 给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。 15 | * 16 | * 说明:本题中,我们将空字符串定义为有效的回文串。 17 | * 18 | * 示例 1: 19 | * 20 | * 输入: "A man, a plan, a canal: Panama" 21 | * 输出: true 22 | * 23 | * 24 | * 示例 2: 25 | * 26 | * 输入: "race a car" 27 | * 输出: false 28 | * 29 | * 30 | */ 31 | /** 32 | * @param {string} s 33 | * @return {boolean} 34 | */ 35 | var isPalindrome = function(s) { 36 | if (!s.length) return true; 37 | let str = s.toLocaleLowerCase(); 38 | let [left, right] = [0, str.length - 1]; 39 | let [lChar, rChar] = [ str[left], str[right]]; 40 | let reg = /[a-zA-Z0-9]/; 41 | while (left < right) { 42 | while (left < right && !reg.test(lChar)) { 43 | lChar = str[++left]; 44 | } 45 | while (left < right && !reg.test(rChar)) { 46 | rChar = str[--right]; 47 | } 48 | if (left < right && lChar !== rChar) { 49 | return false; 50 | } 51 | lChar = str[++left]; 52 | rChar = str[--right]; 53 | } 54 | return true; 55 | }; 56 | 57 | console.log(isPalindrome("race a car")); 58 | -------------------------------------------------------------------------------- /leetcode/136.只出现一次的数字.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=136 lang=javascript 3 | * 4 | * [136] 只出现一次的数字 5 | * 6 | * https://leetcode-cn.com/problems/single-number/description/ 7 | * 8 | * algorithms 9 | * Easy (58.15%) 10 | * Total Accepted: 48.7K 11 | * Total Submissions: 82.2K 12 | * Testcase Example: '[2,2,1]' 13 | * 14 | * 给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。 15 | * 16 | * 说明: 17 | * 18 | * 你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗? 19 | * 20 | * 示例 1: 21 | * 22 | * 输入: [2,2,1] 23 | * 输出: 1 24 | * 25 | * 26 | * 示例 2: 27 | * 28 | * 输入: [4,1,2,1,2] 29 | * 输出: 4 30 | * 31 | */ 32 | /** 33 | * @param {number[]} nums 34 | * @return {number} 35 | */ 36 | var singleNumber = function(nums) { 37 | return nums.reduce((pre, cur) => pre ^ cur, false); 38 | }; 39 | 40 | -------------------------------------------------------------------------------- /leetcode/14-longest-common-prefix.js: -------------------------------------------------------------------------------- 1 | // No.14 最长公共前缀 2 | 3 | // 编写一个函数来查找字符串数组中的最长公共前缀。 4 | 5 | // 如果不存在公共前缀,返回空字符串 ""。 6 | 7 | // 示例 1: 8 | 9 | // 输入: ["flower","flow","flight"] 10 | // 输出: "fl" 11 | // 示例 2: 12 | 13 | // 输入: ["dog","racecar","car"] 14 | // 输出: "" 15 | // 解释: 输入不存在公共前缀。 16 | // 说明: 17 | 18 | // 所有输入只包含小写字母 a-z 。 19 | 20 | /** 21 | * @param {string[]} strs 22 | * @return {string} 23 | */ 24 | var longestCommonPrefix = function(strs) { 25 | if (strs.length == 0) return ''; 26 | let compare = (str1, str2) => { 27 | let same = ''; 28 | for (let i = 0, len = str1.length; i < len; i++) { 29 | if (str1[i] === str2[i]) { 30 | same += str1[i]; 31 | } else { 32 | break; 33 | } 34 | } 35 | return same; 36 | }; 37 | let res = strs[0]; 38 | for (let i = 1, len = strs.length; i < len; i++) { 39 | if (res.length > 0) { 40 | res = compare(res, strs[i]); 41 | } else { 42 | break; 43 | } 44 | } 45 | return res; 46 | }; 47 | 48 | console.log(longestCommonPrefix(["flower","flow","flight"])) 49 | -------------------------------------------------------------------------------- /leetcode/15-three-sum.js: -------------------------------------------------------------------------------- 1 | // No.15 三数之和 2 | 3 | // 给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。 4 | 5 | // 注意:答案中不可以包含重复的三元组。 6 | 7 | // 例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4], 8 | 9 | // 满足要求的三元组集合为: 10 | // [ 11 | // [-1, 0, 1], 12 | // [-1, -1, 2] 13 | // ] 14 | 15 | /** 16 | * @param {number[]} nums 17 | * @return {number[][]} 18 | */ 19 | var threeSum = function(nums) { 20 | if (nums.length < 3) return []; 21 | nums.sort((a, b) => a - b); 22 | let res = []; 23 | let len = nums.length; 24 | for (let i = 0, l = len - 2; i < l; i++) { 25 | if (i == 0 || (i > 0 && nums[i] != nums[i - 1])) { 26 | let lo = i + 1, 27 | hi = len - 1, 28 | sum = 0 - nums[i]; 29 | while (lo < hi) { 30 | if (nums[lo] + nums[hi] == sum) { 31 | res.push([nums[i], nums[lo], nums[hi]]); 32 | while (lo < hi && nums[lo] == nums[lo + 1]) lo++; 33 | while (lo < hi && nums[hi] == nums[hi - 1]) hi--; 34 | lo++; 35 | hi--; 36 | } else if (nums[lo] + nums[hi] < sum) lo++; 37 | else hi--; 38 | } 39 | } 40 | } 41 | return res; 42 | }; 43 | 44 | console.log(threeSum([-1, 0, 1, 2, -1, -4])); 45 | -------------------------------------------------------------------------------- /leetcode/16-three-sum-closest.js: -------------------------------------------------------------------------------- 1 | // No.16 最接近的三数之和 2 | 3 | // 给定一个包括 n 个整数的数组 nums 和 一个目标值 target。 4 | // 找出 nums 中的三个整数,使得它们的和与 target 最接近。 5 | // 返回这三个数的和。假定每组输入只存在唯一答案。 6 | 7 | // 例如,给定数组 nums = [-1,2,1,-4], 和 target = 1. 8 | 9 | // 与 target 最接近的三个数的和为 2. (-1 + 2 + 1 = 2). 10 | 11 | /** 12 | * @param {number[]} nums 13 | * @param {number} target 14 | * @return {number} 15 | */ 16 | var threeSumClosest = function(nums, target) { 17 | nums.sort((a, b) => a - b); 18 | let len = nums.length; 19 | let sum = nums[0] + nums[1] + nums[len - 1]; 20 | let diff = Math.abs(target - sum) 21 | for (let i = len - 1; i > 0; i--) { 22 | let [l, r] = [0, i - 1] 23 | while (l < r) { 24 | let newSum = nums[l] + nums[r] + nums[i]; 25 | if (newSum == target) return newSum; 26 | let newDiff = Math.abs(target - newSum); 27 | newSum < target ? ++l : --r; 28 | if (newDiff < diff) { 29 | diff = newDiff; 30 | sum = newSum; 31 | } 32 | } 33 | } 34 | return sum; 35 | }; 36 | 37 | console.log(threeSumClosest([1,2,4,8,16,32,64,128], 82)) 38 | -------------------------------------------------------------------------------- /leetcode/167.两数之和-ii-输入有序数组.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=167 lang=javascript 3 | * 4 | * [167] 两数之和 II - 输入有序数组 5 | * 6 | * https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted/description/ 7 | * 8 | * algorithms 9 | * Easy (47.06%) 10 | * Total Accepted: 18.2K 11 | * Total Submissions: 37.9K 12 | * Testcase Example: '[2,7,11,15]\n9' 13 | * 14 | * 给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数。 15 | * 16 | * 函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2。 17 | * 18 | * 说明: 19 | * 20 | * 21 | * 返回的下标值(index1 和 index2)不是从零开始的。 22 | * 你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。 23 | * 24 | * 25 | * 示例: 26 | * 27 | * 输入: numbers = [2, 7, 11, 15], target = 9 28 | * 输出: [1,2] 29 | * 解释: 2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。 30 | * 31 | */ 32 | /** 33 | * @param {number[]} numbers 34 | * @param {number} target 35 | * @return {number[]} 36 | */ 37 | var twoSum = function(numbers, target) { 38 | let [index1, index2] = [0, numbers.length - 1]; 39 | while (index1, index2) { 40 | let sum = numbers[index1] + numbers[index2]; 41 | if (sum < target) { 42 | index1++; 43 | } else if (sum > target) { 44 | index2--; 45 | } else { 46 | return [index1 + 1, index2 + 1]; 47 | } 48 | } 49 | }; 50 | 51 | -------------------------------------------------------------------------------- /leetcode/168.excel表列名称.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=168 lang=javascript 3 | * 4 | * [168] Excel表列名称 5 | * 6 | * https://leetcode-cn.com/problems/excel-sheet-column-title/description/ 7 | * 8 | * algorithms 9 | * Easy (29.94%) 10 | * Total Accepted: 5.7K 11 | * Total Submissions: 18.9K 12 | * Testcase Example: '1' 13 | * 14 | * 给定一个正整数,返回它在 Excel 表中相对应的列名称。 15 | * 16 | * 例如, 17 | * 18 | * ⁠ 1 -> A 19 | * ⁠ 2 -> B 20 | * ⁠ 3 -> C 21 | * ⁠ ... 22 | * ⁠ 26 -> Z 23 | * ⁠ 27 -> AA 24 | * ⁠ 28 -> AB 25 | * ⁠ ... 26 | * 27 | * 28 | * 示例 1: 29 | * 30 | * 输入: 1 31 | * 输出: "A" 32 | * 33 | * 34 | * 示例 2: 35 | * 36 | * 输入: 28 37 | * 输出: "AB" 38 | * 39 | * 40 | * 示例 3: 41 | * 42 | * 输入: 701 43 | * 输出: "ZY" 44 | * 45 | * 46 | */ 47 | /** 48 | * @param {number} n 49 | * @return {string} 50 | */ 51 | var convertToTitle = function(n) { 52 | if (n === 0) return ''; 53 | return convertToTitle(~~(--n / 26)) + String.fromCharCode(n % 26 + 65); 54 | }; 55 | -------------------------------------------------------------------------------- /leetcode/169.求众数.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=169 lang=javascript 3 | * 4 | * [169] 求众数 5 | * 6 | * https://leetcode-cn.com/problems/majority-element/description/ 7 | * 8 | * algorithms 9 | * Easy (57.17%) 10 | * Total Accepted: 27.4K 11 | * Total Submissions: 47.1K 12 | * Testcase Example: '[3,2,3]' 13 | * 14 | * 给定一个大小为 n 的数组,找到其中的众数。众数是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。 15 | * 16 | * 你可以假设数组是非空的,并且给定的数组总是存在众数。 17 | * 18 | * 示例 1: 19 | * 20 | * 输入: [3,2,3] 21 | * 输出: 3 22 | * 23 | * 示例 2: 24 | * 25 | * 输入: [2,2,1,1,1,2,2] 26 | * 输出: 2 27 | * 28 | * 29 | */ 30 | /** 31 | * @param {number[]} nums 32 | * @return {number} 33 | */ 34 | var majorityElement = function(nums) { 35 | let major, count = 0; 36 | nums.forEach((val) => { 37 | if (count == 0) { 38 | major = val; 39 | count++; 40 | } else if (major === val) { 41 | count++ 42 | } else { 43 | count--; 44 | } 45 | }); 46 | return major; 47 | }; 48 | 49 | console.log(majorityElement([3, 2, 3])) 50 | 51 | -------------------------------------------------------------------------------- /leetcode/17-letter-combinations-of-a-phone-number.js: -------------------------------------------------------------------------------- 1 | // No.17 电话号码的字母组合 2 | 3 | // 给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。 4 | 5 | // 给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。 6 | 7 | // 2:abc 8 | // 3: def 9 | // 4: ghi 10 | // 5: jkl 11 | // 6: mno 12 | // 7: pqrs 13 | // 8: tuv 14 | // 9: wxyz 15 | 16 | // 示例: 17 | 18 | // 输入:"23" 19 | // 输出:["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"]. 20 | // 说明: 21 | // 尽管上面的答案是按字典序排列的,但是你可以任意选择答案输出的顺序。 22 | 23 | /** 24 | * @param {string} digits 25 | * @return {string[]} 26 | */ 27 | var letterCombinations = function(digits) { 28 | if (digits.length < 1) return []; 29 | let maps = ['0', '1', "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"]; 30 | let res = []; 31 | let dfs = (list, str, i, digits, maps, digitsLen) => { 32 | if (i == digitsLen) { 33 | list.push(str); 34 | return; 35 | } 36 | let s = maps[Number(digits[i])]; 37 | for (let j = 0, len = s.length; j < len; j++) { 38 | dfs(list, str + s[j], i+1, digits, maps, digitsLen); 39 | } 40 | } 41 | dfs(res, '', 0, digits, maps, digits.length); 42 | return res; 43 | }; 44 | 45 | console.log(letterCombinations('22')) -------------------------------------------------------------------------------- /leetcode/171.excel表列序号.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=171 lang=javascript 3 | * 4 | * [171] Excel表列序号 5 | * 6 | * https://leetcode-cn.com/problems/excel-sheet-column-number/description/ 7 | * 8 | * algorithms 9 | * Easy (63.21%) 10 | * Total Accepted: 10K 11 | * Total Submissions: 15.9K 12 | * Testcase Example: '"A"' 13 | * 14 | * 给定一个Excel表格中的列名称,返回其相应的列序号。 15 | * 16 | * 例如, 17 | * 18 | * ⁠ A -> 1 19 | * ⁠ B -> 2 20 | * ⁠ C -> 3 21 | * ⁠ ... 22 | * ⁠ Z -> 26 23 | * ⁠ AA -> 27 24 | * ⁠ AB -> 28 25 | * ⁠ ... 26 | * 27 | * 28 | * 示例 1: 29 | * 30 | * 输入: "A" 31 | * 输出: 1 32 | * 33 | * 34 | * 示例 2: 35 | * 36 | * 输入: "AB" 37 | * 输出: 28 38 | * 39 | * 40 | * 示例 3: 41 | * 42 | * 输入: "ZY" 43 | * 输出: 701 44 | * 45 | * 致谢: 46 | * 特别感谢 @ts 添加此问题并创建所有测试用例。 47 | * 48 | */ 49 | /** 50 | * @param {string} s 51 | * @return {number} 52 | */ 53 | var titleToNumber = function(s) { 54 | let num = 0; 55 | for (let i = 0, len = s.length; i < len; i++) { 56 | num *= 26; 57 | num += s.charCodeAt(i) - 64; 58 | } 59 | return num; 60 | }; 61 | 62 | -------------------------------------------------------------------------------- /leetcode/172.阶乘后的零.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=172 lang=javascript 3 | * 4 | * [172] 阶乘后的零 5 | * 6 | * https://leetcode-cn.com/problems/factorial-trailing-zeroes/description/ 7 | * 8 | * algorithms 9 | * Easy (36.93%) 10 | * Total Accepted: 8.7K 11 | * Total Submissions: 23.4K 12 | * Testcase Example: '3' 13 | * 14 | * 给定一个整数 n,返回 n! 结果尾数中零的数量。 15 | * 16 | * 示例 1: 17 | * 18 | * 输入: 3 19 | * 输出: 0 20 | * 解释: 3! = 6, 尾数中没有零。 21 | * 22 | * 示例 2: 23 | * 24 | * 输入: 5 25 | * 输出: 1 26 | * 解释: 5! = 120, 尾数中有 1 个零. 27 | * 28 | * 说明: 你算法的时间复杂度应为 O(log n) 。 29 | * 30 | */ 31 | /** 32 | * @param {number} n 33 | * @return {number} 34 | */ 35 | var trailingZeroes = function(n) { 36 | 37 | }; 38 | 39 | -------------------------------------------------------------------------------- /leetcode/189.旋转数组.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=189 lang=javascript 3 | * 4 | * [189] 旋转数组 5 | * 6 | * https://leetcode-cn.com/problems/rotate-array/description/ 7 | * 8 | * algorithms 9 | * Easy (36.18%) 10 | * Total Accepted: 39.5K 11 | * Total Submissions: 107.4K 12 | * Testcase Example: '[1,2,3,4,5,6,7]\n3' 13 | * 14 | * 给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。 15 | * 16 | * 示例 1: 17 | * 18 | * 输入: [1,2,3,4,5,6,7] 和 k = 3 19 | * 输出: [5,6,7,1,2,3,4] 20 | * 解释: 21 | * 向右旋转 1 步: [7,1,2,3,4,5,6] 22 | * 向右旋转 2 步: [6,7,1,2,3,4,5] 23 | * 向右旋转 3 步: [5,6,7,1,2,3,4] 24 | * 25 | * 26 | * 示例 2: 27 | * 28 | * 输入: [-1,-100,3,99] 和 k = 2 29 | * 输出: [3,99,-1,-100] 30 | * 解释: 31 | * 向右旋转 1 步: [99,-1,-100,3] 32 | * 向右旋转 2 步: [3,99,-1,-100] 33 | * 34 | * 说明: 35 | * 36 | * 37 | * 尽可能想出更多的解决方案,至少有三种不同的方法可以解决这个问题。 38 | * 要求使用空间复杂度为 O(1) 的原地算法。 39 | * 40 | * 41 | */ 42 | /** 43 | * @param {number[]} nums 44 | * @param {number} k 45 | * @return {void} Do not return anything, modify nums in-place instead. 46 | */ 47 | var rotate = function(nums, k) { 48 | // while (k--) { 49 | // nums.unshift(nums.pop()); 50 | // } 51 | nums.splice(0, 0, ...nums.splice(-k % nums.length)); 52 | }; 53 | 54 | -------------------------------------------------------------------------------- /leetcode/19-remove-nth-node-from-end-of-list.js: -------------------------------------------------------------------------------- 1 | // No.19 删除链表的倒数第N个节点 2 | 3 | // 给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。 4 | 5 | // 示例: 6 | 7 | // 给定一个链表: 1->2->3->4->5, 和 n = 2. 8 | 9 | // 当删除了倒数第二个节点后,链表变为 1->2->3->5. 10 | // 说明: 11 | 12 | // 给定的 n 保证是有效的。 13 | 14 | // 进阶: 15 | 16 | // 你能尝试使用一趟扫描实现吗? 17 | 18 | /** 19 | * Definition for singly-linked list. 20 | * function ListNode(val) { 21 | * this.val = val; 22 | * this.next = null; 23 | * } 24 | */ 25 | /** 26 | * @param {ListNode} head 27 | * @param {number} n 28 | * @return {ListNode} 29 | */ 30 | var removeNthFromEnd = function(head, n) { 31 | let res = new ListNode(-1); 32 | res.next = head; 33 | let a = res; 34 | let b = head; 35 | while (n--) { 36 | if (b == null) return false; 37 | b = b.next; 38 | } 39 | while (b) { 40 | b = b.next; 41 | a = a.next; 42 | } 43 | a.next = a.next.next; 44 | return res.next 45 | }; 46 | 47 | function ListNode(val) { 48 | this.val = val; 49 | this.next = null; 50 | } 51 | 52 | let h = new ListNode(1); 53 | // h.next = new ListNode(2); 54 | 55 | console.log(removeNthFromEnd(h, 1)); 56 | -------------------------------------------------------------------------------- /leetcode/190.颠倒二进制位.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=190 lang=javascript 3 | * 4 | * [190] 颠倒二进制位 5 | * 6 | * https://leetcode-cn.com/problems/reverse-bits/description/ 7 | * 8 | * algorithms 9 | * Easy (34.92%) 10 | * Total Accepted: 9.8K 11 | * Total Submissions: 26.9K 12 | * Testcase Example: '00000010100101000001111010011100' 13 | * 14 | * 颠倒给定的 32 位无符号整数的二进制位。 15 | * 16 | * 17 | * 18 | * 示例 1: 19 | * 20 | * 输入: 00000010100101000001111010011100 21 | * 输出: 00111001011110000010100101000000 22 | * 解释: 输入的二进制串 00000010100101000001111010011100 表示无符号整数 43261596, 23 | * ⁠ 因此返回 964176192,其二进制表示形式为 00111001011110000010100101000000。 24 | * 25 | * 示例 2: 26 | * 27 | * 输入:11111111111111111111111111111101 28 | * 输出:10111111111111111111111111111111 29 | * 解释:输入的二进制串 11111111111111111111111111111101 表示无符号整数 4294967293, 30 | * 因此返回 3221225471 其二进制表示形式为 10101111110010110010011101101001。 31 | * 32 | * 33 | * 34 | * 提示: 35 | * 36 | * 37 | * 请注意,在某些语言(如 38 | * Java)中,没有无符号整数类型。在这种情况下,输入和输出都将被指定为有符号整数类型,并且不应影响您的实现,因为无论整数是有符号的还是无符号的,其内部的二进制表示形式都是相同的。 39 | * 在 Java 中,编译器使用二进制补码记法来表示有符号整数。因此,在上面的 示例 2 中,输入表示有符号整数 -3,输出表示有符号整数 40 | * -1073741825。 41 | * 42 | * 43 | * 44 | * 45 | * 进阶: 46 | * 如果多次调用这个函数,你将如何优化你的算法? 47 | * 48 | */ 49 | /** 50 | * @param {number} n - a positive integer 51 | * @return {number} - a positive integer 52 | */ 53 | var reverseBits = function(n) { 54 | return parseInt((n.toString(2).split('').reverse().join('') + '00000000000000000000000000000000').substr(0, 32), 2) 55 | }; 56 | 57 | console.log(reverseBits(0b11111111)) 58 | 59 | -------------------------------------------------------------------------------- /leetcode/191.位-1-的个数.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=191 lang=javascript 3 | * 4 | * [191] 位1的个数 5 | * 6 | * https://leetcode-cn.com/problems/number-of-1-bits/description/ 7 | * 8 | * algorithms 9 | * Easy (47.14%) 10 | * Total Accepted: 14.7K 11 | * Total Submissions: 30.3K 12 | * Testcase Example: '00000000000000000000000000001011' 13 | * 14 | * 编写一个函数,输入是一个无符号整数,返回其二进制表达式中数字位数为 ‘1’ 的个数(也被称为汉明重量)。 15 | * 16 | * 17 | * 18 | * 示例 1: 19 | * 20 | * 输入:00000000000000000000000000001011 21 | * 输出:3 22 | * 解释:输入的二进制串 00000000000000000000000000001011 中,共有三位为 '1'。 23 | * 24 | * 25 | * 示例 2: 26 | * 27 | * 输入:00000000000000000000000010000000 28 | * 输出:1 29 | * 解释:输入的二进制串 00000000000000000000000010000000 中,共有一位为 '1'。 30 | * 31 | * 32 | * 示例 3: 33 | * 34 | * 输入:11111111111111111111111111111101 35 | * 输出:31 36 | * 解释:输入的二进制串 11111111111111111111111111111101 中,共有 31 位为 '1'。 37 | * 38 | * 39 | * 40 | * 提示: 41 | * 42 | * 43 | * 请注意,在某些语言(如 44 | * Java)中,没有无符号整数类型。在这种情况下,输入和输出都将被指定为有符号整数类型,并且不应影响您的实现,因为无论整数是有符号的还是无符号的,其内部的二进制表示形式都是相同的。 45 | * 在 Java 中,编译器使用二进制补码记法来表示有符号整数。因此,在上面的 示例 3 中,输入表示有符号整数 -3。 46 | * 47 | * 48 | * 49 | * 50 | * 进阶: 51 | * 如果多次调用这个函数,你将如何优化你的算法? 52 | * 53 | */ 54 | /** 55 | * @param {number} n - a positive integer 56 | * @return {number} 57 | */ 58 | var hammingWeight = function(n) { 59 | let res = 0; 60 | while (n > 0) { 61 | n & 1 && res++; 62 | n >>>= 1; 63 | } 64 | return res; 65 | }; 66 | 67 | -------------------------------------------------------------------------------- /leetcode/198.打家劫舍.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=198 lang=javascript 3 | * 4 | * [198] 打家劫舍 5 | * 6 | * https://leetcode-cn.com/problems/house-robber/description/ 7 | * 8 | * algorithms 9 | * Easy (39.18%) 10 | * Total Accepted: 18.3K 11 | * Total Submissions: 46.4K 12 | * Testcase Example: '[1,2,3,1]' 13 | * 14 | * 15 | * 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。 16 | * 17 | * 给定一个代表每个房屋存放金额的非负整数数组,计算你在不触动警报装置的情况下,能够偷窃到的最高金额。 18 | * 19 | * 示例 1: 20 | * 21 | * 输入: [1,2,3,1] 22 | * 输出: 4 23 | * 解释: 偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。 24 | * 偷窃到的最高金额 = 1 + 3 = 4 。 25 | * 26 | * 示例 2: 27 | * 28 | * 输入: [2,7,9,3,1] 29 | * 输出: 12 30 | * 解释: 偷窃 1 号房屋 (金额 = 2), 偷窃 3 号房屋 (金额 = 9),接着偷窃 5 号房屋 (金额 = 1)。 31 | * 偷窃到的最高金额 = 2 + 9 + 1 = 12 。 32 | * 33 | * 34 | */ 35 | /** 36 | * @param {number[]} nums 37 | * @return {number} 38 | */ 39 | var rob = function(nums) { 40 | return nums.reduce( 41 | function(p, n) { 42 | return [p[1], Math.max(p[0] + n, p[1])]; 43 | }, 44 | [0, 0] 45 | )[1]; 46 | }; 47 | 48 | console.log(rob([1, 2, 3, 1])); 49 | -------------------------------------------------------------------------------- /leetcode/2-add-two-numbers.js: -------------------------------------------------------------------------------- 1 | // No.2 两数相加 2 | 3 | // 给定两个非空链表来表示两个非负整数。位数按照逆序方式存储,它们的每个节点只存储单个数字。将两数相加返回一个新的链表。 4 | 5 | // 你可以假设除了数字 0 之外,这两个数字都不会以零开头。 6 | 7 | // 示例: 8 | 9 | // 输入:(2 -> 4 -> 3) + (5 -> 6 -> 4) 10 | // 输出:7 -> 0 -> 8 11 | // 原因:342 + 465 = 807 12 | 13 | /** 14 | * Definition for singly-linked list. 15 | * function ListNode(val) { 16 | * this.val = val; 17 | * this.next = null; 18 | * } 19 | */ 20 | /** 21 | * @param {ListNode} l1 22 | * @param {ListNode} l2 23 | * @return {ListNode} 24 | */ 25 | var addTwoNumbers = function(l1, l2) { 26 | let res = new ListNode(-1); 27 | let node = res; 28 | let carry = 0; 29 | while (l1 || l2 || carry) { 30 | let val = (l1 ? l1.val : 0) + (l2 ? l2.val : 0) + carry; 31 | carry = Math.floor(val / 10); 32 | node.next = new ListNode((val % 10)); 33 | node = node.next; 34 | l1 = l1 && l1.next; 35 | l2 = l2 && l2.next; 36 | } 37 | return res.next; 38 | }; 39 | 40 | function ListNode(val) { 41 | this.val = val; 42 | this.next = null; 43 | } 44 | 45 | let a = new ListNode(1); 46 | 47 | let b = new ListNode(9); 48 | b.next = new ListNode(9); 49 | 50 | console.log(addTwoNumbers(a, b)); 51 | -------------------------------------------------------------------------------- /leetcode/20-valid-parentheses.js: -------------------------------------------------------------------------------- 1 | // No.20 有效的括号 2 | 3 | // 给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。 4 | 5 | // 有效字符串需满足: 6 | 7 | // 左括号必须用相同类型的右括号闭合。 8 | // 左括号必须以正确的顺序闭合。 9 | // 注意空字符串可被认为是有效字符串。 10 | 11 | // 示例 1: 12 | 13 | // 输入: "()" 14 | // 输出: true 15 | // 示例 2: 16 | 17 | // 输入: "()[]{}" 18 | // 输出: true 19 | // 示例 3: 20 | 21 | // 输入: "(]" 22 | // 输出: false 23 | // 示例 4: 24 | 25 | // 输入: "([)]" 26 | // 输出: false 27 | // 示例 5: 28 | 29 | // 输入: "{[]}" 30 | // 输出: true 31 | 32 | /** 33 | * @param {string} s 34 | * @return {boolean} 35 | */ 36 | var isValid = function(s) { 37 | let stack = []; 38 | for (let i = 0, len = s.length; i < len; i++) { 39 | let char = s[i]; 40 | if (char == "(" || char == "[" || char == "{") { 41 | stack.push(char); 42 | } else { 43 | let cur = stack.pop(); 44 | if ( 45 | (char == ")" && cur == "(") || 46 | (char == "]" && cur == "[") || 47 | (char == "}" && cur == "{") 48 | ) { 49 | continue; 50 | } else { 51 | return false; 52 | } 53 | } 54 | } 55 | return !stack.length; 56 | }; 57 | -------------------------------------------------------------------------------- /leetcode/21-merge-two-sorted-lists.js: -------------------------------------------------------------------------------- 1 | // No.21 合并两个有序链表 2 | 3 | // 将两个有序链表合并为一个新的有序链表并返回。 4 | // 新链表是通过拼接给定的两个链表的所有节点组成的。 5 | 6 | // 示例: 7 | 8 | // 输入:1->2->4, 1->3->4 9 | // 输出:1->1->2->3->4->4 10 | 11 | /** 12 | * Definition for singly-linked list. 13 | * function ListNode(val) { 14 | * this.val = val; 15 | * this.next = null; 16 | * } 17 | */ 18 | /** 19 | * @param {ListNode} l1 20 | * @param {ListNode} l2 21 | * @return {ListNode} 22 | */ 23 | var mergeTwoLists = function(l1, l2) { 24 | let ret = new ListNode(-1); 25 | let p = ret; 26 | while (l1 && l2) { 27 | if (l1.val < l2.val) { 28 | p.next = new ListNode(l1.val); 29 | l1 = l1.next; 30 | } else { 31 | p.next = new ListNode(l2.val); 32 | l2 = l2.next; 33 | } 34 | p = p.next; 35 | } 36 | l1 && (p.next = l1); 37 | l2 && (p.next = l2); 38 | return ret.next; 39 | }; -------------------------------------------------------------------------------- /leetcode/22-generate-parentheses.js: -------------------------------------------------------------------------------- 1 | // No.22 括号生成 2 | 3 | // 给出 n 代表生成括号的对数,请你写出一个函数,使其能够生成所有可能的并且有效的括号组合。 4 | 5 | // 例如,给出 n = 3,生成结果为: 6 | 7 | // [ 8 | // "((()))", 9 | // "(()())", 10 | // "(())()", 11 | // "()(())", 12 | // "()()()" 13 | // ] 14 | 15 | /** 16 | * @param {number} n 17 | * @return {string[]} 18 | */ 19 | var generateParenthesis = function(n) { 20 | let ret = []; 21 | let core = (list, str, lCount, rCount, n) => { 22 | if (str.length == n * 2) { 23 | list.push(str); 24 | return; 25 | } 26 | lCount < n && core(list, str + '(', lCount + 1, rCount, n); 27 | rCount < lCount && core(list, str + ')', lCount, rCount + 1, n); 28 | } 29 | core(ret, '', 0, 0, n); 30 | return ret; 31 | }; -------------------------------------------------------------------------------- /leetcode/23-merge-k-sorted-lists.js: -------------------------------------------------------------------------------- 1 | // No.23 合并K个排序链表 2 | 3 | // 合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。 4 | 5 | // 示例: 6 | 7 | // 输入: 8 | // [ 9 | // 1->4->5, 10 | // 1->3->4, 11 | // 2->6 12 | // ] 13 | // 输出: 1->1->2->3->4->4->5->6 14 | 15 | /** 16 | * Definition for singly-linked list. 17 | * function ListNode(val) { 18 | * this.val = val; 19 | * this.next = null; 20 | * } 21 | */ 22 | /** 23 | * @param {ListNode[]} lists 24 | * @return {ListNode} 25 | */ 26 | var mergeKLists = function(lists) { 27 | if (lists.length == 0) { 28 | return null 29 | }; 30 | let mergeList = (l1, l2) => { 31 | if (l1 == null) return l2; 32 | if (l2 == null) return l1; 33 | let l = new ListNode(-1); 34 | let p = l; 35 | while (l1 && l2) { 36 | if (l1.val > l2.val) { 37 | p.next = new ListNode(l2.val); 38 | p = p.next; 39 | l2 = l2.next; 40 | } else { 41 | p.next = new ListNode(l1.val); 42 | p = p.next; 43 | l1 = l1.next; 44 | } 45 | } 46 | if (l1) p.next = l1; 47 | if (l2) p.next = l2; 48 | return l.next; 49 | } 50 | while (lists.length > 1) { 51 | let arr = []; 52 | let len = lists.length; 53 | for (let i = 1; i < len; i+=2) { 54 | arr.push(mergeList(lists[i - 1], lists[i])); 55 | } 56 | if (len % 2) arr.push(lists[len - 1]); 57 | lists = arr; 58 | } 59 | return lists[0]; 60 | }; -------------------------------------------------------------------------------- /leetcode/24-swap-nodes-in-pairs.js: -------------------------------------------------------------------------------- 1 | // No.24 两两交换链表中的节点 2 | 3 | // 给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。 4 | 5 | // 示例: 6 | 7 | // 给定 1->2->3->4, 你应该返回 2->1->4->3. 8 | // 说明: 9 | 10 | // 你的算法只能使用常数的额外空间。 11 | // 你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。 12 | 13 | /** 14 | * Definition for singly-linked list. 15 | * function ListNode(val) { 16 | * this.val = val; 17 | * this.next = null; 18 | * } 19 | */ 20 | function ListNode(val) { 21 | this.val = val; 22 | this.next = null; 23 | } 24 | /** 25 | * @param {ListNode} head 26 | * @return {ListNode} 27 | */ 28 | var swapPairs = function(head) { 29 | if (head == null || head.next == null) return head; 30 | let node = head.next; 31 | head.next = swapPairs(head.next.next); 32 | node.next = head; 33 | return node; 34 | }; 35 | 36 | let nodes = [2, 1, 4, 3]; 37 | function initList(nodes) { 38 | let head = new ListNode(); 39 | let p = head; 40 | for (let i = 0, len = nodes.length; i < len; i++) { 41 | p.next = new ListNode(nodes[i]); 42 | p = p.next; 43 | } 44 | return head.next; 45 | } 46 | 47 | let head = initList(nodes); 48 | console.log(swapPairs(head)) -------------------------------------------------------------------------------- /leetcode/25-reverse-nodes-in-k-group.js: -------------------------------------------------------------------------------- 1 | // No.25 k个一组翻转链表 2 | 3 | // 给出一个链表,每 k 个节点一组进行翻转,并返回翻转后的链表。 4 | 5 | // k 是一个正整数,它的值小于或等于链表的长度。如果节点总数不是 k 的整数倍,那么将最后剩余节点保持原有顺序。 6 | 7 | // 示例 : 8 | 9 | // 给定这个链表:1->2->3->4->5 10 | 11 | // 当 k = 2 时,应当返回: 2->1->4->3->5 12 | 13 | // 当 k = 3 时,应当返回: 3->2->1->4->5 14 | 15 | // 说明 : 16 | 17 | // 你的算法只能使用常数的额外空间。 18 | // 你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。 19 | 20 | /** 21 | * Definition for singly-linked list. 22 | * function ListNode(val) { 23 | * this.val = val; 24 | * this.next = null; 25 | * } 26 | */ 27 | /** 28 | * @param {ListNode} head 29 | * @param {number} k 30 | * @return {ListNode} 31 | */ 32 | var reverseKGroup = function(head, k) { 33 | let curr = head; 34 | let count = 0; 35 | while (curr != null && count != k) { 36 | curr = curr.next; 37 | count++; 38 | } 39 | if (count == k) { 40 | curr = reverseKGroup(curr, k); 41 | while (count-- > 0) { 42 | let tmp = head.next; 43 | head.next = curr; 44 | curr = head; 45 | head = tmp; 46 | } 47 | head = curr; 48 | } 49 | return head; 50 | }; 51 | -------------------------------------------------------------------------------- /leetcode/26-remove-duplicates-from-sorted-array.js: -------------------------------------------------------------------------------- 1 | // No.26 删除排序数组中的重复项 2 | 3 | // 给定一个排序数组,你需要在原地删除重复出现的元素, 4 | // 使得每个元素只出现一次,返回移除后数组的新长度。 5 | 6 | // 不要使用额外的数组空间, 7 | // 你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。 8 | 9 | // 示例 1: 10 | 11 | // 给定数组 nums = [1,1,2], 12 | 13 | // 函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2。 14 | 15 | // 你不需要考虑数组中超出新长度后面的元素。 16 | // 示例 2: 17 | 18 | // 给定 nums = [0,0,1,1,1,2,2,3,3,4], 19 | 20 | // 函数应该返回新的长度 5, 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4。 21 | 22 | // 你不需要考虑数组中超出新长度后面的元素。 23 | // 说明: 24 | 25 | // 为什么返回数值是整数,但输出的答案是数组呢? 26 | 27 | // 请注意,输入数组是以“引用”方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。 28 | 29 | // 你可以想象内部操作如下: 30 | 31 | // // nums 是以“引用”方式传递的。也就是说,不对实参做任何拷贝 32 | // int len = removeDuplicates(nums); 33 | 34 | // // 在函数里修改输入数组对于调用者是可见的。 35 | // // 根据你的函数返回的长度, 它会打印出数组中该长度范围内的所有元素。 36 | // for (int i = 0; i < len; i++) { 37 | // print(nums[i]); 38 | // } 39 | 40 | /** 41 | * @param {number[]} nums 42 | * @return {number} 43 | */ 44 | var removeDuplicates = function(nums) { 45 | let index = 1; 46 | for (let i = 1, len = nums.length; i < len; i++) { 47 | if (nums[i] !== nums[i - 1]) nums[index++] = nums[i]; 48 | } 49 | return nums.length ? index : 0; 50 | }; 51 | 52 | console.log(removeDuplicates([1, 1, 2])); 53 | -------------------------------------------------------------------------------- /leetcode/27-remove-element.js: -------------------------------------------------------------------------------- 1 | // No.27 移除元素 2 | 3 | // 给定一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,返回移除后数组的新长度。 4 | 5 | // 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。 6 | 7 | // 元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。 8 | 9 | // 示例 1: 10 | 11 | // 给定 nums = [3,2,2,3], val = 3, 12 | 13 | // 函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。 14 | 15 | // 你不需要考虑数组中超出新长度后面的元素。 16 | // 示例 2: 17 | 18 | // 给定 nums = [0,1,2,2,3,0,4,2], val = 2, 19 | 20 | // 函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。 21 | 22 | // 注意这五个元素可为任意顺序。 23 | 24 | // 你不需要考虑数组中超出新长度后面的元素。 25 | // 说明: 26 | 27 | // 为什么返回数值是整数,但输出的答案是数组呢? 28 | 29 | // 请注意,输入数组是以“引用”方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。 30 | 31 | // 你可以想象内部操作如下: 32 | 33 | // // nums 是以“引用”方式传递的。也就是说,不对实参作任何拷贝 34 | // int len = removeElement(nums, val); 35 | 36 | // // 在函数里修改输入数组对于调用者是可见的。 37 | // // 根据你的函数返回的长度, 它会打印出数组中该长度范围内的所有元素。 38 | // for (int i = 0; i < len; i++) { 39 | // print(nums[i]); 40 | // } 41 | 42 | /** 43 | * @param {number[]} nums 44 | * @param {number} val 45 | * @return {number} 46 | */ 47 | var removeElement = function(nums, val) { 48 | let [left, right] = [0, nums.length - 1]; 49 | if (right < 0) return 0; 50 | while (left < right) { 51 | if (nums[left] === val) { 52 | while (nums[right] === val) { 53 | right--; 54 | } 55 | if (left < right) { 56 | [nums[left], nums[right]] = [nums[right], nums[left]]; 57 | right--; 58 | left++; 59 | } 60 | } else { 61 | left++; 62 | } 63 | } 64 | return nums[left] !== val ? ++left : left; 65 | }; 66 | 67 | let arr = [3,2,2,3]; 68 | console.log(removeElement(arr, 3)); 69 | console.log(arr); -------------------------------------------------------------------------------- /leetcode/28-implement-str-str.js: -------------------------------------------------------------------------------- 1 | // No.28 实现strStr() 2 | 3 | // 实现 strStr() 函数。 4 | 5 | // 给定一个 haystack 字符串和一个 needle 字符串, 6 | // 在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回 -1。 7 | 8 | // 示例 1: 9 | 10 | // 输入: haystack = "hello", needle = "ll" 11 | // 输出: 2 12 | // 示例 2: 13 | 14 | // 输入: haystack = "aaaaa", needle = "bba" 15 | // 输出: -1 16 | // 说明: 17 | 18 | // 当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。 19 | 20 | // 对于本题而言,当 needle 是空字符串时我们应当返回 0 。 21 | // 这与C语言的 strstr() 以及 Java的 indexOf() 定义相符。 22 | 23 | /** 24 | * @param {string} haystack 25 | * @param {string} needle 26 | * @return {number} 27 | */ 28 | var strStr = function(haystack, needle) { 29 | // if (needle === "") {return 0} 30 | // let ret = -1; 31 | // let reg = new RegExp("(.*?)" + needle) 32 | // haystack.replace(reg, (m, p1) => { 33 | // if (m) { 34 | // ret = p1.length; 35 | // } 36 | // }) 37 | // return ret; 38 | 39 | if (needle === "" || haystack === needle) return 0; 40 | let [len_1, len_2] = [haystack.length, needle.length]; 41 | for (let i = 0, len = len_1 - len_2; i <= len; i++) { 42 | for (let j = 0; j < len_2; j++) { 43 | if (haystack[i + j] !== needle[j]) { 44 | break; 45 | } else { 46 | if (j === len_2 - 1) { 47 | return i; 48 | } 49 | } 50 | } 51 | } 52 | return -1; 53 | }; 54 | 55 | var a = "ppi"; 56 | var b = "pi"; 57 | 58 | console.log(strStr(a, b)); 59 | -------------------------------------------------------------------------------- /leetcode/29-divide-two-integers.js: -------------------------------------------------------------------------------- 1 | // No.29 两数相除 2 | 3 | // 给定两个整数,被除数 dividend 和除数 divisor。将两数相除,要求不使用乘法、除法和 mod 运算符。 4 | 5 | // 返回被除数 dividend 除以除数 divisor 得到的商。 6 | 7 | // 示例 1: 8 | 9 | // 输入: dividend = 10, divisor = 3 10 | // 输出: 3 11 | // 示例 2: 12 | 13 | // 输入: dividend = 7, divisor = -3 14 | // 输出: -2 15 | // 说明: 16 | 17 | // 被除数和除数均为 32 位有符号整数。 18 | // 除数不为 0。 19 | // 假设我们的环境只能存储 32 位有符号整数,其数值范围是 [−2**31, 2**31 − 1]。本题中,如果除法结果溢出,则返回 231 − 1。 20 | 21 | /** 22 | * @param {number} dividend 23 | * @param {number} divisor 24 | * @return {number} 25 | */ 26 | var divide = function(dividend, divisor) { 27 | if (!divisor || (dividend == -(2 ** 31) && divisor == -1)) return 2 ** 31 - 1; 28 | const SIGN = (dividend > 0 ^ divisor < 0); 29 | let [dvd, dvs, res] = [Math.abs(dividend), Math.abs(divisor), 0]; 30 | while (dvd >= dvs) { 31 | let [temp, mult] = [dvs, 1]; 32 | while (dvd >> 1 >= temp) { 33 | temp <<= 1; 34 | mult <<= 1; 35 | } 36 | dvd -= temp; 37 | res += mult; 38 | } 39 | return SIGN ? res : -res; 40 | }; 41 | 42 | console.log(divide(999, 3)); 43 | -------------------------------------------------------------------------------- /leetcode/31.下一个排列.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=31 lang=javascript 3 | * 4 | * [31] 下一个排列 5 | * 6 | * https://leetcode-cn.com/problems/next-permutation/description/ 7 | * 8 | * algorithms 9 | * Medium (32.47%) 10 | * Likes: 354 11 | * Dislikes: 0 12 | * Total Accepted: 37.4K 13 | * Total Submissions: 114.9K 14 | * Testcase Example: '[1,2,3]' 15 | * 16 | * 实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。 17 | * 18 | * 如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。 19 | * 20 | * 必须原地修改,只允许使用额外常数空间。 21 | * 22 | * 以下是一些例子,输入位于左侧列,其相应输出位于右侧列。 23 | * 1,2,3 → 1,3,2 24 | * 3,2,1 → 1,2,3 25 | * 1,1,5 → 1,5,1 26 | * 27 | */ 28 | 29 | // @lc code=start 30 | /** 31 | * @param {number[]} nums 32 | * @return {void} Do not return anything, modify nums in-place instead. 33 | */ 34 | var nextPermutation = function(nums) { 35 | const len = nums.length 36 | if (len < 1) return 37 | // 定义交换数组元素函数 38 | const swap = (arr, l, r) => { 39 | if (l < 0 || r < 0) return 40 | [arr[l], arr[r]] = [arr[r], arr[l]] 41 | } 42 | // 查找数组中从右到左第一个非递增元素索引 leftIndex 43 | let leftIndex = len - 1 44 | while (nums[leftIndex] <= nums[--leftIndex]) {} 45 | // 查找数组中从右到左第一个比 leftIndex 小的元素索引 rightIndex 46 | let rightIndex = len - 1 47 | while (leftIndex >= 0 && nums[leftIndex] >= nums[rightIndex]) rightIndex-- 48 | // 交换两元素位置 49 | swap(nums, leftIndex, rightIndex) 50 | // 将 leftIndex 后的元素按递增顺序排序 51 | for (let i = leftIndex + 1, stop = (i + len) / 2; i < stop; i++) { 52 | swap(nums, i, len + leftIndex - i) 53 | } 54 | }; 55 | // @lc code=end 56 | 57 | -------------------------------------------------------------------------------- /leetcode/32.最长有效括号.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=32 lang=javascript 3 | * 4 | * [32] 最长有效括号 5 | * 6 | * https://leetcode-cn.com/problems/longest-valid-parentheses/description/ 7 | * 8 | * algorithms 9 | * Hard (29.04%) 10 | * Likes: 456 11 | * Dislikes: 0 12 | * Total Accepted: 33.5K 13 | * Total Submissions: 115.4K 14 | * Testcase Example: '"(()"' 15 | * 16 | * 给定一个只包含 '(' 和 ')' 的字符串,找出最长的包含有效括号的子串的长度。 17 | * 18 | * 示例 1: 19 | * 20 | * 输入: "(()" 21 | * 输出: 2 22 | * 解释: 最长有效括号子串为 "()" 23 | * 24 | * 25 | * 示例 2: 26 | * 27 | * 输入: ")()())" 28 | * 输出: 4 29 | * 解释: 最长有效括号子串为 "()()" 30 | * 31 | * 32 | */ 33 | 34 | // @lc code=start 35 | /** 36 | * @param {string} s 37 | * @return {number} 38 | */ 39 | var longestValidParentheses = function(s) { 40 | let max = 0 41 | let a = 0 42 | let b = s.length 43 | while (a !== b) { 44 | a = b 45 | s = s.replace(/\((_*)\)/g, '_$1') 46 | b = s.length 47 | } 48 | s = s.replace(/[^_]+/g, ' ').trim() 49 | s.split(' ').forEach((str) => { 50 | max = Math.max(max, str.length) 51 | }) 52 | return max * 2 53 | }; 54 | // @lc code=end 55 | 56 | -------------------------------------------------------------------------------- /leetcode/33.搜索旋转排序数组.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=33 lang=javascript 3 | * 4 | * [33] 搜索旋转排序数组 5 | */ 6 | 7 | // 假设按照升序排序的数组在预先未知的某个点上进行了旋转。 8 | 9 | // ( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。 10 | 11 | // 搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。 12 | 13 | // 你可以假设数组中不存在重复的元素。 14 | 15 | // 你的算法时间复杂度必须是 O(log n) 级别。 16 | 17 | // 示例 1: 18 | 19 | // 输入: nums = [4,5,6,7,0,1,2], target = 0 20 | // 输出: 4 21 | // 示例 2: 22 | 23 | // 输入: nums = [4,5,6,7,0,1,2], target = 3 24 | // 输出: -1 25 | 26 | // @lc code=start 27 | /** 28 | * @param {number[]} nums 29 | * @param {number} target 30 | * @return {number} 31 | */ 32 | var search = function (nums, target) { 33 | let [left, right] = [0, nums.length - 1] 34 | while (left <= right) { 35 | const pivot = (left + right) >> 1 36 | if (target === nums[pivot]) return pivot 37 | if (target === nums[left]) return left 38 | if (target === nums[right]) return right 39 | if ( 40 | target < nums[pivot] && target > nums[left] && nums[pivot] > nums[left] 41 | || target < nums[left] && target < nums[pivot] && nums[pivot] < nums[left] 42 | || target > nums[left] && nums[pivot] < nums[left] 43 | ) right = pivot - 1 44 | else left = pivot + 1 45 | } 46 | return -1 47 | }; 48 | // @lc code=end 49 | 50 | 51 | const res = search([5,1,2,3,4], 1) 52 | console.log('TCL: res', res) 53 | -------------------------------------------------------------------------------- /leetcode/34.在排序数组中查找元素的第一个和最后一个位置.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=34 lang=javascript 3 | * 4 | * [34] 在排序数组中查找元素的第一个和最后一个位置 5 | * 6 | * https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array/description/ 7 | * 8 | * algorithms 9 | * Medium (38.43%) 10 | * Likes: 285 11 | * Dislikes: 0 12 | * Total Accepted: 54.9K 13 | * Total Submissions: 142.4K 14 | * Testcase Example: '[5,7,7,8,8,10]\n8' 15 | * 16 | * 给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。 17 | * 18 | * 你的算法时间复杂度必须是 O(log n) 级别。 19 | * 20 | * 如果数组中不存在目标值,返回 [-1, -1]。 21 | * 22 | * 示例 1: 23 | * 24 | * 输入: nums = [5,7,7,8,8,10], target = 8 25 | * 输出: [3,4] 26 | * 27 | * 示例 2: 28 | * 29 | * 输入: nums = [5,7,7,8,8,10], target = 6 30 | * 输出: [-1,-1] 31 | * 32 | */ 33 | 34 | // @lc code=start 35 | /** 36 | * @param {number[]} nums 37 | * @param {number} target 38 | * @return {number[]} 39 | */ 40 | var searchRange = function(nums, target) { 41 | const core = (nums, target, left, right, type) => { 42 | while (left <= right) { 43 | const pivot = (left + right) >> 1 44 | if (target < nums[pivot] || type === 'left' && target === nums[pivot - 1]) right = pivot - 1 45 | else if (target > nums[pivot] || type === 'right' && target === nums[pivot + 1]) left = pivot + 1 46 | else { 47 | return !type 48 | ? [core(nums, target, left, pivot, 'left'), core(nums, target, pivot, right, 'right')] 49 | : pivot 50 | } 51 | } 52 | return !type ? [-1, -1] : -1 53 | } 54 | return core(nums, target, 0, nums.length - 1) 55 | }; 56 | // @lc code=end 57 | 58 | -------------------------------------------------------------------------------- /leetcode/35.搜索插入位置.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=35 lang=javascript 3 | * 4 | * [35] 搜索插入位置 5 | * 6 | * https://leetcode-cn.com/problems/search-insert-position/description/ 7 | * 8 | * algorithms 9 | * Easy (42.77%) 10 | * Total Accepted: 30.1K 11 | * Total Submissions: 70.4K 12 | * Testcase Example: '[1,3,5,6]\n5' 13 | * 14 | * 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 15 | * 16 | * 你可以假设数组中无重复元素。 17 | * 18 | * 示例 1: 19 | * 20 | * 输入: [1,3,5,6], 5 21 | * 输出: 2 22 | * 23 | * 24 | * 示例 2: 25 | * 26 | * 输入: [1,3,5,6], 2 27 | * 输出: 1 28 | * 29 | * 30 | * 示例 3: 31 | * 32 | * 输入: [1,3,5,6], 7 33 | * 输出: 4 34 | * 35 | * 36 | * 示例 4: 37 | * 38 | * 输入: [1,3,5,6], 0 39 | * 输出: 0 40 | * 41 | * 42 | */ 43 | /** 44 | * @param {number[]} nums 45 | * @param {number} target 46 | * @return {number} 47 | */ 48 | var searchInsert = function(nums, target) { 49 | let left = 0; 50 | let right = nums.length; 51 | while (left < right) { 52 | let mid = ~~((left + right) / 2); 53 | let val = nums[mid]; 54 | if (val < target) { 55 | left = mid + 1; 56 | } else if (val > target) { 57 | right = mid; 58 | } else { 59 | return mid; 60 | } 61 | } 62 | return left; 63 | }; 64 | 65 | -------------------------------------------------------------------------------- /leetcode/38.报数.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=38 lang=javascript 3 | * 4 | * [38] 报数 5 | * 6 | * https://leetcode-cn.com/problems/count-and-say/description/ 7 | * 8 | * algorithms 9 | * Easy (48.10%) 10 | * Total Accepted: 21.3K 11 | * Total Submissions: 44.2K 12 | * Testcase Example: '1' 13 | * 14 | * 报数序列是一个整数序列,按照其中的整数的顺序进行报数,得到下一个数。其前五项如下: 15 | * 16 | * 1. 1 17 | * 2. 11 18 | * 3. 21 19 | * 4. 1211 20 | * 5. 111221 21 | * 22 | * 23 | * 1 被读作  "one 1"  ("一个一") , 即 11。 24 | * 11 被读作 "two 1s" ("两个一"), 即 21。 25 | * 21 被读作 "one 2",  "one 1" ("一个二" ,  "一个一") , 即 1211。 26 | * 27 | * 给定一个正整数 n(1 ≤ n ≤ 30),输出报数序列的第 n 项。 28 | * 29 | * 注意:整数顺序将表示为一个字符串。 30 | * 31 | * 32 | * 33 | * 示例 1: 34 | * 35 | * 输入: 1 36 | * 输出: "1" 37 | * 38 | * 39 | * 示例 2: 40 | * 41 | * 输入: 4 42 | * 输出: "1211" 43 | * 44 | * 45 | */ 46 | /** 47 | * @param {number} n 48 | * @return {string} 49 | */ 50 | var countAndSay = function(n) { 51 | let getNext = str => { 52 | let res = ""; 53 | let index = 0; 54 | let len = str.length; 55 | while (index < len) { 56 | let s = str.slice(index); 57 | let firstChar = s[0]; 58 | let reg = new RegExp(`^(${firstChar}+)`); 59 | if (reg.test(s)) { 60 | let count = RegExp.$1.length; 61 | res += `${count}${firstChar}`; 62 | index += count; 63 | } 64 | } 65 | return res; 66 | }; 67 | let pre = "1"; 68 | let cur = "1"; 69 | for (let i = 1; i < n; i++) { 70 | cur = getNext(pre); 71 | pre = cur; 72 | } 73 | return cur; 74 | }; 75 | 76 | // console.log(countAndSay(4)) 77 | -------------------------------------------------------------------------------- /leetcode/4-find-median-sorted-arrays.js: -------------------------------------------------------------------------------- 1 | // No.4 两个排序数组的中位数 2 | 3 | // 给定两个大小为 m 和 n 的有序数组 nums1 和 nums2 。 4 | 5 | // 请找出这两个有序数组的中位数。要求算法的时间复杂度为 O(log (m+n)) 。 6 | 7 | // 你可以假设 nums1 和 nums2 不同时为空。 8 | 9 | // 示例 1: 10 | 11 | // nums1 = [1, 3] 12 | // nums2 = [2] 13 | 14 | // 中位数是 2.0 15 | // 示例 2: 16 | 17 | // nums1 = [1, 2] 18 | // nums2 = [3, 4] 19 | 20 | // 中位数是 (2 + 3)/2 = 2.5 21 | 22 | /** 23 | * @param {number[]} nums1 24 | * @param {number[]} nums2 25 | * @return {number} 26 | */ 27 | var findMedianSortedArrays = function(nums1, nums2) { 28 | let len = nums1.length + nums2.length; 29 | let isOdd = len % 2; 30 | let midIndex = (len >> 1) + 1; 31 | let count = 0; 32 | let tmp; 33 | while (nums1.length && nums2.length) { 34 | count++; 35 | if (count == midIndex) { 36 | let cur = nums1[0] < nums2[0] ? nums1.shift() : nums2.shift(); 37 | return isOdd ? cur : (tmp + cur) / 2; 38 | } else { 39 | tmp = nums1[0] < nums2[0] ? nums1.shift() : nums2.shift(); 40 | } 41 | } 42 | while (nums1.length) { 43 | count++; 44 | if (count == midIndex) { 45 | let cur = nums1.shift(); 46 | return isOdd ? cur : (tmp + cur) / 2; 47 | } else { 48 | tmp = nums1.shift(); 49 | } 50 | } 51 | while (nums2.length) { 52 | count++; 53 | if (count == midIndex) { 54 | let cur = nums2.shift(); 55 | return isOdd ? cur : (tmp + cur) / 2; 56 | } else { 57 | tmp = nums2.shift(); 58 | } 59 | } 60 | }; 61 | 62 | console.log(findMedianSortedArrays([1, 3, 5, 7], [2, 4, 6, 8])); 63 | -------------------------------------------------------------------------------- /leetcode/5-longest-palindrome.js: -------------------------------------------------------------------------------- 1 | // No.5 最长回文子串 2 | 3 | // 给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为1000。 4 | 5 | // 示例 1: 6 | 7 | // 输入: "babad" 8 | // 输出: "bab" 9 | // 注意: "aba"也是一个有效答案。 10 | // 示例 2: 11 | 12 | // 输入: "cbbd" 13 | // 输出: "bb" 14 | 15 | /** 16 | * @param {string} s 17 | * @return {string} 18 | */ 19 | var longestPalindrome = function(s) { 20 | let len = s.length; 21 | if (len < 2) { 22 | return s; 23 | } 24 | let start = 0; 25 | let maxLen = 1; 26 | let core = (s, l, r) => { 27 | let len = s.length; 28 | while (l >= 0 && r < len && s[l] === s[r]) { 29 | l--; 30 | r++; 31 | } 32 | if (maxLen < r - l - 1) { 33 | start = l + 1; 34 | maxLen = r - l - 1; 35 | } 36 | } 37 | for (let i = 0; i < len - 1; i++) { 38 | core(s, i, i); 39 | core(s, i, i + 1); 40 | } 41 | return s.substr(start, maxLen); 42 | }; 43 | 44 | console.log(longestPalindrome("bb")); 45 | -------------------------------------------------------------------------------- /leetcode/53.最大子序和.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=53 lang=javascript 3 | * 4 | * [53] 最大子序和 5 | * 6 | * https://leetcode-cn.com/problems/maximum-subarray/description/ 7 | * 8 | * algorithms 9 | * Easy (42.51%) 10 | * Total Accepted: 37.9K 11 | * Total Submissions: 88.9K 12 | * Testcase Example: '[-2,1,-3,4,-1,2,1,-5,4]' 13 | * 14 | * 给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。 15 | * 16 | * 示例: 17 | * 18 | * 输入: [-2,1,-3,4,-1,2,1,-5,4], 19 | * 输出: 6 20 | * 解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。 21 | * 22 | * 23 | * 进阶: 24 | * 25 | * 如果你已经实现复杂度为 O(n) 的解法,尝试使用更为精妙的分治法求解。 26 | * 27 | */ 28 | /** 29 | * @param {number[]} nums 30 | * @return {number} 31 | */ 32 | var maxSubArray = function(nums) { 33 | let len = nums.length; 34 | if (!len) return 0; 35 | let max = nums[0]; 36 | let tmp = nums[0]; 37 | for (let i = 1; i < len; i++) { 38 | tmp = tmp > 0 ? tmp + nums[i] : nums[i]; 39 | max = tmp > max ? tmp : max; 40 | } 41 | return max; 42 | }; 43 | 44 | -------------------------------------------------------------------------------- /leetcode/58.最后一个单词的长度.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=58 lang=javascript 3 | * 4 | * [58] 最后一个单词的长度 5 | * 6 | * https://leetcode-cn.com/problems/length-of-last-word/description/ 7 | * 8 | * algorithms 9 | * Easy (28.80%) 10 | * Total Accepted: 17.9K 11 | * Total Submissions: 62.4K 12 | * Testcase Example: '"Hello World"' 13 | * 14 | * 给定一个仅包含大小写字母和空格 ' ' 的字符串,返回其最后一个单词的长度。 15 | * 16 | * 如果不存在最后一个单词,请返回 0 。 17 | * 18 | * 说明:一个单词是指由字母组成,但不包含任何空格的字符串。 19 | * 20 | * 示例: 21 | * 22 | * 输入: "Hello World" 23 | * 输出: 5 24 | * 25 | * 26 | */ 27 | /** 28 | * @param {string} s 29 | * @return {number} 30 | */ 31 | var lengthOfLastWord = function(s) { 32 | let i = s.length; 33 | let count = 0; 34 | while (s[i - 1] === ' ') i--; 35 | while (s[--i] && s[i] !== ' ') { 36 | ++count; 37 | } 38 | return count; 39 | }; 40 | 41 | -------------------------------------------------------------------------------- /leetcode/6-zig-zag-conversion.js: -------------------------------------------------------------------------------- 1 | // No.6 Z字形变换 2 | 3 | // 将字符串 "PAYPALISHIRING" 以Z字形排列成给定的行数: 4 | 5 | // P A H N 6 | // A P L S I I G 7 | // Y I R 8 | // 之后从左往右,逐行读取字符:"PAHNAPLSIIGYIR" 9 | 10 | // 实现一个将字符串进行指定行数变换的函数: 11 | 12 | // string convert(string s, int numRows); 13 | // 示例 1: 14 | 15 | // 输入: s = "PAYPALISHIRING", numRows = 3 16 | // 输出: "PAHNAPLSIIGYIR" 17 | // 示例 2: 18 | 19 | // 输入: s = "PAYPALISHIRING", numRows = 4 20 | // 输出: "PINALSIGYAHRPI" 21 | // 解释: 22 | 23 | // P I N 24 | // A L S I G 25 | // Y A H R 26 | // P I 27 | 28 | /** 29 | * @param {string} s 30 | * @param {number} numRows 31 | * @return {string} 32 | */ 33 | var convert = function(s, numRows) { 34 | let res = ""; 35 | let len = s.length; 36 | if (len < 2 || numRows < 2 || len <= numRows) return s; 37 | let f = 2 * (numRows - 1); 38 | for (let i = 0; i < numRows; i++) { 39 | let bit = f - 2 * i; 40 | let flag = true; 41 | for (let j = i; j < len;) { 42 | res += flag ? (bit !== 0 ? s[j] : "") : (bit !== f ? s[j] : ""); 43 | j += flag ? bit : f - bit; 44 | flag = !flag; 45 | } 46 | } 47 | return res; 48 | }; 49 | 50 | console.log(convert("PAYPALISHIRING", 4)); 51 | -------------------------------------------------------------------------------- /leetcode/66.加一.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=66 lang=javascript 3 | * 4 | * [66] 加一 5 | * 6 | * https://leetcode-cn.com/problems/plus-one/description/ 7 | * 8 | * algorithms 9 | * Easy (37.49%) 10 | * Total Accepted: 37.9K 11 | * Total Submissions: 101.2K 12 | * Testcase Example: '[1,2,3]' 13 | * 14 | * 给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一。 15 | * 16 | * 最高位数字存放在数组的首位, 数组中每个元素只存储一个数字。 17 | * 18 | * 你可以假设除了整数 0 之外,这个整数不会以零开头。 19 | * 20 | * 示例 1: 21 | * 22 | * 输入: [1,2,3] 23 | * 输出: [1,2,4] 24 | * 解释: 输入数组表示数字 123。 25 | * 26 | * 27 | * 示例 2: 28 | * 29 | * 输入: [4,3,2,1] 30 | * 输出: [4,3,2,2] 31 | * 解释: 输入数组表示数字 4321。 32 | * 33 | * 34 | */ 35 | /** 36 | * @param {number[]} digits 37 | * @return {number[]} 38 | */ 39 | var plusOne = function(digits) { 40 | let i = digits.length; 41 | while (digits[--i] === 9) { 42 | digits[i] = 0; 43 | } 44 | digits[i]++; 45 | return i < 0 ? [1, ...digits] : digits; 46 | }; 47 | -------------------------------------------------------------------------------- /leetcode/67.二进制求和.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=67 lang=javascript 3 | * 4 | * [67] 二进制求和 5 | * 6 | * https://leetcode-cn.com/problems/add-binary/description/ 7 | * 8 | * algorithms 9 | * Easy (46.54%) 10 | * Total Accepted: 17K 11 | * Total Submissions: 36.4K 12 | * Testcase Example: '"11"\n"1"' 13 | * 14 | * 给定两个二进制字符串,返回他们的和(用二进制表示)。 15 | * 16 | * 输入为非空字符串且只包含数字 1 和 0。 17 | * 18 | * 示例 1: 19 | * 20 | * 输入: a = "11", b = "1" 21 | * 输出: "100" 22 | * 23 | * 示例 2: 24 | * 25 | * 输入: a = "1010", b = "1011" 26 | * 输出: "10101" 27 | * 28 | */ 29 | /** 30 | * @param {string} a 31 | * @param {string} b 32 | * @return {string} 33 | */ 34 | var addBinary = function(a, b) { 35 | let [indexA, indexB, flag, res, xor, longStr, longIndex] = [a.length - 1, b.length - 1, 0, ""]; 36 | if (indexA > indexB) { 37 | longStr = a; 38 | longIndex = indexA - indexB - 1; 39 | } else { 40 | longStr = b; 41 | longIndex = indexB - indexA - 1; 42 | } 43 | while (indexA >= 0 && indexB >= 0) { 44 | xor = a[indexA] ^ b[indexB] ^ flag; 45 | flag = ~~((~~a[indexA--] + ~~b[indexB--] + ~~flag) > 1); 46 | res = xor + res; 47 | } 48 | while (longIndex >= 0) { 49 | xor = longStr[longIndex--] ^ flag; 50 | flag = !xor && flag; 51 | res = xor + res; 52 | } 53 | return flag ? flag + res : res; 54 | }; 55 | 56 | console.log(addBinary("11", "1")) 57 | -------------------------------------------------------------------------------- /leetcode/69.x-的平方根.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=69 lang=javascript 3 | * 4 | * [69] x 的平方根 5 | * 6 | * https://leetcode-cn.com/problems/sqrtx/description/ 7 | * 8 | * algorithms 9 | * Easy (34.57%) 10 | * Total Accepted: 24.3K 11 | * Total Submissions: 70.3K 12 | * Testcase Example: '4' 13 | * 14 | * 实现 int sqrt(int x) 函数。 15 | * 16 | * 计算并返回 x 的平方根,其中 x 是非负整数。 17 | * 18 | * 由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。 19 | * 20 | * 示例 1: 21 | * 22 | * 输入: 4 23 | * 输出: 2 24 | * 25 | * 26 | * 示例 2: 27 | * 28 | * 输入: 8 29 | * 输出: 2 30 | * 说明: 8 的平方根是 2.82842..., 31 | * 由于返回类型是整数,小数部分将被舍去。 32 | * 33 | * 34 | */ 35 | /** 36 | * @param {number} x 37 | * @return {number} 38 | */ 39 | var mySqrt = function(x) { 40 | let last = x; 41 | let cur = x / 2 + 0.5; 42 | while (Math.abs(last - cur) >= 1) { 43 | last = cur; 44 | cur = (last + x / last) / 2; 45 | } 46 | return parseInt(cur); 47 | }; 48 | 49 | // // dichotomy 50 | // var mySqrt = function(x) { 51 | // if (x <= 1) return x; 52 | // let left = 0; 53 | // let right = x; 54 | // let mid = left + ((right - left) >> 1); 55 | // while (right - left > 1) { 56 | // let square = mid ** 2; 57 | // if (square > x) { 58 | // right = mid; 59 | // mid = left + ((mid - left) >> 1); 60 | // } else if (square < x) { 61 | // left = mid; 62 | // mid = mid + ((right - mid) >> 1); 63 | // } else { 64 | // return mid; 65 | // } 66 | // } 67 | // return mid; 68 | // }; 69 | -------------------------------------------------------------------------------- /leetcode/7-reverse-integer.js: -------------------------------------------------------------------------------- 1 | // No.7 反转整数 2 | 3 | // 给定一个 32 位有符号整数,将整数中的数字进行反转。 4 | 5 | // 示例 1: 6 | 7 | // 输入: 123 8 | // 输出: 321 9 | // 示例 2: 10 | 11 | // 输入: -123 12 | // 输出: -321 13 | // 示例 3: 14 | 15 | // 输入: 120 16 | // 输出: 21 17 | // 注意: 18 | 19 | // 假设我们的环境只能存储 32 位有符号整数,其数值范围是 [−231, 231 − 1]。 20 | // 根据这个假设,如果反转后的整数溢出,则返回 0。 21 | 22 | /** 23 | * @param {number} x 24 | * @return {number} 25 | */ 26 | var reverse = function(x) { 27 | // if (x > 2**31 - 1 || x < -(2**31)) return 0; 28 | // let res = x >= 0 29 | // ? Number(x.toString().split('').reverse().join('')) 30 | // : -Number(x.toString().split('').reverse().join('').slice(0, -1)); 31 | // return res > 2**31 - 1 || res < -(2**31) ? 0 : res; 32 | 33 | let [res, MIN, MAX] = [0, -(2 ** 31), 2 ** 31 - 1]; 34 | while (x !== 0) { 35 | res = res * 10 + (x % 10); 36 | x = Math.trunc(x / 10); 37 | if (res < MIN || res > MAX) return 0; 38 | } 39 | return res; 40 | }; 41 | -------------------------------------------------------------------------------- /leetcode/70.爬楼梯.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=70 lang=javascript 3 | * 4 | * [70] 爬楼梯 5 | * 6 | * https://leetcode-cn.com/problems/climbing-stairs/description/ 7 | * 8 | * algorithms 9 | * Easy (44.21%) 10 | * Total Accepted: 32K 11 | * Total Submissions: 72.3K 12 | * Testcase Example: '2' 13 | * 14 | * 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 15 | * 16 | * 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢? 17 | * 18 | * 注意:给定 n 是一个正整数。 19 | * 20 | * 示例 1: 21 | * 22 | * 输入: 2 23 | * 输出: 2 24 | * 解释: 有两种方法可以爬到楼顶。 25 | * 1. 1 阶 + 1 阶 26 | * 2. 2 阶 27 | * 28 | * 示例 2: 29 | * 30 | * 输入: 3 31 | * 输出: 3 32 | * 解释: 有三种方法可以爬到楼顶。 33 | * 1. 1 阶 + 1 阶 + 1 阶 34 | * 2. 1 阶 + 2 阶 35 | * 3. 2 阶 + 1 阶 36 | * 37 | * 38 | */ 39 | /** 40 | * @param {number} n 41 | * @return {number} 42 | */ 43 | var climbStairs = function(n) { 44 | if (n < 3) return n; 45 | let pre = 1; 46 | let cur = 2; 47 | for (let i = 2; i < n; i++) { 48 | let tmp = cur; 49 | cur = pre + cur; 50 | pre = tmp; 51 | } 52 | return cur; 53 | }; 54 | 55 | -------------------------------------------------------------------------------- /leetcode/8-string-to-integer-atoi.js: -------------------------------------------------------------------------------- 1 | // No.8 字符串转整数 (atoi) 2 | 3 | // 实现 atoi,将字符串转为整数。 4 | 5 | // 该函数首先根据需要丢弃任意多的空格字符,直到找到第一个非空格字符为止。如果第一个非空字符是正号或负号,选取该符号,并将其与后面尽可能多的连续的数字组合起来,这部分字符即为整数的值。如果第一个非空字符是数字,则直接将其与之后连续的数字字符组合起来,形成整数。 6 | 7 | // 字符串可以在形成整数的字符后面包括多余的字符,这些字符可以被忽略,它们对于函数没有影响。 8 | 9 | // 当字符串中的第一个非空字符序列不是个有效的整数;或字符串为空;或字符串仅包含空白字符时,则不进行转换。 10 | 11 | // 若函数不能执行有效的转换,返回 0。 12 | 13 | // 说明: 14 | 15 | // 假设我们的环境只能存储 32 位有符号整数,其数值范围是 [−231, 231 − 1]。如果数值超过可表示的范围,则返回 INT_MAX (231 − 1) 或 INT_MIN (−231) 。 16 | 17 | // 示例 1: 18 | 19 | // 输入: "42" 20 | // 输出: 42 21 | // 示例 2: 22 | 23 | // 输入: " -42" 24 | // 输出: -42 25 | // 解释: 第一个非空白字符为 '-', 它是一个负号。 26 | // 我们尽可能将负号与后面所有连续出现的数字组合起来,最后得到 -42 。 27 | // 示例 3: 28 | 29 | // 输入: "4193 with words" 30 | // 输出: 4193 31 | // 解释: 转换截止于数字 '3' ,因为它的下一个字符不为数字。 32 | // 示例 4: 33 | 34 | // 输入: "words and 987" 35 | // 输出: 0 36 | // 解释: 第一个非空字符是 'w', 但它不是数字或正、负号。 37 | // 因此无法执行有效的转换。 38 | // 示例 5: 39 | 40 | // 输入: "-91283472332" 41 | // 输出: -2147483648 42 | // 解释: 数字 "-91283472332" 超过 32 位有符号整数范围。 43 | // 因此返回 INT_MIN (−231) 。 44 | 45 | /** 46 | * @param {string} str 47 | * @return {number} 48 | */ 49 | var myAtoi = function(str) { 50 | if (/^\s*([+-]?\d+)/g.test(str)) { 51 | var num = Number(RegExp.$1); 52 | let [MIN, MAX] = [-(2 ** 31), 2 ** 31 - 1] 53 | if (num > MAX) return MAX; 54 | if (num < MIN) return MIN; 55 | return num; 56 | } 57 | return 0; 58 | }; -------------------------------------------------------------------------------- /leetcode/83.删除排序链表中的重复元素.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=83 lang=javascript 3 | * 4 | * [83] 删除排序链表中的重复元素 5 | * 6 | * https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list/description/ 7 | * 8 | * algorithms 9 | * Easy (43.86%) 10 | * Total Accepted: 17.6K 11 | * Total Submissions: 39.9K 12 | * Testcase Example: '[1,1,2]' 13 | * 14 | * 给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。 15 | * 16 | * 示例 1: 17 | * 18 | * 输入: 1->1->2 19 | * 输出: 1->2 20 | * 21 | * 22 | * 示例 2: 23 | * 24 | * 输入: 1->1->2->3->3 25 | * 输出: 1->2->3 26 | * 27 | */ 28 | /** 29 | * Definition for singly-linked list. 30 | * function ListNode(val) { 31 | * this.val = val; 32 | * this.next = null; 33 | * } 34 | */ 35 | /** 36 | * @param {ListNode} head 37 | * @return {ListNode} 38 | */ 39 | var deleteDuplicates = function(head) { 40 | if (head === null) return head; 41 | let pre = head; 42 | let cur = head.next; 43 | while (cur !== null) { 44 | if (pre.val === cur.val) { 45 | cur = cur.next; 46 | pre.next = cur; 47 | } else { 48 | cur = cur.next; 49 | pre = pre.next; 50 | } 51 | } 52 | return head; 53 | }; 54 | -------------------------------------------------------------------------------- /leetcode/848-shifting-letters.js: -------------------------------------------------------------------------------- 1 | // 848. Shifting Letters 2 | 3 | // We have a string S of lowercase letters, and an integer array shifts. 4 | 5 | // Call the shift of a letter, the next letter in the alphabet, (wrapping around so that 'z' becomes 'a'). 6 | 7 | // For example, shift('a') = 'b', shift('t') = 'u', and shift('z') = 'a'. 8 | 9 | // Now for each shifts[i] = x, we want to shift the first i+1 letters of S, x times. 10 | 11 | // Return the final string after all such shifts to S are applied. 12 | 13 | // Example 1: 14 | // Input: S = "abc", shifts = [3,5,9] 15 | // Output: "rpl" 16 | // Explanation: 17 | // We start with "abc". 18 | // After shifting the first 1 letters of S by 3, we have "dbc". 19 | // After shifting the first 2 letters of S by 5, we have "igc". 20 | // After shifting the first 3 letters of S by 9, we have "rpl", the answer. 21 | 22 | // Note: 23 | // 1 <= S.length = shifts.length <= 20000 24 | // 0 <= shifts[i] <= 10 ^ 9 25 | 26 | /** 27 | * @param {string} S 28 | * @param {number[]} shifts 29 | * @return {string} 30 | */ 31 | var shiftingLetters = function(S, shifts) { 32 | let shiftBit = 0; 33 | let len = shifts.length; 34 | let res = ""; 35 | while (len--) { 36 | shiftBit += shifts[len]; 37 | if (S[len]) { 38 | let code = (S[len].charCodeAt() + shiftBit - 97)%26 + 97; 39 | res = String.fromCharCode(code) + res; 40 | } 41 | } 42 | return res; 43 | }; 44 | 45 | console.log(shiftingLetters("abc",[3,5,9])) -------------------------------------------------------------------------------- /leetcode/856-score-of-parentheses.js: -------------------------------------------------------------------------------- 1 | // 856. Score of Parentheses 2 | 3 | // Given a balanced parentheses string S, compute the score of the string based on the following rule: 4 | 5 | // () has score 1 6 | // AB has score A + B, where A and B are balanced parentheses strings. 7 | // (A) has score 2 * A, where A is a balanced parentheses string. 8 | 9 | 10 | // Example 1: 11 | 12 | // Input: "()" 13 | // Output: 1 14 | // Example 2: 15 | 16 | // Input: "(())" 17 | // Output: 2 18 | // Example 3: 19 | 20 | // Input: "()()" 21 | // Output: 2 22 | // Example 4: 23 | 24 | // Input: "(()(()))" 25 | // Output: 6 26 | 27 | 28 | // Note: 29 | 30 | // S is a balanced parentheses string, containing only ( and ). 31 | // 2 <= S.length <= 50 32 | 33 | /** 34 | * @param {string} S 35 | * @return {number} 36 | */ 37 | var scoreOfParentheses = function(S) { 38 | let [res,layers,len] = [0,0,S.length]; 39 | for (let i = 0; i < len; i++) { 40 | S[i] == "(" ? layers++ : layers--; 41 | if (S[i] == "(" && S[i+1] == ")") { 42 | res += 1 << (layers - 1) 43 | } 44 | } 45 | return res; 46 | }; 47 | 48 | let S = "(((())())())"; 49 | console.log(scoreOfParentheses(S)); -------------------------------------------------------------------------------- /leetcode/88.合并两个有序数组.js: -------------------------------------------------------------------------------- 1 | /* 2 | * @lc app=leetcode.cn id=88 lang=javascript 3 | * 4 | * [88] 合并两个有序数组 5 | * 6 | * https://leetcode-cn.com/problems/merge-sorted-array/description/ 7 | * 8 | * algorithms 9 | * Easy (42.77%) 10 | * Total Accepted: 29.4K 11 | * Total Submissions: 68.8K 12 | * Testcase Example: '[1,2,3,0,0,0]\n3\n[2,5,6]\n3' 13 | * 14 | * 给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组。 15 | * 16 | * 说明: 17 | * 18 | * 19 | * 初始化 nums1 和 nums2 的元素数量分别为 m 和 n。 20 | * 你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。 21 | * 22 | * 23 | * 示例: 24 | * 25 | * 输入: 26 | * nums1 = [1,2,3,0,0,0], m = 3 27 | * nums2 = [2,5,6], n = 3 28 | * 29 | * 输出: [1,2,2,3,5,6] 30 | * 31 | */ 32 | /** 33 | * @param {number[]} nums1 34 | * @param {number} m 35 | * @param {number[]} nums2 36 | * @param {number} n 37 | * @return {void} Do not return anything, modify nums1 in-place instead. 38 | */ 39 | var merge = function(nums1, m, nums2, n) { 40 | let [p1, p2, count] = [m - 1, n - 1, m + n - 1]; 41 | while (p1 >= 0 && p2 >= 0) { 42 | if (nums1[p1] > nums2[p2]) { 43 | nums1[count--] = nums1[p1--]; 44 | } else { 45 | nums1[count--] = nums2[p2--]; 46 | } 47 | } 48 | while (p2 >= 0) { 49 | nums1[count--] = nums2[p2--]; 50 | } 51 | }; 52 | 53 | // let arr = [1, 2, 3, 0, 0, 0]; 54 | // merge(arr, 3, [2, 5, 6], 3); 55 | -------------------------------------------------------------------------------- /leetcode/9-palindrome-number.js: -------------------------------------------------------------------------------- 1 | // No.9 回文数 2 | 3 | // 判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。 4 | 5 | // 示例 1: 6 | 7 | // 输入: 121 8 | // 输出: true 9 | // 示例 2: 10 | 11 | // 输入: -121 12 | // 输出: false 13 | // 解释: 从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。 14 | // 示例 3: 15 | 16 | // 输入: 10 17 | // 输出: false 18 | // 解释: 从右向左读, 为 01 。因此它不是一个回文数。 19 | // 进阶: 20 | 21 | // 你能不将整数转为字符串来解决这个问题吗? 22 | 23 | /** 24 | * @param {number} x 25 | * @return {boolean} 26 | */ 27 | var isPalindrome = function(x) { 28 | // return Number(x.toString().split('').reverse().join('')) === x; 29 | 30 | // let s = x.toString(); 31 | // let len = s.length; 32 | // for (let l = 0, r = len - 1, n = len >> 1; l < n;) { 33 | // if (l <= r && s[l++] !== s[r--]) { 34 | // return false; 35 | // } 36 | // } 37 | // return true; 38 | 39 | if (x < 0 || (x !== 0 && x % 10 == 0)) return false; 40 | let [left, right] = [x, 0]; 41 | while (left > right) { 42 | right = 10 * right + (left % 10); 43 | left = Math.trunc(left / 10); 44 | } 45 | return left === right || left === Math.trunc(right / 10); 46 | }; 47 | 48 | console.log(isPalindrome(10022201)); 49 | -------------------------------------------------------------------------------- /leetcode/top-interview-questions/array-and-strings/3-longest-substring-without-repeating-characters.js: -------------------------------------------------------------------------------- 1 | // No.3 无重复字符的最长子串 2 | // 给定一个字符串,找出不含有重复字符的最长子串的长度。 3 | 4 | // 示例: 5 | 6 | // 给定 "abcabcbb" ,没有重复字符的最长子串是 "abc" ,那么长度就是3。 7 | 8 | // 给定 "bbbbb" ,最长的子串就是 "b" ,长度是1。 9 | 10 | // 给定 "pwwkew" ,最长子串是 "wke" ,长度是3。请注意答案必须是一个子串,"pwke" 是 子序列 而不是子串。 11 | 12 | /** 13 | * @param {string} s 14 | * @return {number} 15 | */ 16 | 17 | var lengthOfLongestSubstring = function(s) { 18 | var res = 0; // 用于存放当前最长无重复子串的长度 19 | var str = ""; // 用于存放无重复子串 20 | var len = s.length; 21 | for (var i = 0; i < len; i++) { 22 | var char = s[i]; 23 | var index = str.indexOf(char); 24 | if (index === -1) { 25 | str += char; 26 | res = res < str.length ? str.length : res; 27 | } else { 28 | str = str.substr(index + 1) + char; 29 | } 30 | } 31 | return res; 32 | }; 33 | 34 | var s = "pwwkew"; 35 | console.log(lengthOfLongestSubstring(s)); 36 | -------------------------------------------------------------------------------- /leetcode/top-interview-questions/array-and-strings/334-increasing-triplet-subsequence.js: -------------------------------------------------------------------------------- 1 | // No.334 递增的三元子序列 2 | // 给定一个未排序的数组,请判断这个数组中是否存在长度为3的递增的子序列。 3 | 4 | // 正式的数学表达如下: 5 | 6 | // 如果存在这样的 i, j, k, 且满足 0 ≤ i < j < k ≤ n-1, 7 | // 使得 arr[i] < arr[j] < arr[k] ,返回 true ; 否则返回 false 。 8 | // 要求算法时间复杂度为O(n),空间复杂度为O(1) 。 9 | 10 | // 示例: 11 | // 输入 [1, 2, 3, 4, 5], 12 | // 输出 true. 13 | 14 | // 输入 [5, 4, 3, 2, 1], 15 | // 输出 false. 16 | 17 | /** 18 | * @param {number[]} nums 19 | * @return {boolean} 20 | */ 21 | var increasingTriplet = function(nums) { 22 | var small = Number.MAX_SAFE_INTEGER; 23 | var big = Number.MAX_SAFE_INTEGER; 24 | for(var i = 0; i=0 && right amount ? -1 : dp[amount]; 40 | }; -------------------------------------------------------------------------------- /leetcode/top-interview-questions/dynamic-programming/jump-game.js: -------------------------------------------------------------------------------- 1 | // 跳跃游戏 2 | // 给定一个非负整数数组,您最初位于数组的第一个索引处。 3 | 4 | // 数组中的每个元素表示您在该位置的最大跳跃长度。 5 | 6 | // 确定是否能够到达最后一个索引。 7 | 8 | // 示例: 9 | // A = [2,3,1,1,4],返回 true。 10 | 11 | // A = [3,2,1,0,4],返回 false。 12 | 13 | /** 14 | * @param {number[]} nums 15 | * @return {boolean} 16 | */ 17 | var canJump = function(nums) { 18 | var max = 0; 19 | for(var i = 0;imax){ 21 | return false; 22 | } 23 | max = Math.max(i+nums[i],max); 24 | } 25 | return true; 26 | }; -------------------------------------------------------------------------------- /leetcode/top-interview-questions/dynamic-programming/longest-increasing-subsequence.js: -------------------------------------------------------------------------------- 1 | // 给出一个无序的整形数组,找到最长上升子序列的长度。 2 | 3 | // 例如, 4 | 5 | // 给出 [10, 9, 2, 5, 3, 7, 101, 18], 6 | // 最长的上升子序列是 [2, 3, 7, 101],因此它的长度是4。因为可能会有超过一种的最长上升子序列的组合,因此你只需要输出对应的长度即可。 7 | 8 | // 你的算法的时间复杂度应该在 O(n2) 之内。 9 | 10 | // 进阶: 你能将算法的时间复杂度降低到 O(n log n) 吗? 11 | 12 | 13 | /** 14 | * @param {number[]} nums 15 | * @return {number} 16 | */ 17 | var lengthOfLIS = function(nums) { 18 | var tails = new Array(nums.length); 19 | var size = 0; 20 | for (var x in nums){ 21 | var i = 0, j = size; 22 | while(i !== j){ 23 | var m = Math.floor((i+j)/2); 24 | if(tails[m] 4 -> 3) + (5 -> 6 -> 4) 9 | // 输出:7 -> 0 -> 8 10 | // 原因:342 + 465 = 807 11 | 12 | /** 13 | * Definition for singly-linked list. 14 | * function ListNode(val) { 15 | * this.val = val; 16 | * this.next = null; 17 | * } 18 | */ 19 | /** 20 | * @param {ListNode} l1 21 | * @param {ListNode} l2 22 | * @return {ListNode} 23 | */ 24 | var addTwoNumbers = function(l1, l2) { 25 | var a1 = l1; 26 | var a2 = l2; 27 | var carry = 0; 28 | var result = new ListNode(0); 29 | var tmp = result; 30 | while(a1 || a2){ 31 | var v1 = 0; 32 | var v2 = 0; 33 | if(a1){ 34 | v1 = a1.val; 35 | a1 = a1.next; 36 | } 37 | if(a2){ 38 | v2 = a2.val; 39 | a2 = a2.next; 40 | } 41 | var sum = v1 + v2 + carry; 42 | tmp.next = new ListNode(sum % 10); 43 | carry = sum < 10 ? 0 : 1; 44 | tmp = tmp.next; 45 | } 46 | if(carry){ 47 | tmp.next = new ListNode(1); 48 | } 49 | return result.next; 50 | }; 51 | 52 | function ListNode(val) { 53 | this.val = val; 54 | this.next = null; 55 | } 56 | 57 | var a = new ListNode(1); 58 | // a.next = new ListNode(4); 59 | // a.next.next = new ListNode(3); 60 | 61 | var b = new ListNode(9); 62 | b.next = new ListNode(9); 63 | // b.next.next = new ListNode(4); 64 | 65 | 66 | console.log(addTwoNumbers(a,b)); 67 | -------------------------------------------------------------------------------- /leetcode/top-interview-questions/linked-list/intersection-of-two-linked-lists.js: -------------------------------------------------------------------------------- 1 | // 编写一个程序,找到两个单链表相交的起始节点。 2 | 3 | // 例如,下面的两个链表: 4 | 5 | // A: a1 → a2 6 | // ↘ 7 | // c1 → c2 → c3 8 | // ↗ 9 | // B: b1 → b2 → b3 10 | // 在节点 c1 开始相交。 11 | 12 | // 注意: 13 | 14 | // 如果两个链表没有交点,返回 null. 15 | // 在返回结果后,两个链表仍须保持原有的结构。 16 | // 可假定整个链表结构中没有循环。 17 | // 程序尽量满足 O(n) 时间复杂度,且仅用 O(1) 内存。 18 | 19 | /** 20 | * Definition for singly-linked list. 21 | * function ListNode(val) { 22 | * this.val = val; 23 | * this.next = null; 24 | * } 25 | */ 26 | function ListNode(val) { 27 | this.val = val; 28 | this.next = null; 29 | } 30 | 31 | /** 32 | * @param {ListNode} headA 33 | * @param {ListNode} headB 34 | * @return {ListNode} 35 | */ 36 | var getIntersectionNode = function(headA, headB) { 37 | if(headA == null && headB == null) { 38 | return null; 39 | } 40 | let a = headA; 41 | let b = headB; 42 | while(a != b) { 43 | a = a == null ? headB : a.next; 44 | b = b == null ? headA : b.next; 45 | } 46 | return a; 47 | }; 48 | 49 | let C = new ListNode(0); 50 | C.next = new ListNode(1); 51 | C.next.next = new ListNode(2); 52 | 53 | let B = new ListNode(-2); 54 | B.next = new ListNode(-1); 55 | B.next.next = C; 56 | 57 | let A = new ListNode(-1); 58 | A.next = C; 59 | 60 | let D = C; 61 | // console.log(D); 62 | console.log(getIntersectionNode(A,B)); 63 | 64 | -------------------------------------------------------------------------------- /leetcode/top-interview-questions/linked-list/odd-even-list.js: -------------------------------------------------------------------------------- 1 | // Odd Even Linked List 2 | // 给定一个单链表,把所有的奇数节点和偶数节点分别排在一起。请注意,这里的奇数节点和偶数节点指的是节点编号的奇偶性,而不是节点的值的奇偶性。 3 | 4 | // 请尝试使用原地算法完成。你的算法的空间复杂度应为 O(1),时间复杂度应为 O(nodes),nodes为节点总数。 5 | 6 | // 示例: 7 | 8 | // 输入: 1->2->3->4->5->NULL 9 | // 输出: 1->3->5->2->4->NULL 10 | // 说明: 11 | 12 | // 应当保持奇数节点和偶数节点的相对顺序。 13 | // 链表的第一个节点视为奇数节点,第二个节点视为偶数节点,以此类推。 14 | 15 | /** 16 | * Definition for singly-linked list. 17 | * function ListNode(val) { 18 | * this.val = val; 19 | * this.next = null; 20 | * } 21 | */ 22 | /** 23 | * @param {ListNode} head 24 | * @return {ListNode} 25 | */ 26 | var oddEvenList = function(head) { 27 | if(head !== null) { 28 | var odd = head; 29 | var even = head.next; 30 | var evenHead = even; 31 | }else {return head;} 32 | while(even !== null && even.next !== null) { 33 | odd.next = odd.next.next; 34 | odd = odd.next; 35 | even.next = even.next.next; 36 | even = even.next; 37 | } 38 | odd.next = evenHead; 39 | return head; 40 | }; -------------------------------------------------------------------------------- /leetcode/top-interview-questions/math/divide-two-integers.js: -------------------------------------------------------------------------------- 1 | // 两数相除 2 | // 给定两个整数,被除数 dividend 和除数 divisor。将两数相除,要求不使用乘法、除法和 mod 运算符。 3 | 4 | // 返回被除数 dividend 除以除数 divisor 得到的商。 5 | 6 | // 示例 1: 7 | 8 | // 输入: dividend = 10, divisor = 3 9 | // 输出: 3 10 | // 示例 2: 11 | 12 | // 输入: dividend = 7, divisor = -3 13 | // 输出: -2 14 | // 说明: 15 | 16 | // 被除数和除数均为 32 位有符号整数。 17 | // 除数不为 0。 18 | // 假设我们的环境只能存储 32 位有符号整数,其数值范围是 [−231, 231 − 1]。本题中,如果除法结果溢出,则返回 231 − 1。 19 | 20 | /** 21 | * @param {number} dividend 22 | * @param {number} divisor 23 | * @return {number} 24 | */ 25 | 26 | var divide = function(dividend, divisor) { 27 | if (divisor === 0) return 0; 28 | if (dividend === 0) return 0; 29 | if (dividend === -2147483648 && divisor === -1) return 2147483647; 30 | var res = 0; 31 | var flag = true; 32 | if (dividend > 0 !== divisor > 0) flag = false; 33 | divisor = Math.abs(divisor); 34 | dividend = Math.abs(dividend); 35 | debugger; 36 | while(dividend >= divisor){ 37 | var tmp = divisor; 38 | var multiple = 1; 39 | while((dividend >> 1) >= tmp){ 40 | tmp = tmp << 1; 41 | multiple = multiple << 1; 42 | } 43 | dividend -= tmp; 44 | res += multiple; 45 | } 46 | return flag?res:-res; 47 | }; 48 | 49 | console.log(divide(-2147483648 ,1)); -------------------------------------------------------------------------------- /leetcode/top-interview-questions/math/excel-sheet-column-number.js: -------------------------------------------------------------------------------- 1 | // Excel表列序号 2 | // 与 Excel表列名称 问题类似。 3 | 4 | // 给定一个Excel表格中的列名称,返回其相应的列序号。 5 | 6 | // 示例: 7 | 8 | // A -> 1 9 | // B -> 2 10 | // C -> 3 11 | // ... 12 | // Z -> 26 13 | // AA -> 27 14 | // AB -> 28 15 | 16 | /** 17 | * @param {string} s 18 | * @return {number} 19 | */ 20 | var titleToNumber = function(s) { 21 | var len = s.length; 22 | var res = 0; 23 | for(var i = 0;i= denominator){ 29 | integer = Math.floor(numerator/denominator); 30 | numerator = numerator%denominator; 31 | } 32 | for(var i = 0; i < 19; i++){ 33 | if(numerator === 0){break;} 34 | if(arr.indexOf(numerator) === -1){ 35 | arr.push(numerator); 36 | }else{ 37 | loop = decimal.substring(arr.indexOf(numerator),decimal.length); 38 | decimal = `${decimal.substring(0,arr.indexOf(numerator))}(${loop})`; 39 | result = `${integer}.${decimal}`; 40 | return flag ? `-${result}` : result; 41 | } 42 | decimal += `${Math.floor(numerator*10/denominator)}`; 43 | numerator = numerator*10%denominator; 44 | } 45 | result = decimal === "" ? `${integer}` : `${integer}.${decimal}`; 46 | return flag ? `-${result}` : result; 47 | }; 48 | 49 | console.log(fractionToDecimal(-22,-2)); -------------------------------------------------------------------------------- /leetcode/top-interview-questions/math/happy-number.js: -------------------------------------------------------------------------------- 1 | // 快乐数 2 | // 写一个算法来判断一个数是不是“快乐数”。 3 | 4 | // 一个数是不是快乐是这么定义的:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1,或是无限循环但始终变不到 1。如果可以变为 1,那么这个数就是快乐数。 5 | 6 | // 案例: 19 是一个快乐数。 7 | 8 | // 1^2 + 9^2 = 82 9 | // 8^2 + 2^2 = 68 10 | // 6^2 + 8^2 = 100 11 | // 1^2 + 0^2 + 0^2 = 1 12 | 13 | /** 14 | * @param {number} n 15 | * @return {boolean} 16 | */ 17 | var isHappy = function(n) { 18 | var digitSquareSum = function(n){ 19 | var sum = 0; 20 | var tmp; 21 | while(n){ 22 | tmp = n%10; 23 | sum += tmp*tmp; 24 | n = Math.floor(n/10); 25 | } 26 | return sum; 27 | } 28 | var slow = n; 29 | var fast = n; 30 | do{ 31 | slow = digitSquareSum(slow); 32 | console.log(slow); 33 | fast = digitSquareSum(fast); 34 | console.log(fast); 35 | fast = digitSquareSum(fast); 36 | console.log(fast); 37 | console.log(';'); 38 | if(fast === 1){ 39 | return true; 40 | } 41 | }while(slow != fast); 42 | return false; 43 | }; 44 | 45 | var a = 19; 46 | console.log(isHappy(a)); 47 | 48 | // var isHappy = function(n) { 49 | // let ts = 0 50 | // function fn(m){ 51 | // var res = m.toString().split('').map(a => a * a ).reduce((c,d)=> c + d) 52 | // ts++ 53 | // if(ts>=10){ return false } 54 | 55 | // return (res == 1) ? true: fn(res) 56 | // } 57 | // return fn(n) 58 | // }; -------------------------------------------------------------------------------- /leetcode/top-interview-questions/math/pow.js: -------------------------------------------------------------------------------- 1 | // Pow(x, n) 2 | // 实现 pow(x, n) ,即计算 x 的 n 次幂函数。 3 | 4 | // 示例 1: 5 | 6 | // 输入: 2.00000, 10 7 | // 输出: 1024.00000 8 | // 示例 2: 9 | 10 | // 输入: 2.10000, 3 11 | // 输出: 9.26100 12 | // 示例 3: 13 | 14 | // 输入: 2.00000, -2 15 | // 输出: 0.25000 16 | // 解释: 2-2 = 1/22 = 1/4 = 0.25 17 | 18 | // 说明: 19 | 20 | // -100.0 < x < 100.0 21 | // n 是 32 位有符号整数,其数值范围是 [−2^31, 2^31 − 1] 。 22 | 23 | /** 24 | * @param {number} x 25 | * @param {number} n 26 | * @return {number} 27 | */ 28 | var myPow = function(x, n) { 29 | var result=1; 30 | var i = 1; 31 | var negative=false; 32 | var nnegative=false; 33 | if(n===0){ 34 | return 1; 35 | } 36 | if(n===1){ 37 | return x; 38 | } 39 | if(x===0){ 40 | return 0; 41 | } 42 | if((x<0)&&(n%2==1)){ 43 | negative = true; 44 | } 45 | if(n<0){ 46 | nnegative=true; 47 | } 48 | function abs(val){ 49 | if(val<0){ 50 | val = -val; 51 | } 52 | return val; 53 | } 54 | x = abs(x); 55 | n = abs(n); 56 | while(times<=n){ 57 | var maxx=x 58 | var maxn=1; 59 | while((maxn+maxn)<=(n-times+1)){ 60 | maxx=maxx*maxx; 61 | maxn=maxn*2; 62 | } 63 | times=times+maxn; 64 | result = result*maxx; 65 | 66 | } 67 | if(negative){ 68 | result=0-result; 69 | } 70 | if(nnegative){ 71 | result = 1/result; 72 | } 73 | return result; 74 | } 75 | 76 | console.log(myPow(2.00000,7)); -------------------------------------------------------------------------------- /leetcode/top-interview-questions/math/sqrt.js: -------------------------------------------------------------------------------- 1 | // x 的平方根 2 | // 实现 int sqrt(int x) 函数。 3 | 4 | // 计算并返回 x 的平方根,其中 x 是非负整数。 5 | 6 | // 由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。 7 | 8 | // 示例 1: 9 | 10 | // 输入: 4 11 | // 输出: 2 12 | // 示例 2: 13 | 14 | // 输入: 8 15 | // 输出: 2 16 | // 说明: 8 的平方根是 2.82842..., 17 | // 由于返回类型是整数,小数部分将被舍去。 18 | 19 | /** 20 | * @param {number} x 21 | * @return {number} 22 | */ 23 | 24 | //牛顿迭代法 25 | var mySqrt = function (x) { 26 | if(x > 0 && x <= 1){ 27 | return x; 28 | }; 29 | let r = x/2; 30 | while (r * r > x){ 31 | r = ((r + x / r) / 2) | 0; 32 | } 33 | return Math.floor(r); 34 | }; 35 | 36 | console.log(mySqrt(75)); 37 | 38 | 39 | // var mySqrt = function(x) { 40 | // var res = 1; 41 | // if(x>0&&x<=1){return x}; 42 | // while(res*res<=x){ 43 | // if((res+1)*(res+1)>x){return res;} 44 | // } 45 | // }; -------------------------------------------------------------------------------- /leetcode/top-interview-questions/others/majority-element.js: -------------------------------------------------------------------------------- 1 | // 求众数 2 | // 给定一个大小为 n 的数组,找到其中的众数。众数是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。 3 | 4 | // 你可以假设数组是非空的,并且数组中的众数永远存在。 5 | 6 | /** 7 | * @param {number[]} nums 8 | * @return {number} 9 | */ 10 | var majorityElement = function(nums) { 11 | var len = nums.length; 12 | var count = 0; 13 | var num; 14 | for(var i = 0; i < len; i++){ 15 | if(count === 0){ 16 | num = nums[i]; 17 | count++; 18 | }else if(num === nums[i]){ 19 | count++; 20 | }else{ 21 | count--; 22 | } 23 | } 24 | return num; 25 | }; 26 | 27 | var a = [1]; 28 | console.log(majorityElement(a)); -------------------------------------------------------------------------------- /leetcode/top-interview-questions/others/sum-of-two-integers.js: -------------------------------------------------------------------------------- 1 | // 两整数之和 2 | // 不使用运算符 + 和-,计算两整数a 、b之和。 3 | 4 | // 示例: 5 | // 若 a = 1 ,b = 2,返回 3。 6 | 7 | /** 8 | * @param {number} a 9 | * @param {number} b 10 | * @return {number} 11 | */ 12 | var getSum = function(a, b) { 13 | if(a === 0) return b; 14 | if(b === 0) return a; 15 | var carry; 16 | while(b !== 0){ 17 | carry = a & b; 18 | a = a ^ b; 19 | b = carry << 1; 20 | } 21 | return a; 22 | }; 23 | 24 | // var getSubtract = function(a, b) { 25 | // var borrow ; 26 | // while(b !== 0){ 27 | // borrow = ~a & b; 28 | // a = a ^ b; 29 | // b = borrow << 1; 30 | // } 31 | // return a; 32 | // }; 33 | 34 | 35 | console.log(getSubtract(666,777)); -------------------------------------------------------------------------------- /leetcode/top-interview-questions/others/task-scheduler.js: -------------------------------------------------------------------------------- 1 | // Task Scheduler 2 | // 给定一个用字符数组表示的 CPU 需要执行的任务列表。 3 | // 其中包含使用大写的 A - Z 字母表示的26 种不同种类的任务。 4 | // 任务可以以任意顺序执行,并且每个任务都可以在 1 个单位时间内执行完。 5 | // CPU 在任何一个单位时间内都可以执行一个任务,或者在待命状态。 6 | 7 | // 然而,两个相同种类的任务之间必须有长度为 n 的冷却时间, 8 | // 因此至少有连续 n 个单位时间内 CPU 在执行不同的任务,或者在待命状态。 9 | 10 | // 你需要计算完成所有任务所需要的最短时间。 11 | 12 | // 示例 1: 13 | 14 | // 输入: tasks = ["A","A","A","B","B","B"], n = 2 15 | // 输出: 8 16 | // 执行顺序: A -> B -> (待命) -> A -> B -> (待命) -> A -> B. 17 | // 注: 18 | 19 | // 1、任务的总个数为 [1, 10000]。 20 | // 2、n 的取值范围为 [0, 100]。 21 | 22 | /** 23 | * @param {character[]} tasks 24 | * @param {number} n 25 | * @return {number} 26 | */ 27 | var leastInterval = function(tasks, n) { 28 | let arr = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]; 29 | let len = tasks.length; 30 | tasks.forEach(val=>arr[val.charCodeAt() - 65]++) 31 | arr.sort((a,b)=>{return a-b;}); 32 | let i = 25; 33 | while(i >= 0 && arr[i] === arr[25]){ 34 | i--; 35 | } 36 | return Math.max(len,(arr[25] - 1) * (n + 1) + 25 - i); 37 | }; 38 | 39 | let a = ['A','A','A','B','B','B']; 40 | let n = 2; 41 | console.log(leastInterval(a,n)); -------------------------------------------------------------------------------- /leetcode/top-interview-questions/sorting-and-searching/find-peak-element.js: -------------------------------------------------------------------------------- 1 | // 寻找峰值 2 | // 峰值元素是指其值大于左右相邻值的元素。 3 | 4 | // 给定一个输入数组 nums,其中 num[i] ≠ num[i+1],找到峰值元素并返回其索引。 5 | 6 | // 数组可能包含多个峰值,在这种情况下,返回到任何一个峰值所在位置都可以。 7 | 8 | // 你可以假设 num[-1] = num[n] = -∞。 9 | 10 | // 示例 1: 11 | // 输入: nums = [1,2,3,1] 12 | // 输出: 2 13 | // 解释: 3 是峰值元素,你的函数应该返回其索引 2。 14 | 15 | // 示例 2: 16 | // 输入: nums = [1,2,1,3,5,6,4] 17 | // 输出: 1 or 5 18 | // 解释: 你的函数可以返回索引 1,其峰值元素为 2; 19 | // 或者返回索引 5, 其峰值元素为 6。 20 | // 说明: 21 | 22 | // 你的解法应该是 O(logN) 时间复杂度的。 23 | 24 | /** 25 | * @param {number[]} nums 26 | * @return {number} 27 | */ 28 | var findPeakElement = function(nums) { 29 | var start = 0; 30 | var end = nums.length - 1; 31 | var middle = Math.floor((end + start)/2);; 32 | while(start < end){ 33 | nums[middle] < nums[middle + 1] ? start = middle + 1 : end = middle; 34 | middle = Math.floor((end + start)/2); 35 | } 36 | return start; 37 | }; 38 | 39 | -------------------------------------------------------------------------------- /leetcode/top-interview-questions/sorting-and-searching/sort-colors.js: -------------------------------------------------------------------------------- 1 | // 分类颜色 2 | // 给定一个包含红色、白色和蓝色,一共 n 个元素的数组,原地对它们进行排序, 3 | // 使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。 4 | 5 | // 此题中,我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。 6 | 7 | // 注意: 8 | // 不能使用代码库中的排序函数来解决这道题。 9 | 10 | // 示例: 11 | 12 | // 输入: [2,0,2,1,1,0] 13 | // 输出: [0,0,1,1,2,2] 14 | // 进阶: 15 | 16 | // 一个直观的解决方案是使用计数排序的两趟扫描算法。 17 | // 首先,迭代计算出0、1 和 2 元素的个数,然后按照0、1、2的排序,重写当前数组。 18 | // 你能想出一个仅使用常数空间的一趟扫描算法吗? 19 | 20 | /** 21 | * @param {number[]} nums 22 | * @return {void} Do not return anything, modify nums in-place instead. 23 | */ 24 | var sortColors = function(nums) { 25 | var len = nums.length; 26 | var i = 0; 27 | while(icount[b] - count[a]); 31 | for(var j = 0; j < k; j++){ 32 | result.push(parseInt(index[j])); 33 | } 34 | return result; 35 | }; 36 | 37 | var nums = [-1,-1,-2,-3]; 38 | var k = 1; 39 | console.log(topKFrequent(nums,k)); -------------------------------------------------------------------------------- /leetcode/top-interview-questions/trees-and-graphs/construct-binary-tree-from-preorder-and-inorder-traversal.js: -------------------------------------------------------------------------------- 1 | // 从前序与中序遍历序列构造二叉树 2 | // 根据一棵树的前序遍历与中序遍历构造二叉树。 3 | 4 | // 注意: 5 | // 你可以假设树中没有重复的元素。 6 | 7 | // 例如,给出 8 | 9 | // 前序遍历 preorder = [3,9,20,15,7] 10 | // 中序遍历 inorder = [9,3,15,20,7] 11 | // 返回如下的二叉树: 12 | 13 | // 3 14 | // / \ 15 | // 9 20 16 | // / \ 17 | // 15 7 18 | 19 | 20 | /** 21 | * Definition for a binary tree node. 22 | * function TreeNode(val) { 23 | * this.val = val; 24 | * this.left = this.right = null; 25 | * } 26 | */ 27 | function TreeNode(val) { 28 | this.val = val; 29 | this.left = this.right = null; 30 | } 31 | 32 | 33 | /** 34 | * @param {number[]} preorder 35 | * @param {number[]} inorder 36 | * @return {TreeNode} 37 | */ 38 | var buildTree = function(preorder, inorder) { 39 | return traveral(0,0,inorder.length - 1,preorder,inorder); 40 | }; 41 | 42 | function traveral(preStart,inStart,inEnd,preorder,inorder) { 43 | if(preStart > preorder.length - 1 || inStart > inEnd) return null; 44 | var root = new TreeNode(preorder[preStart]); 45 | var inIndex = inorder.indexOf(root.val); 46 | root.left = traveral(preStart + 1,inStart,inIndex - 1,preorder,inorder); 47 | root.right = traveral(preStart + inIndex - inStart + 1,inIndex + 1,inEnd,preorder,inorder); 48 | return root; 49 | } 50 | 51 | var a = [1,2,3]; 52 | var b = [2,3,1]; 53 | console.log(buildTree(a,b)); -------------------------------------------------------------------------------- /leetcode/top-interview-questions/trees-and-graphs/inordertraversal.js: -------------------------------------------------------------------------------- 1 | // 中序遍历二叉树 2 | // 给定一个二叉树,返回它的中序 遍历。 3 | 4 | // 示例: 5 | 6 | // 输入: [1,null,2,3] 7 | // 1 8 | // \ 9 | // 2 10 | // / 11 | // 3 12 | 13 | // 输出: [1,3,2] 14 | 15 | /** 16 | * Definition for a binary tree node. 17 | * function TreeNode(val) { 18 | * this.val = val; 19 | * this.left = this.right = null; 20 | * } 21 | */ 22 | function TreeNode(val) { 23 | this.val = val; 24 | this.left = this.right = null; 25 | } 26 | 27 | /** 28 | * @param {TreeNode} root 29 | * @return {number[]} 30 | */ 31 | 32 | //迭代实现 33 | var inorderTraversal = function(root) { 34 | var stack = []; 35 | var res = []; 36 | while (root || stack.length) { 37 | // drill left 38 | while (root) { 39 | stack.push(root); 40 | root = root.left; 41 | } 42 | // print & go to right child 43 | root = stack.pop(); 44 | res.push(root.val); 45 | root = root.right; 46 | } 47 | return res; 48 | }; 49 | 50 | let a = new TreeNode(1); 51 | a.right = new TreeNode(2); 52 | a.right.left = new TreeNode(3); 53 | 54 | console.log(inorderTraversal(a)); 55 | 56 | // //递归实现 57 | // var inorderTraversal = function (root) { 58 | // let ans = [] 59 | // helper(root) 60 | // return ans 61 | // }; 62 | 63 | // function helper(node) { 64 | // if (node == null) return 65 | // if (node.left) helper(node.left) 66 | // ans.push(node.val) 67 | // if (node.right) helper(node.right) 68 | // } 69 | -------------------------------------------------------------------------------- /nowcoder/a-test-driven-js-assessment/alter-context.js: -------------------------------------------------------------------------------- 1 | // 改变上下文 2 | 3 | // 题目描述 4 | // 将函数 fn 的执行上下文改为 obj,返回 fn 执行后的值 5 | // 示例1 6 | // 输入 7 | // alterContext(function() {return this.greeting + ', ' + this.name + '!'; }, {name: 'Rebecca', greeting: 'Yo' }) 8 | // 输出 9 | // Yo, Rebecca! 10 | 11 | /** 12 | * @param {Function} fn 13 | * @param {Object} obj 14 | */ 15 | function alterContext(fn, obj) { 16 | return fn.call(obj); 17 | } -------------------------------------------------------------------------------- /nowcoder/a-test-driven-js-assessment/alter-objects.js: -------------------------------------------------------------------------------- 1 | // 批量改变对象的属性 2 | 3 | // 题目描述 4 | // 给定一个构造函数 constructor,请完成 alterObjects 方法,将 constructor 的所有实例的 greeting 属性指向给定的 greeting 变量。 5 | // 示例1 6 | // 输入 7 | // var C = function(name) {this.name = name; return this;}; 8 | // var obj1 = new C('Rebecca'); 9 | // alterObjects(C, 'What\'s up'); obj1.greeting; 10 | // 输出 11 | // What's up 12 | 13 | /** 14 | * @param {Function} constructor 15 | * @param {} greeting 16 | */ 17 | function alterObjects(constructor, greeting) { 18 | constructor.prototype.greeting = greeting; 19 | } -------------------------------------------------------------------------------- /nowcoder/a-test-driven-js-assessment/and.js: -------------------------------------------------------------------------------- 1 | // 且运算 2 | 3 | // 题目描述 4 | // 返回参数 a 和 b 的逻辑且运算结果 5 | // 示例1 6 | // 输入 7 | // false, true 8 | // 输出 9 | // false 10 | 11 | function and(a, b) { 12 | return a && b; 13 | } -------------------------------------------------------------------------------- /nowcoder/a-test-driven-js-assessment/append.js: -------------------------------------------------------------------------------- 1 | // 添加元素 2 | 3 | // 题目描述 4 | // 在数组 arr 末尾添加元素 item。不要直接修改数组 arr,结果返回新的数组 5 | // 示例1 6 | // 输入: [1, 2, 3, 4], 10 7 | // 输出: [1, 2, 3, 4, 10] 8 | 9 | /** 10 | * @param {Array []} arr 11 | * @param {Number} item 12 | * @return {Array} 13 | */ 14 | function append(arr, item) { 15 | // return arr.concat(item); 16 | 17 | var Arr = arr.slice(0); 18 | Arr.push(item); 19 | return Arr; 20 | } -------------------------------------------------------------------------------- /nowcoder/a-test-driven-js-assessment/args-as-array.js: -------------------------------------------------------------------------------- 1 | // 函数传参 2 | 3 | // 题目描述 4 | // 将数组 arr 中的元素作为调用函数 fn 的参数 5 | // 示例1 6 | // 输入 7 | // function (greeting, name, punctuation) {return greeting + ', ' + name + (punctuation || '!');}, ['Hello', 'Ellie', '!'] 8 | // 输出 9 | // Hello, Ellie! 10 | 11 | /** 12 | * @param {Function} fn 13 | * @param {Array} arr 14 | * @return {} 15 | */ 16 | function argsAsArray(fn, arr) { 17 | return fn.apply(this, arr); 18 | } -------------------------------------------------------------------------------- /nowcoder/a-test-driven-js-assessment/base10.js: -------------------------------------------------------------------------------- 1 | // 二进制转换2 2 | 3 | // 题目描述 4 | // 给定二进制字符串,将其换算成对应的十进制数字 5 | // 示例1 6 | // 输入 7 | // '11000000' 8 | // 输出 9 | // 192 10 | 11 | /** 12 | * @param {String} str 13 | * @return {Number} 14 | */ 15 | function base10(str) { 16 | // return parseInt(str,2); 17 | var res = 0; 18 | for (var i = 0, len = str.length; i < len; i++) { 19 | res += (str[i] & 1) << (len - i - 1); 20 | } 21 | return res; 22 | } 23 | -------------------------------------------------------------------------------- /nowcoder/a-test-driven-js-assessment/call-it.js: -------------------------------------------------------------------------------- 1 | // 使用 apply 调用函数 2 | 3 | // 题目描述 4 | // 实现函数 callIt,调用之后满足如下条件 5 | // 1、返回的结果为调用 fn 之后的结果 6 | // 2、fn 的调用参数为 callIt 的第一个参数之后的全部参数 7 | // 示例1 8 | // 输入 9 | // 无 10 | // 输出 11 | // 无 12 | 13 | /** 14 | * @param {Function} fn 15 | * @return {} 16 | */ 17 | function callIt(fn) { 18 | var arr = [].slice.call(arguments, 1); 19 | return fn.apply(this, arr); 20 | } 21 | -------------------------------------------------------------------------------- /nowcoder/a-test-driven-js-assessment/capture-three-numbers.js: -------------------------------------------------------------------------------- 1 | // 获取指定字符串 2 | 3 | // 题目描述 4 | // 给定字符串 str,检查其是否包含 连续3个数字 5 | // 1、如果包含,返回最新出现的 3 个数字的字符串 6 | // 2、如果不包含,返回 false 7 | // 示例1 8 | // 输入 9 | // '9876543' 10 | // 输出 11 | // 987 12 | 13 | /** 14 | * @param {String} str 15 | * @return {Boolean | String} 16 | */ 17 | function captureThreeNumbers(str) { 18 | return /(\d{3})/.test(str) ? RegExp.$1 : false; 19 | } -------------------------------------------------------------------------------- /nowcoder/a-test-driven-js-assessment/concat.js: -------------------------------------------------------------------------------- 1 | // 数组合并 2 | 3 | // 题目描述 4 | // 合并数组 arr1 和数组 arr2。不要直接修改数组 arr,结果返回新的数组 5 | // 示例1 6 | // 输入: [1, 2, 3, 4], ['a', 'b', 'c', 1] 7 | // 输出: [1, 2, 3, 4, 'a', 'b', 'c', 1] 8 | 9 | /** 10 | * @param {Array []} arr1 11 | * @param {Array []} arr2 12 | * @return {Array} 13 | */ 14 | function concat(arr1, arr2) { 15 | return arr1.concat(arr2); 16 | } -------------------------------------------------------------------------------- /nowcoder/a-test-driven-js-assessment/contains-number.js: -------------------------------------------------------------------------------- 1 | // 判断是否包含数字 2 | 3 | // 题目描述 4 | // 给定字符串 str,检查其是否包含数字,包含返回 true,否则返回 false 5 | // 示例1 6 | // 输入 7 | // 'abc123' 8 | // 输出 9 | // true 10 | 11 | /** 12 | * @param {String} str 13 | * @return {Boolean} 14 | */ 15 | function containsNumber(str) { 16 | return /\d/.test(str); 17 | } -------------------------------------------------------------------------------- /nowcoder/a-test-driven-js-assessment/contains-repeating-letter.js: -------------------------------------------------------------------------------- 1 | // 检查重复字符串 2 | 3 | // 题目描述 4 | // 给定字符串 str,检查其是否包含连续重复的字母(a-zA-Z),包含返回 true,否则返回 false 5 | // 示例1 6 | // 输入 7 | // 'rattler' 8 | // 输出 9 | // true 10 | 11 | /** 12 | * @param {String} str 13 | * @return {Boolean} 14 | */ 15 | function containsRepeatingLetter(str) { 16 | return /([a-zA-Z])\1/.test(str); 17 | } -------------------------------------------------------------------------------- /nowcoder/a-test-driven-js-assessment/convert-to-binary.js: -------------------------------------------------------------------------------- 1 | // 二进制转换3 2 | 3 | // 题目描述 4 | // 将给定数字转换成二进制字符串。如果字符串长度不足 8 位,则在前面补 0 到满8位。 5 | // 示例1 6 | // 输入 7 | // 65 8 | // 输出 9 | // 01000001 10 | 11 | /** 12 | * @param {Number} num 13 | * @return {String} 14 | */ 15 | function convertToBinary(num) { 16 | // return ("00000000" + num.toString(2)).slice(-8); 17 | var res = ""; 18 | while (num > 0) { 19 | res = (num & 1) + res; 20 | num = num >> 1; 21 | } 22 | return ('00000000' + res).slice(-8); 23 | } -------------------------------------------------------------------------------- /nowcoder/a-test-driven-js-assessment/count.js: -------------------------------------------------------------------------------- 1 | // 计数 2 | 3 | // 题目描述 4 | // 统计数组 arr 中值等于 item 的元素出现的次数 5 | // 示例1 6 | // 输入 7 | // [1, 2, 4, 4, 3, 4, 3], 4 8 | // 输出 9 | // 3 10 | 11 | /** 12 | * @param {Array []} arr 13 | * @param {Number | String | Object | Boolean | undefined | null} item 14 | * @return {Number} 15 | */ 16 | function count(arr, item) { 17 | // return arr.reduce(function (count, cur) { 18 | // return cur === item ? ++count : count; 19 | // }, 0); 20 | var count = 0; 21 | for (var i = 0, len = arr.length; i < len; i++) { 22 | arr[i] === item ? count++ : 0; 23 | } 24 | return count; 25 | } 26 | -------------------------------------------------------------------------------- /nowcoder/a-test-driven-js-assessment/create-module.js: -------------------------------------------------------------------------------- 1 | // 模块 2 | 3 | // 题目描述 4 | // 完成函数 createModule,调用之后满足如下要求: 5 | // 1、返回一个对象 6 | // 2、对象的 greeting 属性值等于 str1, name 属性值等于 str2 7 | // 3、对象存在一个 sayIt 方法,该方法返回的字符串为 greeting属性值 + ', ' + name属性值 8 | 9 | /** 10 | * @param {String} str1 11 | * @param {String} str2 12 | * @return {} 13 | */ 14 | function createModule(str1, str2) { 15 | return { 16 | greeting: str1, 17 | name: str2, 18 | sayIt: function () { 19 | return this.greeting + ', ' + this.name; 20 | } 21 | } 22 | } -------------------------------------------------------------------------------- /nowcoder/a-test-driven-js-assessment/curry-it.js: -------------------------------------------------------------------------------- 1 | // 柯里化 2 | 3 | // 题目描述 4 | // 已知 fn 为一个预定义函数,实现函数 curryIt,调用之后满足如下条件: 5 | // 1、返回一个函数 a,a 的 length 属性值为 1(即显式声明 a 接收一个参数) 6 | // 2、调用 a 之后,返回一个函数 b, b 的 length 属性值为 1 7 | // 3、调用 b 之后,返回一个函数 c, c 的 length 属性值为 1 8 | // 4、调用 c 之后,返回的结果与调用 fn 的返回值一致 9 | // 5、fn 的参数依次为函数 a, b, c 的调用参数 10 | // 示例1 11 | // 输入 12 | // var fn = function (a, b, c) {return a + b + c}; curryIt(fn)(1)(2)(3); 13 | // 输出 14 | // 6 15 | 16 | function curryIt(fn) { 17 | var args = [], 18 | len = fn.length; 19 | return function curry(arg) { 20 | args.push(arg); 21 | return args.length < len ? curry : fn.apply(this, args); 22 | } 23 | } -------------------------------------------------------------------------------- /nowcoder/a-test-driven-js-assessment/curtail.js: -------------------------------------------------------------------------------- 1 | // 删除数组第一个元素 2 | 3 | // 题目描述 4 | // 删除数组 arr 第一个元素。不要直接修改数组 arr,结果返回新的数组 5 | // 示例1 6 | // 输入: [1, 2, 3, 4], 10 7 | // 输出: [10, 1, 2, 3, 4] 8 | 9 | /** 10 | * @param {Array []} arr 11 | * @return {Array} 12 | */ 13 | function curtail(arr) { 14 | return arr.slice(1); 15 | } -------------------------------------------------------------------------------- /nowcoder/a-test-driven-js-assessment/duplicates.js: -------------------------------------------------------------------------------- 1 | // 查找重复元素 2 | 3 | // 题目描述 4 | // 找出数组 arr 中重复出现过的元素 5 | // 示例1 6 | // 输入 7 | // [1, 2, 4, 4, 3, 3, 1, 5, 3] 8 | // 输出 9 | // [1, 3, 4] 10 | 11 | /** 12 | * @param {Array []} arr 13 | * @return {Array} 14 | */ 15 | function duplicates(arr) { 16 | var obj = {},res = []; 17 | arr.forEach(function (v, i) { 18 | if (obj[v]) { 19 | obj[v].push(i); 20 | } else { 21 | obj[v] = [i] 22 | } 23 | }) 24 | for (var item in obj) { 25 | if (obj[item].length > 1) { 26 | res.push(arr[obj[item][0]]); 27 | } 28 | } 29 | return res; 30 | 31 | // var result = []; 32 | // arr.forEach(function(elem) { 33 | // if ( 34 | // arr.indexOf(elem) != arr.lastIndexOf(elem) && 35 | // result.indexOf(elem) == -1 36 | // ) { 37 | // result.push(elem); 38 | // } 39 | // }); 40 | // return result; 41 | } 42 | 43 | var a = duplicates([1, 2, 4, 4, 3, 3, 1, 5, 3]); 44 | console.log(a); 45 | -------------------------------------------------------------------------------- /nowcoder/a-test-driven-js-assessment/ends-with-vowel.js: -------------------------------------------------------------------------------- 1 | // 判断是否以元音字母结尾 2 | 3 | // 题目描述 4 | // 给定字符串 str,检查其是否以元音字母结尾 5 | // 1、元音字母包括 a,e,i,o,u,以及对应的大写 6 | // 2、包含返回 true,否则返回 false 7 | // 示例1 8 | // 输入 9 | // 'gorilla' 10 | // 输出 11 | // true 12 | 13 | /** 14 | * @param {String} str 15 | * @return {Boolean} 16 | */ 17 | function endsWithVowel(str) { 18 | return /[aeiou]$/i.test(str); 19 | } 20 | -------------------------------------------------------------------------------- /nowcoder/a-test-driven-js-assessment/find-all-occurrences.js: -------------------------------------------------------------------------------- 1 | // 查找元素位置 2 | 3 | // 题目描述 4 | // 在数组 arr 中,查找值与 item 相等的元素出现的所有位置 5 | // 示例1 6 | // 输入 7 | // 'abcdefabc' 8 | // 输出 9 | // [0, 6] 10 | 11 | /** 12 | * @param {Array []} arr 13 | * @param {Number | String | Object | Boolean | undefined | null} target 14 | * @return {Array} 15 | */ 16 | function findAllOccurrences(arr, target) { 17 | var result = []; 18 | arr.forEach(function(val, i) { 19 | val !== target || result.push(i); 20 | }); 21 | return result; 22 | } 23 | -------------------------------------------------------------------------------- /nowcoder/a-test-driven-js-assessment/function-function.js: -------------------------------------------------------------------------------- 1 | // 返回函数 2 | 3 | // 题目描述 4 | // 实现函数 functionFunction,调用之后满足如下条件: 5 | // 1、返回值为一个函数 f 6 | // 2、调用返回的函数 f,返回值为按照调用顺序的参数拼接,拼接字符为英文逗号加一个空格,即 ', ' 7 | // 3、所有函数的参数数量为 1,且均为 String 类型 8 | // 示例1 9 | // 输入 10 | // functionFunction('Hello')('world') 11 | // 输出 12 | // Hello, world 13 | 14 | /** 15 | * @param {Function} fn 16 | * @param {Object} obj 17 | * @return {} 18 | */ 19 | function functionFunction(str) { 20 | return function (s) { 21 | return str+", "+s; 22 | } 23 | } -------------------------------------------------------------------------------- /nowcoder/a-test-driven-js-assessment/functions.js: -------------------------------------------------------------------------------- 1 | // 正确的函数定义 2 | 3 | // 题目描述 4 | // 请修复给定的 js 代码中,函数定义存在的问题 5 | // 示例1 6 | // 输入 7 | // true 8 | // 输出 9 | // a 10 | 11 | // function functions(flag) { 12 | // if (flag) { 13 | // function getValue() { return 'a'; } 14 | // } else { 15 | // function getValue() { return 'b'; } 16 | // } 17 | 18 | // return getValue(); 19 | // } 20 | 21 | function functions(flag) { 22 | // 在代码块内使用变量声明 23 | if (flag) { 24 | var getValue = function () { return 'a'; } 25 | } else { 26 | var getValue = function () { return 'b'; } 27 | } 28 | 29 | return getValue(); 30 | } -------------------------------------------------------------------------------- /nowcoder/a-test-driven-js-assessment/globals.js: -------------------------------------------------------------------------------- 1 | // 避免全局变量 2 | 3 | // 题目描述 4 | // 给定的 js 代码中存在全局变量,请修复 5 | 6 | // function globals() { 7 | // myObject = { 8 | // name : 'Jory' 9 | // }; 10 | 11 | // return myObject; 12 | // } 13 | function globals() { 14 | // 函数内部使用var(ES6使用let、coust)定义为局部变量 15 | var myObject = { 16 | name : 'Jory' 17 | }; 18 | return myObject; 19 | } -------------------------------------------------------------------------------- /nowcoder/a-test-driven-js-assessment/identity.js: -------------------------------------------------------------------------------- 1 | // 完全等同 2 | 3 | // 题目描述 4 | // 判断 val1 和 val2 是否完全等同 5 | 6 | /** 7 | * @param {Number | String | Object | Boolean | undefined | null} val1 8 | * @param {Number | String | Object | Boolean | undefined | null} val2 9 | * @return {Boolean} 10 | */ 11 | function identity(val1, val2) { 12 | return val1 === val2; 13 | } -------------------------------------------------------------------------------- /nowcoder/a-test-driven-js-assessment/indexOf.js: -------------------------------------------------------------------------------- 1 | // 查找数组元素位置 2 | 3 | // 题目描述 4 | // 找出元素 item 在给定数组 arr 中的位置 5 | // 输出描述: 6 | // 如果数组中存在 item,则返回元素在数组中的位置,否则返回 -1 7 | // 输入: [ 1, 2, 3, 4 ], 3 8 | // 输出: 2 9 | 10 | /** 11 | * @param {Array []} arr 12 | * @param {Number} item 13 | * @return {Number} 14 | */ 15 | function indexOf(arr, item) { 16 | if (Array.prototype.indexOf) { 17 | return arr.indexOf(item); 18 | } else { 19 | for (var i = 0, len = arr.length; i < len; i++) { 20 | if (arr[i] === item) { 21 | return i; 22 | } 23 | } 24 | } 25 | return -1; 26 | } -------------------------------------------------------------------------------- /nowcoder/a-test-driven-js-assessment/insert.js: -------------------------------------------------------------------------------- 1 | // 添加元素 2 | 3 | // 题目描述 4 | // 在数组 arr 的 index 处添加元素 item。不要直接修改数组 arr,结果返回新的数组 5 | // 示例1 6 | // 输入 7 | // [1, 2, 3, 4], 'z', 2 8 | // 输出 9 | // [1, 2, 'z', 3, 4] 10 | 11 | /** 12 | * @param {Array []} arr 13 | * @param {Number | String | Object | Boolean | undefined | null} item 14 | * @param {Number} index 15 | * @return {Array} 16 | */ 17 | function insert(arr, item, index) { 18 | // return arr.slice(0, index).concat(item, arr.slice(index)); 19 | var Arr = arr.slice(0); 20 | Arr.splice(index,0,item); 21 | return Arr; 22 | } -------------------------------------------------------------------------------- /nowcoder/a-test-driven-js-assessment/is-usd.js: -------------------------------------------------------------------------------- 1 | // 判断是否符合USD格式 2 | 3 | // 题目描述 4 | // 给定字符串 str,检查其是否符合美元书写格式 5 | // 1、以 $ 开始 6 | // 2、整数部分,从个位起,满 3 个数字用 , 分隔 7 | // 3、如果为小数,则小数部分长度为 2 8 | // 4、正确的格式如:$1,023,032.03 或者 $2.03,错误的格式如:$3,432,12.12 或者 $34,344.3 9 | // 示例1 10 | // 输入 11 | // '$20,933,209.93' 12 | // 输出 13 | // true 14 | 15 | /** 16 | * @param {String} str 17 | * @return {Boolean} 18 | */ 19 | function isUSD(str) { 20 | return /^\$([1-9]\d{0,2}(,\d{3})*|0)(\.\d{2})?$/gm 21 | } -------------------------------------------------------------------------------- /nowcoder/a-test-driven-js-assessment/iterate.js: -------------------------------------------------------------------------------- 1 | // 属性遍历 2 | 3 | // 题目描述 4 | // 找出对象 obj 不在原型链上的属性(注意这题测试例子的冒号后面也有一个空格~) 5 | // 1、返回数组,格式为 key: value 6 | // 2、结果数组不要求顺序 7 | // 示例1 8 | // 输入 9 | // var C = function() {this.foo = 'bar'; this.baz = 'bim';}; 10 | // C.prototype.bop = 'bip'; 11 | // iterate(new C()); 12 | // 输出 13 | // ["foo: bar", "baz: bim"] 14 | 15 | /** 16 | * @param {Object} obj 17 | * @return {Object} 18 | */ 19 | function iterate(obj) { 20 | // return Object.getOwnPropertyNames(obj).map(function(key) { 21 | // return key + ": " + obj[key]; 22 | // }); 23 | 24 | var res = []; 25 | obj.__proto__ = null; 26 | for (var key in obj) { 27 | res.push(key + ': ' + obj[key]); 28 | } 29 | return res; 30 | } 31 | -------------------------------------------------------------------------------- /nowcoder/a-test-driven-js-assessment/make-closures.js: -------------------------------------------------------------------------------- 1 | // 使用闭包 2 | 3 | // 题目描述 4 | // 实现函数 makeClosures,调用之后满足如下条件: 5 | // 1、返回一个函数数组 result,长度与 arr 相同 6 | // 2、运行 result 中第 i 个函数,即 result[i](),结果与 fn(arr[i]) 相同 7 | // 示例1 8 | // 输入 9 | // [1, 2, 3], function (x) { 10 | // return x * x; 11 | // } 12 | // 输出 13 | // 4 14 | 15 | /** 16 | * @param {Array} arr 17 | * @param {Function} fn 18 | * @return {} 19 | */ 20 | function makeClosures(arr, fn) { 21 | var res = []; 22 | arr.forEach(function (v) { 23 | res.push(function () { 24 | return fn(v); 25 | }) 26 | }) 27 | return res; 28 | } -------------------------------------------------------------------------------- /nowcoder/a-test-driven-js-assessment/matches-pattern.js: -------------------------------------------------------------------------------- 1 | // 判断是否符合指定格式 2 | 3 | // 题目描述 4 | // 给定字符串 str,检查其是否符合如下格式 5 | // 1、XXX-XXX-XXXX 6 | // 2、其中 X 为 Number 类型 7 | // 示例1 8 | // 输入 9 | // '800-555-1212' 10 | // 输出 11 | // true 12 | 13 | /** 14 | * @param {String} str 15 | * @return {Boolean} 16 | */ 17 | function matchesPattern(str) { 18 | return /^\d{3}-\d{3}-\d{4}$/.test(str); 19 | } -------------------------------------------------------------------------------- /nowcoder/a-test-driven-js-assessment/multiply.js: -------------------------------------------------------------------------------- 1 | // 乘法 2 | 3 | // 题目描述 4 | // 求 a 和 b 相乘的值,a 和 b 可能是小数,需要注意结果的精度问题 5 | // 示例1 6 | // 输入 7 | // 3, 0.0001 8 | // 输出 9 | // 0.0003 10 | 11 | /** 12 | * @param {Number} a 13 | * @param {Number} b 14 | * @return {Number} 15 | */ 16 | function multiply(a, b) { 17 | a = a.toString(); 18 | b = b.toString(); 19 | var aLen = a.substring(a.indexOf(".") + 1).length; 20 | var bLen = a.substring(a.indexOf(".") + 1).length; 21 | return ( 22 | (a * Math.pow(10, aLen) * (b * Math.pow(10, bLen))) / 23 | Math.pow(10, aLen + bLen) 24 | ); 25 | } 26 | -------------------------------------------------------------------------------- /nowcoder/a-test-driven-js-assessment/or.js: -------------------------------------------------------------------------------- 1 | // 或运算 2 | 3 | // 返回参数 a 和 b 的逻辑或运算结果 4 | // 示例1 5 | // 输入 6 | // false, true 7 | // 输出 8 | // true 9 | 10 | function or(a, b) { 11 | return a || b; 12 | } 13 | -------------------------------------------------------------------------------- /nowcoder/a-test-driven-js-assessment/parse2Int.js: -------------------------------------------------------------------------------- 1 | // 正确的使用parseInt 2 | 3 | // 题目描述 4 | // 修改 js 代码中 parseInt 的调用方式,使之通过全部测试用例 5 | // 示例1 6 | // 输入 7 | // '12' 8 | // 输出 9 | // 12 10 | // 示例2 11 | // 输入 12 | // '12px' 13 | // 输出 14 | // 12 15 | // 示例3 16 | // 输入 17 | // '0x12' 18 | // 输出 19 | // 0 20 | 21 | /** 22 | * @param {Number | String | Object | Boolean | undefined | null} num 23 | * @return {Number} 24 | */ 25 | function parse2Int(num) { 26 | // parseInt函数接受两个参数,第一个为要转换为数字的字符,第二个为转换的进制(2-36) 27 | return parseInt(num,10); 28 | } -------------------------------------------------------------------------------- /nowcoder/a-test-driven-js-assessment/partial-using-arguments.js: -------------------------------------------------------------------------------- 1 | // 二次封装函数2 2 | 3 | // 题目描述 4 | // 实现函数 partialUsingArguments,调用之后满足如下条件: 5 | // 1、返回一个函数 result 6 | // 2、调用 result 之后,返回的结果与调用函数 fn 的结果一致 7 | // 3、fn 的调用参数为 partialUsingArguments 的第一个参数之后的全部参数以及 result 的调用参数 8 | 9 | function partialUsingArguments(fn) { 10 | var params = [].slice.call(arguments, 1); 11 | return function () { 12 | return fn.apply(this, params.concat([].slice.call(arguments))); 13 | } 14 | } -------------------------------------------------------------------------------- /nowcoder/a-test-driven-js-assessment/partial.js: -------------------------------------------------------------------------------- 1 | // 二次封装函数 2 | 3 | // 题目描述 4 | // 已知函数 fn 执行需要 3 个参数。请实现函数 partial,调用之后满足如下条件: 5 | // 1、返回一个函数 result,该函数接受一个参数 6 | // 2、执行 result(str3) ,返回的结果与 fn(str1, str2, str3) 一致 7 | // 示例1 8 | // 输入 9 | // var sayIt = function(greeting, name, punctuation) { return greeting + ', ' + name + (punctuation || '!'); }; partial(sayIt, 'Hello', 'Ellie')('!!!'); 10 | // 输出 11 | // Hello, Ellie!!! 12 | 13 | /** 14 | * @param {Function} fn 15 | * @param {String} str1 16 | * @param {String} str2 17 | * @return {} 18 | */ 19 | function partial(fn, str1, str2) { 20 | return function (str3) { 21 | return fn(str1, str2, str3); 22 | } 23 | } -------------------------------------------------------------------------------- /nowcoder/a-test-driven-js-assessment/prepend.js: -------------------------------------------------------------------------------- 1 | // 添加元素 2 | 3 | // 题目描述 4 | // 在数组 arr 开头添加元素 item。不要直接修改数组 arr,结果返回新的数组 5 | // 示例1 6 | // 输入: [1, 2, 3, 4], 10 7 | // 输出: [10, 1, 2, 3, 4] 8 | 9 | /** 10 | * @param {Array []} arr 11 | * @param {Number} item 12 | * @return {Array} 13 | */ 14 | function prepend(arr, item) { 15 | return [item].concat(arr); 16 | } -------------------------------------------------------------------------------- /nowcoder/a-test-driven-js-assessment/process-control.js: -------------------------------------------------------------------------------- 1 | // 流程控制 2 | 3 | // 题目描述 4 | // 实现 fizzBuzz 函数,参数 num 与返回值的关系如下: 5 | // 1、如果 num 能同时被 3 和 5 整除,返回字符串 fizzbuzz 6 | // 2、如果 num 能被 3 整除,返回字符串 fizz 7 | // 3、如果 num 能被 5 整除,返回字符串 buzz 8 | // 4、如果参数为空或者不是 Number 类型,返回 false 9 | // 5、其余情况,返回参数 num 10 | // 示例1 11 | // 输入 12 | // 15 13 | // 输出 14 | // fizzbuzz 15 | 16 | /** 17 | * @param {Number} num 18 | * @return {Number | String | Boolean} 19 | */ 20 | function fizzBuzz(num) { 21 | if (typeof num != 'number') return false; 22 | if (!(num % 15)) return 'fizzbuzz'; 23 | if (!(num % 3)) return 'fizz'; 24 | if (!(num % 5)) return 'buzz'; 25 | return num; 26 | } -------------------------------------------------------------------------------- /nowcoder/a-test-driven-js-assessment/remove-without-copy.js: -------------------------------------------------------------------------------- 1 | // 移除数组中的元素 2 | 3 | // 题目描述 4 | // 移除数组 arr 中的所有值与 item 相等的元素,直接在给定的 arr 数组上进行操作,并将结果返回 5 | // 示例1 6 | // 输入: [1, 2, 2, 3, 4, 2, 2], 2 7 | // 输出: [1, 3, 4] 8 | 9 | /** 10 | * @param {Array []} arr 11 | * @param {Number} item 12 | * @return {Array} 13 | */ 14 | function removeWithoutCopy(arr, item) { 15 | // arr.forEach(function(v, i) { 16 | // if (v === item) { 17 | // arr.splice(i, i + 1); 18 | // } 19 | // }); 20 | // return arr; 21 | 22 | var left = 0, 23 | right = 0, 24 | count = 0, 25 | len = arr.length; 26 | while (right < len) { 27 | while (arr[right] === item) { 28 | count++; 29 | right++; 30 | } 31 | arr[left++] = arr[right++]; 32 | } 33 | arr.length = len - count; 34 | return arr; 35 | } 36 | 37 | var a = removeWithoutCopy([1, 2, 2, 3, 4, 2, 2], 2); 38 | console.log(a); 39 | -------------------------------------------------------------------------------- /nowcoder/a-test-driven-js-assessment/remove.js: -------------------------------------------------------------------------------- 1 | // 移除数组中的元素 2 | 3 | // 题目描述 4 | // 移除数组 arr 中的所有值与 item 相等的元素。不要直接修改数组 arr,结果返回新的数组 5 | // 示例1 6 | // 输入: [1, 2, 3, 4, 2], 2 7 | // 输出: [1, 3, 4] 8 | 9 | /** 10 | * @param {Array []} arr 11 | * @param {Number} item 12 | * @return {Array} 13 | */ 14 | function remove(arr, item) { 15 | // return arr.filter(function(v) { 16 | // return v !== item; 17 | // }); 18 | var res = []; 19 | for (var i = 0, len = arr.length; i < len; i++) { 20 | if (arr[i] !== item) { 21 | res.push(arr[i]); 22 | } 23 | } 24 | return res; 25 | } -------------------------------------------------------------------------------- /nowcoder/a-test-driven-js-assessment/speak.js: -------------------------------------------------------------------------------- 1 | // 函数的上下文 2 | 3 | // 题目描述 4 | // 将函数 fn 的执行上下文改为 obj 对象 5 | // 示例1 6 | // 输入 7 | // function () {return this.greeting + ', ' + this.name + '!!!';}, {greeting: 'Hello', name: 'Rebecca'} 8 | // 输出 9 | // Hello, Rebecca!!! 10 | 11 | /** 12 | * @param {Function} fn 13 | * @param {Object} obj 14 | * @return {} 15 | */ 16 | function speak(fn, obj) { 17 | return fn.call(obj); 18 | } -------------------------------------------------------------------------------- /nowcoder/a-test-driven-js-assessment/square.js: -------------------------------------------------------------------------------- 1 | // 求二次方 2 | 3 | // 题目描述 4 | // 为数组 arr 中的每个元素求二次方。不要直接修改数组 arr,结果返回新的数组 5 | // 示例1 6 | // 输入 7 | // [1, 2, 3, 4] 8 | // 输出 9 | // [1, 4, 9, 16] 10 | 11 | /** 12 | * @param {Array []} arr 13 | * @return {Array} 14 | */ 15 | function square(arr) { 16 | return arr.map(function (v) { 17 | return v*v; 18 | }) 19 | } -------------------------------------------------------------------------------- /nowcoder/a-test-driven-js-assessment/sum.js: -------------------------------------------------------------------------------- 1 | // 数组求和 2 | 3 | // 题目描述 4 | // 计算给定数组 arr 中所有元素的总和 5 | // 输入描述: 6 | // 数组中的元素均为 Number 类型 7 | // 示例1 8 | // 输入: [ 1, 2, 3, 4 ] 9 | // 输出: 10 10 | 11 | /** 12 | * @param {Array []} arr 13 | * @return {Number} 14 | */ 15 | function sum(arr) { 16 | // return arr.reduce(function(sum, cur) { 17 | // return sum + cur; 18 | // }, 0); 19 | var sum = 0; 20 | for (var i = 0, len = arr.length; i < len; i++) { 21 | sum += arr[i]; 22 | } 23 | return sum; 24 | } 25 | -------------------------------------------------------------------------------- /nowcoder/a-test-driven-js-assessment/timer.js: -------------------------------------------------------------------------------- 1 | // 计时器 2 | 3 | // 题目描述 4 | // 实现一个打点计时器,要求 5 | // 1、从 start 到 end(包含 start 和 end),每隔 100 毫秒 console.log 一个数字,每次数字增幅为 1 6 | // 2、返回的对象中需要包含一个 cancel 方法,用于停止定时操作 7 | // 3、第一个数需要立即输出 8 | 9 | /** 10 | * @param {Number | String | Object | Boolean | undefined | null} val1 11 | * @param {Number | String | Object | Boolean | undefined | null} val2 12 | * @return {Boolean} 13 | */ 14 | function count(start, end) { 15 | if (start <= end) { 16 | console.log(start++); 17 | timer = setTimeout(function () { 18 | count(start, end); 19 | }, 100); 20 | } 21 | return { 22 | cancel: function () { 23 | clearTimeout(timer); 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /nowcoder/a-test-driven-js-assessment/truncate.js: -------------------------------------------------------------------------------- 1 | // 删除数组最后一个元素 2 | 3 | // 题目描述 4 | // 删除数组 arr 最后一个元素。不要直接修改数组 arr,结果返回新的数组 5 | // 示例1 6 | // 输入: [1, 2, 3, 4] 7 | // 输出: [1, 2, 3] 8 | 9 | /** 10 | * @param {Array []} arr 11 | * @return {Array} 12 | */ 13 | function truncate(arr) { 14 | // return arr.slice(0, arr.length - 1); 15 | 16 | var Arr = arr.slice(); 17 | Arr.pop(); 18 | return Arr; 19 | } -------------------------------------------------------------------------------- /nowcoder/a-test-driven-js-assessment/use-arguments.js: -------------------------------------------------------------------------------- 1 | // 使用 arguments 2 | 3 | // 题目描述 4 | // 函数 useArguments 可以接收 1 个及以上的参数。请实现函数 useArguments,返回所有调用参数相加后的结果。本题的测试参数全部为 Number 类型,不需考虑参数转换。 5 | // 示例1 6 | // 输入 7 | // 1, 2, 3, 4 8 | // 输出 9 | // 10 10 | 11 | function useArguments() { 12 | var sum = 0; 13 | for (var i = 0, len = arguments.length; i < len; i++) { 14 | sum += arguments[i]; 15 | } 16 | return sum; 17 | 18 | // var sum = 0, 19 | // arr = Array.prototype.slice.call(arguments); 20 | // for (var i = 0; i < arr.length; i++) { 21 | // sum += arguments[i]; 22 | // } 23 | // return sum; 24 | } 25 | -------------------------------------------------------------------------------- /nowcoder/a-test-driven-js-assessment/value-at-bit.js: -------------------------------------------------------------------------------- 1 | // 二进制转换 2 | 3 | // 题目描述 4 | // 获取数字 num 二进制形式第 bit 位的值。注意: 5 | // 1、bit 从 1 开始 6 | // 2、返回 0 或 1 7 | // 3、举例:2 的二进制为 10,第 1 位为 0,第 2 位为 1 8 | // 示例1 9 | // 输入 10 | // 128, 8 11 | // 输出 12 | // 1 13 | 14 | /** 15 | * @param {Number} num 16 | * @param {Number} bit 17 | * @return {Number} 18 | */ 19 | function valueAtBit(num, bit) { 20 | return num >> (bit - 1) & 1; 21 | } -------------------------------------------------------------------------------- /nowcoder/front-end-challenge/bind-this.js: -------------------------------------------------------------------------------- 1 | // 修改 this 指向 2 | 3 | // 题目描述 4 | // 封装函数 f,使 f 的 this 指向指定的对象 5 | 6 | /* 7 | * @param {Function} f 8 | * @param {Object} oTarget 9 | * @return {Function} 10 | */ 11 | function bindThis(f, oTarget) { 12 | return f.bind(oTarget); 13 | } 14 | 15 | -------------------------------------------------------------------------------- /nowcoder/front-end-challenge/common-parent-node.js: -------------------------------------------------------------------------------- 1 | // dom 节点查找 2 | 3 | // 题目描述 4 | // 查找两个节点的最近的一个共同父节点,可以包括节点自身 5 | // 输入描述: 6 | // oNode1 和 oNode2 在同一文档中,且不会为相同的节点 7 | 8 | /* 9 | * @param {Dom} oNode1 10 | * @param {Dom} oNode2 11 | * @return {Boolean} 12 | */ 13 | function commonParentNode(oNode1, oNode2) { 14 | while (oNode1) { 15 | if (oNode1.contains(oNode2)) return oNode1; 16 | oNode1 = oNode1.parentNode; 17 | } 18 | return false; 19 | } -------------------------------------------------------------------------------- /nowcoder/front-end-challenge/css-style2-dom-style.js: -------------------------------------------------------------------------------- 1 | // 将字符串转换为驼峰格式 2 | 3 | // 题目描述 4 | // css 中经常有类似 background-image 这种通过 - 连接的字符,通过 javascript 设置样式的时候需要将这种样式转换成 backgroundImage 驼峰格式,请完成此转换功能 5 | // 1. 以 - 为分隔符,将第二个起的非空单词首字母转为大写 6 | // 2. -webkit-border-image 转换后的结果为 webkitBorderImage 7 | // 示例1 8 | // 输入 9 | // 'font-size' 10 | // 输出 11 | // fontSize 12 | 13 | /* 14 | * @param {String} sName 15 | * @return {String} 16 | */ 17 | function cssStyle2DomStyle(sName) { 18 | return sName.replace(/^-/g,"").replace(/-./g,function(s){ 19 | return s[1].toUpperCase(); 20 | }); 21 | } 22 | 23 | var a = cssStyle2DomStyle("-webkit-border-image"); 24 | console.log(a); -------------------------------------------------------------------------------- /nowcoder/front-end-challenge/date-format.js: -------------------------------------------------------------------------------- 1 | // 时间格式化输出 2 | 3 | // 题目描述 4 | // 按所给的时间格式输出指定的时间 5 | // 格式说明 6 | // 对于 2014.09.05 13:14:20 7 | // yyyy: 年份,2014 8 | // yy: 年份,14 9 | // MM: 月份,补满两位,09 10 | // M: 月份, 9 11 | // dd: 日期,补满两位,05 12 | // d: 日期, 5 13 | // HH: 24制小时,补满两位,13 14 | // H: 24制小时,13 15 | // hh: 12制小时,补满两位,01 16 | // h: 12制小时,1 17 | // mm: 分钟,补满两位,14 18 | // m: 分钟,14 19 | // ss: 秒,补满两位,20 20 | // s: 秒,20 21 | // w: 星期,为 ['日', '一', '二', '三', '四', '五', '六'] 中的某一个,本 demo 结果为 五 22 | // 示例1 23 | // 输入 24 | // formatDate(new Date(1409894060000), 'yyyy-MM-dd HH:mm:ss 星期w') 25 | // 输出 26 | // 2014-09-05 13:14:20 星期五 27 | 28 | /* 29 | * @param {Date} t 30 | * @param {String} str 31 | * @return {String} 32 | */ 33 | function formatDate(t, str) { 34 | var obj = { 35 | yyyy: t.getFullYear(), 36 | yy: ("" + t.getFullYear()).slice(-2), 37 | M: t.getMonth() + 1, 38 | MM: ("0" + (t.getMonth() + 1)).slice(-2), 39 | d: t.getDate(), 40 | dd: ("0" + t.getDate()).slice(-2), 41 | H: t.getHours(), 42 | HH: ("0" + t.getHours()).slice(-2), 43 | h: t.getHours() % 12, 44 | hh: ("0" + t.getHours() % 12).slice(-2), 45 | m: t.getMinutes(), 46 | mm: ("0" + t.getMinutes()).slice(-2), 47 | s: t.getSeconds(), 48 | ss: ("0" + t.getSeconds()).slice(-2), 49 | w: ['日', '一', '二', '三', '四', '五', '六'][t.getDay()] 50 | }; 51 | return str.replace(/([a-zA-Z]+)/g, function (key) { 52 | return obj[key] 53 | }); 54 | } -------------------------------------------------------------------------------- /nowcoder/front-end-challenge/fibonacci.js: -------------------------------------------------------------------------------- 1 | // 斐波那契数列 2 | 3 | // 题目描述 4 | // 用 JavaScript 实现斐波那契数列函数,返回第n个斐波那契数。 f(1) = 1, f(2) = 1 等 5 | 6 | /* 7 | * @param {Number} n 8 | * @return {Number} 9 | */ 10 | function fibonacci(n) { 11 | var f = function (n, ac1, ac2) { 12 | return n < 3 ? ac2 : f(--n, ac2, ac1 + ac2); 13 | } 14 | return f(n, 1, 1); 15 | } 16 | 17 | var a = fibonacci(500); 18 | console.log(a); -------------------------------------------------------------------------------- /nowcoder/front-end-challenge/get-url-param.js: -------------------------------------------------------------------------------- 1 | // 获取 url 参数 2 | 3 | // 题目描述 4 | // 获取 url 中的参数 5 | // 1. 指定参数名称,返回该参数的值 或者 空字符串 6 | // 2. 不指定参数名称,返回全部的参数对象 或者 {} 7 | // 3. 如果存在多个同名参数,则返回数组 8 | 9 | // 示例1 10 | // 输入 11 | // http://www.nowcoder.com?key=1&key=2&key=3&test=4#hehe 12 | // 输出 13 | // [1, 2, 3] 14 | 15 | /* 16 | * @param {String} sUrl 17 | * @param {String} sKey 18 | * @return {String | Array | Object} 19 | */ 20 | function getUrlParam(sUrl, sKey) { 21 | var res = ''; 22 | sKey 23 | ? sUrl.replace(new RegExp('\\??' + sKey + '=(\\w+)&?', 'g'), function (m, p1) { 24 | res = res ? [].concat(res, p1) : p1; 25 | }) 26 | : sUrl.replace(/\??(\w+)=(\w+)&?/g, function (m, p1, p2) { 27 | res = res || {}; 28 | res[p1] = res[p1] 29 | ? [].concat(res[p1], p2) 30 | : p2; 31 | }) 32 | return res; 33 | } 34 | 35 | var a = getUrlParam('http://www.nowcoder.com?key=1&key=2&key=3&test=4#hehe','test') 36 | console.log(a) -------------------------------------------------------------------------------- /nowcoder/front-end-challenge/is-available-email.js: -------------------------------------------------------------------------------- 1 | // 邮箱字符串判断 2 | 3 | // 题目描述 4 | // 判断输入是否是正确的邮箱格式 5 | // 输入描述: 6 | // 邮箱字符串 7 | // 输出描述: 8 | // true表示格式正确 9 | 10 | /* 11 | * @param {String} sEmail 12 | * @return {Boolean} 13 | */ 14 | function isAvailableEmail(sEmail) { 15 | var reg = /^(\w)+(\.\w+)*@(\w)+(\.\w+)+/g; 16 | return reg.test(sEmail); 17 | } -------------------------------------------------------------------------------- /nowcoder/front-end-challenge/namespace.js: -------------------------------------------------------------------------------- 1 | // 根据包名,在指定空间中创建对象 2 | 3 | // 题目描述 4 | // 根据包名,在指定空间中创建对象 5 | // 输入描述: 6 | // namespace({a: {test: 1, b: 2}}, 'a.b.c.d') 7 | // 输出描述: 8 | // {a: {test: 1, b: {c: {d: {}}}}} 9 | 10 | /* 11 | * @param {Object} oNamespace 12 | * @param {String} sPackage 13 | * @return {Object} 14 | */ 15 | function namespace(oNamespace, sPackage) { 16 | var res = oNamespace; 17 | var obj = res; 18 | sPackage.replace(/(\w+)\.?/g, function (m, p) { 19 | obj[p] = typeof obj[p] === 'object' ? obj[p] : {}; 20 | obj = obj[p]; 21 | }) 22 | return res; 23 | } 24 | 25 | var a = namespace({a: {test: 1, b: 2}}, 'a.b.c.d') 26 | console.log(a); -------------------------------------------------------------------------------- /nowcoder/front-end-challenge/rgb2hex.js: -------------------------------------------------------------------------------- 1 | // 颜色字符串转换 2 | 3 | // 题目描述 4 | // 将 rgb 颜色字符串转换为十六进制的形式,如 rgb(255, 255, 255) 转为 #ffffff 5 | // 1. rgb 中每个 , 后面的空格数量不固定 6 | // 2. 十六进制表达式使用六位小写字母 7 | // 3. 如果输入不符合 rgb 格式,返回原始输入 8 | // 示例1 9 | // 输入 10 | // 'rgb(255, 255, 255)' 11 | // 输出 12 | // #ffffff 13 | 14 | /* 15 | * @param {String} sRGB 16 | * @return {String} 17 | */ 18 | function rgb2hex(sRGB) { 19 | var reg = /rgb\((\d+),\s*(\d+),\s*(\d+)\)/i; 20 | var res = sRGB.match(reg); 21 | if (res) { 22 | var str = '#'; 23 | for(var i = 1; i <= 3; i++){ 24 | var num = parseInt(res[i]); 25 | if (num < 0 ||num > 255){ 26 | return sRGB; 27 | } 28 | str += num < 16 ? '0' + num.toString(16) : num.toString(16); 29 | } 30 | return str; 31 | } else { 32 | return sRGB; 33 | } 34 | } -------------------------------------------------------------------------------- /nowcoder/front-end-challenge/str-length.js: -------------------------------------------------------------------------------- 1 | // 获取字符串的长度 2 | 3 | // 题目描述 4 | // 如果第二个参数 bUnicode255For1 === true,则所有字符长度为 1 5 | // 否则如果字符 Unicode 编码 > 255 则长度为 2 6 | // 示例1 7 | // 输入 8 | // 'hello world, 牛客', false 9 | // 输出 10 | // 17 11 | 12 | /* 13 | * @param {String} s 14 | * @param {Boolean}} bUnicode255For1 15 | * @return {Number} 16 | */ 17 | function strLength(s, bUnicode255For1) { 18 | var len = s.length; 19 | if (!bUnicode255For1) { 20 | for (var i = 0; i < len; i++) { 21 | if (s.charCodeAt(i) > 255) { 22 | len++; 23 | } 24 | } 25 | } 26 | return len; 27 | } 28 | 29 | var a = strLength('hello world, 牛客', false); 30 | console.log(a); -------------------------------------------------------------------------------- /nowcoder/front-end-challenge/string-count.js: -------------------------------------------------------------------------------- 1 | // 字符串字符统计 2 | 3 | // 题目描述 4 | // 统计字符串中每个字符的出现频率,返回一个 Object,key 为统计字符,value 为出现频率 5 | // 1. 不限制 key 的顺序 6 | // 2. 输入的字符串参数不会为空 7 | // 3. 忽略空白字符 8 | // 示例1 9 | // 输入 10 | // 'hello world' 11 | // 输出 12 | // {h: 1, e: 1, l: 3, o: 2, w: 1, r: 1, d: 1} 13 | 14 | /* 15 | * @param {String} sName 16 | * @return {Object} 17 | */ 18 | function count(str) { 19 | var res = {}; 20 | str.replace(/\S/g,function(s){ 21 | !res[s] ? res[s]=1 : res[s]++; 22 | }) 23 | return res; 24 | } 25 | 26 | var a = count('hello world'); 27 | console.log(a); -------------------------------------------------------------------------------- /nowcoder/front-end-challenge/uniq.js: -------------------------------------------------------------------------------- 1 | // 数组去重 2 | 3 | // 题目描述 4 | // 为 Array 对象添加一个去除重复项的方法 5 | // 示例1 6 | // 输入 7 | // [false, true, undefined, null, NaN, 0, 1, {}, {}, 'a', 'a', NaN] 8 | // 输出 9 | // [false, true, undefined, null, NaN, 0, 1, {}, {}, 'a'] 10 | 11 | Array.prototype.uniq = function () { 12 | var res = []; 13 | var arr = this; 14 | var hasNaN = false; 15 | var include = function (array, val) { 16 | for (var i = 0, l = array.length; i < l; i++) { 17 | if (array[i] === val) { 18 | return true; 19 | } 20 | } 21 | return false; 22 | }; 23 | for (var i = 0, len = arr.length; i < len; i++) { 24 | var val = arr[i]; 25 | if (!include(res, val)) { 26 | if (val !== val) { 27 | if (!hasNaN) { 28 | hasNaN = true; 29 | res.push(NaN); 30 | } 31 | } else { 32 | res.push(val); 33 | } 34 | } 35 | } 36 | return res; 37 | } 38 | 39 | var a = [false, true, undefined, null, NaN, 0, 1, {}, {}, 'a', 'a', NaN] 40 | console.log(a.uniq()); -------------------------------------------------------------------------------- /nowcoder/jz-offer/add.js: -------------------------------------------------------------------------------- 1 | // 不用加减乘除做加法 2 | 3 | // 题目描述 4 | // 写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。 5 | 6 | /** 7 | * @param {Number} num1 8 | * @param {Number} num2 9 | * @return {Number} 10 | */ 11 | function Add(num1, num2) { 12 | while (num1 !== 0) { 13 | var tmp = num1 ^ num2; 14 | num1 = (num1 & num2) << 1; 15 | num2 = tmp; 16 | } 17 | return num2; 18 | } 19 | -------------------------------------------------------------------------------- /nowcoder/jz-offer/binary-search-tree-and-doubly-linked-list.js: -------------------------------------------------------------------------------- 1 | // 二叉搜索树与双向链表 2 | 3 | // 题目描述 4 | // 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。 5 | // 要求不能创建任何新的结点,只能调整树中结点指针的指向。 6 | 7 | /* function TreeNode(x) { 8 | this.val = x; 9 | this.left = null; 10 | this.right = null; 11 | } */ 12 | 13 | /** 14 | * @param {TreeNode []} pRootOfTree 15 | * @return {LinkedList} pRootOfTree 16 | */ 17 | 18 | function Convert(pRootOfTree) { 19 | if (pRootOfTree == null) return null; 20 | let [stack, p, pre, isFirst] = [[], pRootOfTree, null, true]; 21 | while (p !== null || stack.length !== 0) { 22 | while (p !== null) { 23 | stack.push(p); 24 | p = p.left; 25 | } 26 | p = stack.pop(); 27 | if (isFirst) { 28 | pRootOfTree = p; 29 | pre = pRootOfTree; 30 | isFirst = false; 31 | } else { 32 | pre.right = p; 33 | p.left = pre; 34 | pre = p; 35 | } 36 | p = p.right; 37 | } 38 | return pRootOfTree; 39 | } 40 | -------------------------------------------------------------------------------- /nowcoder/jz-offer/clockwise-print-matrix.js: -------------------------------------------------------------------------------- 1 | // 顺时针打印矩阵 2 | 3 | // 题目描述 4 | // 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字, 5 | // 例如,如果输入如下4 X 4矩阵: 6 | // 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 7 | // 则依次打印出数字: 8 | // 1,2,3,4,8,12,16,15,14,13,9,5,6,7,11,10. 9 | 10 | /** 11 | * @param {Array[][]} matrix 12 | * @return {Array} 13 | */ 14 | function printMatrix(matrix) { 15 | let [row, col, res] = [matrix.length, matrix[0].length, []]; 16 | let circle = Math.floor(((row < col ? row : col) - 1) / 2) + 1; 17 | for (let i = 0; i < circle; i++) { 18 | // left -> right 19 | for (let j = i; j < col - i; j++) { 20 | res.push(matrix[i][j]); 21 | } 22 | // top -> botttom 23 | for (let j = i + 1; j < row - i; j++) { 24 | res.push(matrix[j][col - i - 1]); 25 | } 26 | // right -> left 27 | for (let j = col - i - 2; j >= i && row - i - 1 != i; j--) { 28 | res.push(matrix[row - i - 1][j]); 29 | } 30 | // bottom -> top 31 | for (let j = row - i - 2; j > i && col - i - 1 != i; j--) { 32 | res.push(matrix[j][i]); 33 | } 34 | } 35 | return res; 36 | } 37 | 38 | let arr = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]; 39 | 40 | console.log(printMatrix(arr)); 41 | -------------------------------------------------------------------------------- /nowcoder/jz-offer/clone-complex-chain.js: -------------------------------------------------------------------------------- 1 | // 复杂链表的复制 2 | 3 | // 题目描述 4 | // 输入一个复杂链表(每个节点中有节点值, 5 | // 以及两个指针,一个指向下一个节点, 6 | // 另一个特殊指针指向任意一个节点), 7 | // 返回结果为复制后复杂链表的head。 8 | // (注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空) 9 | 10 | /*function RandomListNode(x){ 11 | this.label = x; 12 | this.next = null; 13 | this.random = null; 14 | }*/ 15 | 16 | /** 17 | * @param {RandomListNode} pHead 18 | * @return {RandomListNode} 19 | */ 20 | function Clone(pHead) { 21 | if (!pHead) { 22 | return null; 23 | } 24 | let curNode, node, clone, tmp; 25 | curNode = pHead; 26 | while (curNode) { 27 | node = new RandomListNode(curNode.label); 28 | node.next = curNode.next; 29 | curNode.next = node; 30 | curNode = node.next; 31 | } 32 | curNode = pHead; 33 | while (curNode) { 34 | node = curNode.next; 35 | if (curNode.random) { 36 | node.random = curNode.random.next; 37 | } 38 | curNode = node.next; 39 | } 40 | clone = pHead.next; 41 | curNode = pHead; 42 | while (curNode.next) { 43 | tmp = curNode.next; 44 | curNode.next = tmp.next; 45 | curNode = tmp; 46 | } 47 | return clone; 48 | } 49 | -------------------------------------------------------------------------------- /nowcoder/jz-offer/delete-duplication.js: -------------------------------------------------------------------------------- 1 | // 删除链表中重复的结点 2 | 3 | // 题目描述 4 | // 在一个排序的链表中,存在重复的结点, 5 | // 请删除该链表中重复的结点,重复的结点不保留, 6 | // 返回链表头指针。 7 | // 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5 8 | 9 | function ListNode(x) { 10 | this.val = x; 11 | this.next = null; 12 | } 13 | 14 | /** 15 | * @param {ListNode} pHead 16 | * @return {ListNode} 17 | */ 18 | function deleteDuplication(pHead) { 19 | const list = new ListNode(-1); 20 | list.next = pHead; 21 | let p = pHead; 22 | let prev = list; 23 | while (p !== null && p.next !== null) { 24 | if (p.val === p.next.val) { 25 | let val = p.val; 26 | while (p !== null && p.val === val) { 27 | p = p.next; 28 | } 29 | prev.next = p; 30 | } else { 31 | prev = p; 32 | p = p.next; 33 | } 34 | } 35 | return list.next; 36 | } 37 | 38 | const list = new ListNode(-1); 39 | let p = list; 40 | let arr = [1, 2, 3, 3, 4, 4, 5]; 41 | arr.forEach(val => { 42 | p.next = new ListNode(val); 43 | p = p.next; 44 | }); 45 | 46 | console.log(deleteDuplication(list.next)); 47 | -------------------------------------------------------------------------------- /nowcoder/jz-offer/duplicate.js: -------------------------------------------------------------------------------- 1 | // 数组中重复的数字 2 | 3 | // 题目描述 4 | // 在一个长度为n的数组里的所有数字都在0到n-1的范围内。 5 | // 数组中某些数字是重复的,但不知道有几个数字是重复的。 6 | // 也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 7 | // 例如,如果输入长度为7的数组{2,3,1,0,2,5,3}, 8 | // 那么对应的输出是第一个重复的数字2。 9 | 10 | /** 11 | * @param {Array} numbers 12 | * @param {Array} duplication 13 | * @return {Boolean} 14 | */ 15 | function duplicate(numbers, duplication) { 16 | //这里要特别注意~找到任意重复的一个值并赋值到duplication[0] 17 | //函数返回true/false 18 | for (let i = 0, len = numbers.length; i < len; i++) { 19 | if (numbers[i] !== i) { 20 | if (numbers[i] == numbers[numbers[i]]) { 21 | duplication[0] = numbers[i]; 22 | return true; 23 | } 24 | [numbers[numbers[i]], numbers[i]] = [numbers[i], numbers[numbers[i]]]; 25 | } 26 | } 27 | return false; 28 | } 29 | -------------------------------------------------------------------------------- /nowcoder/jz-offer/entry-node-of-loop.js: -------------------------------------------------------------------------------- 1 | // 链表中环的入口结点 2 | 3 | // 题目描述 4 | // 给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。 5 | 6 | /*function ListNode(x){ 7 | this.val = x; 8 | this.next = null; 9 | }*/ 10 | 11 | /** 12 | * @param {ListNode} pHead 13 | * @return {ListNode|null} 14 | */ 15 | function EntryNodeOfLoop(pHead) { 16 | if (pHead === null || pHead.next === null || pHead.next.next === null) 17 | return null; 18 | let [slow, fast] = [pHead, pHead]; 19 | while (fast !== null) { 20 | slow = slow.next; 21 | fast = fast.next; 22 | if (fast !== null) { 23 | fast = fast.next; 24 | } else { 25 | return null; 26 | } 27 | if (fast === slow) break; 28 | } 29 | fast = pHead; 30 | while (fast !== slow) { 31 | fast = fast.next; 32 | slow = slow.next; 33 | } 34 | return fast; 35 | } 36 | -------------------------------------------------------------------------------- /nowcoder/jz-offer/fibonacci.js: -------------------------------------------------------------------------------- 1 | // 大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项。 2 | // n<=39 3 | 4 | /** 5 | * @param {number[]} n 6 | * @return {number} 7 | */ 8 | // function Fibonacci(n) { 9 | // if (typeof n !== "number") { 10 | // return false; 11 | // } 12 | // if (n === 0) { 13 | // return 0 14 | // } 15 | // var res = 0; 16 | // var tmp = 1; 17 | // while (n--) { 18 | // tmp += res; 19 | // res = tmp - res; 20 | // } 21 | // return res; 22 | // } 23 | 24 | function Fibonacci(n) { 25 | let [res, ac1, ac2] = [0, 1, 1]; 26 | for (let i = 0; i < n; i++) { 27 | res = ac1; 28 | ac1 = ac2; 29 | ac2 = res + ac2; 30 | } 31 | return res; 32 | } 33 | 34 | console.log(Fibonacci(1000)); -------------------------------------------------------------------------------- /nowcoder/jz-offer/find-continuous-sequence.js: -------------------------------------------------------------------------------- 1 | // 和为S的连续正数序列 2 | 3 | // 题目描述 4 | // 小明很喜欢数学,有一天他在做数学作业时, 5 | // 要求计算出9~16的和,他马上就写出了正确答案是100。 6 | // 但是他并不满足于此,他在想究竟有多少种连续的正数序列的和为100(至少包括两个数)。 7 | // 没多久,他就得到另一组连续正数和为100的序列:18,19,20,21,22。 8 | // 现在把问题交给你,你能不能也很快的找出所有和为S的连续正数序列? 9 | // Good Luck! 10 | // 输出描述: 11 | // 输出所有和为S的连续正数序列。 12 | // 序列内按照从小至大的顺序,序列间按照开始数字从小到大的顺序 13 | 14 | /** 15 | * @param {Number} sum 16 | * @return {Array} 17 | */ 18 | function FindContinuousSequence(sum) { 19 | let res = []; 20 | let n = Math.floor(Math.sqrt(2 * sum)); 21 | while (n > 1) { 22 | if ((n & (1 == 1) && sum % n == 0) || (sum % n) * 2 == n) { 23 | let arr = []; 24 | let start = sum / n - (n - 1) / 2; 25 | for (let i = 0; i < n; i++) { 26 | arr.push(start); 27 | start++; 28 | } 29 | res.push(arr); 30 | } 31 | n--; 32 | } 33 | return res; 34 | } 35 | -------------------------------------------------------------------------------- /nowcoder/jz-offer/find-first-common-node.js: -------------------------------------------------------------------------------- 1 | // 两个链表的第一个公共结点 2 | 3 | // 题目描述 4 | // 输入两个链表,找出它们的第一个公共结点。 5 | 6 | /*function ListNode(x){ 7 | this.val = x; 8 | this.next = null; 9 | }*/ 10 | 11 | /** 12 | * @param {ListNode} pHead1 13 | * @param {ListNode} pHead2 14 | * @return {ListNode} 15 | */ 16 | function FindFirstCommonNode(pHead1, pHead2) { 17 | let [p1, p2] = [pHead1, pHead2]; 18 | while (p1 != p2) { 19 | p1 = p1 == null ? pHead2 : p1.next; 20 | p2 = p2 == null ? pHead1 : p2.next; 21 | } 22 | return p1; 23 | } 24 | -------------------------------------------------------------------------------- /nowcoder/jz-offer/find-greatest-sum-of-sub-array.js: -------------------------------------------------------------------------------- 1 | // 连续子数组的最大和 2 | 3 | // 题目描述 4 | // HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学。 5 | // 今天测试组开完会后,他又发话了:在古老的一维模式识别中, 6 | // 常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决。 7 | // 但是,如果向量中包含负数,是否应该包含某个负数,并期望旁边的正数会弥补它呢? 8 | // 例如:{6,-3,-2,7,-15,1,2,2},连续子向量的最大和为8(从第0个开始,到第3个为止)。 9 | // 给一个数组,返回它的最大连续子序列的和,你会不会被他忽悠住? 10 | // (子向量的长度至少是1) 11 | 12 | /** 13 | * @param {Array []} array 14 | * @return {Number} 15 | */ 16 | function FindGreatestSumOfSubArray(array) { 17 | let len = array.length; 18 | if (!len) return false; 19 | if (len == 1) return array[0]; 20 | let max = array[0]; 21 | let res = array[0]; 22 | for (var i = 1; i < len; i++) { 23 | max = Math.max(max + array[i], array[i]); 24 | res = Math.max(max, res); 25 | } 26 | return res; 27 | } 28 | 29 | let a = FindGreatestSumOfSubArray([6, -3, -2, 7, -15, 1, 2, 2]); 30 | console.log(a); 31 | -------------------------------------------------------------------------------- /nowcoder/jz-offer/find-kth-to-tail.js: -------------------------------------------------------------------------------- 1 | // 链表中倒数第k个结点 2 | 3 | // 题目描述 4 | // 输入一个链表,输出该链表中倒数第k个结点。 5 | 6 | /*function ListNode(x){ 7 | this.val = x; 8 | this.next = null; 9 | }*/ 10 | 11 | /** 12 | * @param {ListNode} head 13 | * @param {Number} k 14 | * @return {ListNode} 15 | */ 16 | function FindKthToTail(head, k) { 17 | let pre = head; 18 | let cur = head; 19 | while (k--) { 20 | if (cur == null) { 21 | return null; 22 | } 23 | cur = cur.next; 24 | } 25 | while(cur) { 26 | pre = pre.next; 27 | cur = cur.next; 28 | } 29 | return pre; 30 | } 31 | 32 | function ListNode(x){ 33 | this.val = x; 34 | this.next = null; 35 | } 36 | 37 | let head = new ListNode(1); 38 | head.next = new ListNode(2); 39 | head.next.next = new ListNode(3); 40 | head.next.next.next = new ListNode(4); 41 | head.next.next.next.next = new ListNode(5); 42 | 43 | let a = FindKthToTail(head, 4); 44 | 45 | console.log(a); 46 | -------------------------------------------------------------------------------- /nowcoder/jz-offer/find-numbers-with-sum.js: -------------------------------------------------------------------------------- 1 | // 和为S的两个数字 2 | 3 | // 题目描述 4 | // 输入一个递增排序的数组和一个数字S,在数组中查找两个数, 5 | // 使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。 6 | // 输出描述: 7 | // 对应每个测试案例,输出两个数,小的先输出。 8 | 9 | /** 10 | * @param {Array} array 11 | * @param {Number} sum 12 | * @return {Array | Boolean} 13 | */ 14 | function FindNumbersWithSum(array, sum) { 15 | let end = array.length - 1; 16 | let start = 0; 17 | while (start < end) { 18 | let s = array[start] + array[end]; 19 | if (s === sum) { 20 | return [array[start], array[end]]; 21 | } else if (s < sum) { 22 | start++; 23 | } else { 24 | end--; 25 | } 26 | } 27 | return false; 28 | } 29 | -------------------------------------------------------------------------------- /nowcoder/jz-offer/find-nums-appear-once.js: -------------------------------------------------------------------------------- 1 | // 数组中只出现一次的数字 2 | 3 | // 题目描述 4 | // 一个整型数组里除了两个数字之外,其他的数字都出现了偶数次。 5 | // 请写程序找出这两个只出现一次的数字。 6 | 7 | /** 8 | * @param {Array []} array 9 | * @return {Array []} 10 | */ 11 | function FindNumsAppearOnce(array) { 12 | let res = [0, 0]; 13 | let xor = array.reduce((total, cur) => total ^ cur); 14 | let index = 0; 15 | while ((xor & 1) == 0) { 16 | xor = xor >> 1; 17 | index++; 18 | } 19 | array.forEach((v) => { 20 | if (v >> index & 1) { 21 | res[1] = res[1] ^ v; 22 | } else { 23 | res[0] = res[0] ^ v; 24 | } 25 | }) 26 | return res; 27 | } 28 | 29 | 30 | // function FindNumsAppearOnce(array) { 31 | // // write code here 32 | // // return list, 比如[a,b],其中ab是出现一次的两个数字 33 | // let [len, list, tmp, index] = [array.length, [0, 0], array[0], 0]; 34 | // if (len < 2) return; 35 | // for (let i = 1; i < len; i++) { 36 | // tmp = tmp ^ array[i]; 37 | // } 38 | // if (tmp === 0) return; 39 | // while ((tmp & 1) == 0) { 40 | // tmp = tmp >> 1; 41 | // index++; 42 | // } 43 | // let isBit = (num, index) => { 44 | // return num >> index & 1; 45 | // } 46 | // for (let i = 0; i < len; i++) { 47 | // if (isBit(array[i], index)) { 48 | // list[0] = list[0] ^ array[i]; 49 | // } else { 50 | // list[1] = list[1] ^ array[i]; 51 | // } 52 | // } 53 | // return list; 54 | // } 55 | 56 | var array = [2,4,3,6,3,2,5,5]; 57 | console.log(FindNumsAppearOnce(array)); -------------------------------------------------------------------------------- /nowcoder/jz-offer/find-path.js: -------------------------------------------------------------------------------- 1 | // 二叉树中和为某一值的路径 2 | 3 | // 题目描述 4 | // 输入一颗二叉树的跟节点和一个整数, 5 | // 打印出二叉树中结点值的和为输入整数的所有路径。 6 | // 路径定义为从树的根结点开始往下一直到叶结点所经过的结点形成一条路径。 7 | // (注意: 在返回值的list中,数组长度大的数组靠前) 8 | 9 | function TreeNode(x) { 10 | this.val = x; 11 | this.left = null; 12 | this.right = null; 13 | } 14 | 15 | /** 16 | * @param {TreeNode} root 17 | * @param {Number} expectNumber 18 | * @return {Array} 19 | */ 20 | 21 | function FindPath(root, expectNumber) { 22 | if (!root) return []; 23 | let [res, stack, sum, path, node] = [[], [], 0, [], root]; 24 | while (node !== null || stack.length !== 0) { 25 | while (node !== null) { 26 | stack.push(node); 27 | sum += node.val; 28 | path.push(node.val); 29 | node = node.left; 30 | } 31 | if (stack.length !== 0) { 32 | node = stack.pop(); 33 | if (path[path.length - 1] !== node.val) { 34 | sum -= path.pop(); 35 | } 36 | if (node.right === null) { 37 | if (sum === expectNumber) { 38 | res.push(path.slice()); 39 | } 40 | sum -= path.pop(); 41 | } 42 | node = node.right; 43 | } 44 | } 45 | return res; 46 | } 47 | 48 | var root = new TreeNode(10); 49 | root.left = new TreeNode(5); 50 | root.left.left = new TreeNode(4); 51 | root.left.right = new TreeNode(7); 52 | root.right = new TreeNode(12); 53 | 54 | console.log(FindPath(root, 22)); // [ [ 10, 5, 7 ], [ 10, 12 ] ] 55 | -------------------------------------------------------------------------------- /nowcoder/jz-offer/find.js: -------------------------------------------------------------------------------- 1 | // 二维数组中的查找 2 | 3 | // 题目描述 4 | // 在一个二维数组中(每个一维数组的长度相同), 5 | // 每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。 6 | // 请完成一个函数,输入这样的一个二维数组和一个整数, 7 | // 判断数组中是否含有该整数。 8 | 9 | /** 10 | * @param {Number} target 11 | * @param {Array} array 12 | * @return {Boolean} 13 | */ 14 | function Find(target, array) { 15 | let row = array.length - 1, 16 | col = array[0].length - 1, 17 | i = row, 18 | j = 0; 19 | while (i >= 0 && j <= col) { 20 | let val = array[i][j]; 21 | if (val > target) { 22 | i--; 23 | } else if (val < target) { 24 | j++; 25 | } else { 26 | return true; 27 | } 28 | } 29 | return false; 30 | } 31 | -------------------------------------------------------------------------------- /nowcoder/jz-offer/first-appearing-once.js: -------------------------------------------------------------------------------- 1 | // 字符流中第一个不重复的字符 2 | 3 | // 题目描述 4 | // 请实现一个函数用来找出字符流中第一个只出现一次的字符。 5 | // 例如,当从字符流中只读出前两个字符"go"时, 6 | // 第一个只出现一次的字符是"g"。 7 | // 当从该字符流中读出前六个字符“google"时, 8 | // 第一个只出现一次的字符是"l"。 9 | // 输出描述: 10 | // 如果当前字符流没有存在出现一次的字符,返回#字符。 11 | 12 | // 示例: 13 | // 输入: 'google' 14 | // 输出: 'ggg#ll' 15 | 16 | //Init module if you need 17 | function Init() { 18 | this.map = {}; 19 | this.stream = []; 20 | this.index = 0; 21 | } 22 | //Insert one char from stringstream 23 | function Insert(ch) { 24 | if (typeof ch === 'string') { 25 | let [map, stream] = [this.map, this.stream]; 26 | map[ch] = map[ch] > 0 ? ++map[ch] : 1; 27 | stream.push(ch); 28 | } 29 | } 30 | //return the first appearence once char in current stringstream 31 | function FirstAppearingOnce() { 32 | let [map, stream, index] = [this.map, this.stream, this.index]; 33 | let len = stream.length; 34 | for (let i = index; i < len; i++) { 35 | let ch = stream[i]; 36 | if (map[ch] == 1) { 37 | this.index = i; 38 | return ch; 39 | } 40 | } 41 | this.index = len; 42 | return '#'; 43 | } 44 | 45 | var s = 'google'; 46 | Init(); 47 | for (let i = 0, len = s.length; i < len; i++) { 48 | Insert(s[i]); 49 | console.log(FirstAppearingOnce()); 50 | } 51 | -------------------------------------------------------------------------------- /nowcoder/jz-offer/first-not-repeating-char.js: -------------------------------------------------------------------------------- 1 | // 第一个只出现一次的字符 2 | 3 | // 题目描述 4 | // 在一个字符串(0<=字符串长度<=10000,全部由字母组成) 5 | // 中找到第一个只出现一次的字符,并返回它的位置, 6 | // 如果没有则返回 -1(需要区分大小写). 7 | 8 | /** 9 | * @param {String} str 10 | * @return {Number} 11 | */ 12 | function FirstNotRepeatingChar(str) { 13 | let obj = Object.create(null); 14 | for (let i = 0, len = str.length; i < len; i++) { 15 | if (obj[str[i]]) { 16 | obj[str[i]]++; 17 | } else { 18 | obj[str[i]] = 1; 19 | } 20 | } 21 | for (let item in obj) { 22 | if (obj[item] == 1) { 23 | return str.indexOf(item); 24 | } 25 | } 26 | return -1; 27 | } 28 | 29 | console.log(FirstNotRepeatingChar('google')); -------------------------------------------------------------------------------- /nowcoder/jz-offer/format-date.js: -------------------------------------------------------------------------------- 1 | // 题目描述 2 | 3 | // 按所给的时间格式输出指定的时间 4 | // 格式说明 5 | // 对于 2014.09.05 13:14:20 6 | // yyyy: 年份,2014 7 | // yy: 年份,14 8 | // MM: 月份,补满两位,09 9 | // M: 月份, 9 10 | // dd: 日期,补满两位,05 11 | // d: 日期, 5 12 | // HH: 24制小时,补满两位,13 13 | // H: 24制小时,13 14 | // hh: 12制小时,补满两位,01 15 | // h: 12制小时,补满两位,1 16 | // mm: 分钟,补满两位,14 17 | // m: 分钟,14 18 | // ss: 秒,补满两位,20 19 | // s: 秒,20 20 | // w: 星期,为 ['日', '一', '二', '三', '四', '五', '六'] 中的某一个,本 demo 结果为 五 21 | 22 | // 示例1 23 | // 输入 24 | // formatDate(new Date(1409894060000), 'yyyy-MM-dd HH:mm:ss 星期w') 25 | 26 | // 输出 27 | // 2014-09-05 13:14:20 星期五 28 | 29 | /** 30 | * @param {new Date()} date 31 | * @return {string} str 32 | */ 33 | 34 | function formatDate(date,str){ 35 |   var obj = { 36 |     yyyy:date.getFullYear(), 37 |     yy:(""+ date.getFullYear()).slice(-2), 38 |     M:date.getMonth()+1, 39 |     MM:("0"+ (date.getMonth()+1)).slice(-2), 40 |     d:date.getDate(), 41 |     dd:("0" + date.getDate()).slice(-2), 42 |     H:date.getHours(), 43 |     HH:("0" + date.getHours()).slice(-2), 44 |     h:date.getHours() % 12, 45 |     hh:("0"+date.getHours() % 12).slice(-2), 46 |     m:date.getMinutes(), 47 |     mm:("0" + date.getMinutes()).slice(-2), 48 |     s:date.getSeconds(), 49 |     ss:("0" + date.getSeconds()).slice(-2), 50 |     w:['日', '一', '二', '三', '四', '五', '六'][date.getDay()] 51 |   }; 52 |   return str.replace(/([a-zA-Z]+)/g,function(key){return obj[key]}); 53 | } 54 | 55 | console.log(formatDate(new Date(1409894060000), 'yyyy-MM-dd HH:mm:ss 星期w')); -------------------------------------------------------------------------------- /nowcoder/jz-offer/get-least-numbers-solution.js: -------------------------------------------------------------------------------- 1 | // 最小的K个数 2 | 3 | // 题目描述 4 | // 输入n个整数,找出其中最小的K个数。 5 | // 例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4个数字是1,2,3,4,。 6 | 7 | /** 8 | * @param {Array []} input 9 | * @param {Number} k 10 | * @return {Number} 11 | */ 12 | function GetLeastNumbers_Solution(input, k) { 13 | return input.length >= k ? input.sort((a, b) => a - b).slice(0, k) : []; 14 | } 15 | -------------------------------------------------------------------------------- /nowcoder/jz-offer/get-median-of-steam.js: -------------------------------------------------------------------------------- 1 | // 数据流中的中位数 2 | 3 | // 题目描述 4 | // 如何得到一个数据流中的中位数? 5 | // 如果从数据流中读出奇数个数值, 6 | // 那么中位数就是所有数值排序之后位于中间的数值。 7 | // 如果从数据流中读出偶数个数值, 8 | // 那么中位数就是所有数值排序之后中间两个数的平均值。 9 | // 我们使用Insert()方法读取数据流, 10 | // 使用GetMedian()方法获取当前读取数据的中位数。 11 | 12 | let arr = []; 13 | function Insert(num) { 14 | let index = arr.length - 1; 15 | arr.push(num); 16 | for (let i = index; i >= 0; i--) { 17 | if (arr[i] > num) { 18 | [arr[i], arr[i + 1]] = [arr[i + 1], arr[i]]; 19 | } else { 20 | break; 21 | } 22 | } 23 | } 24 | function GetMedian() { 25 | let len = arr.length; 26 | if (len <= 0) return; 27 | let mid = Math.floor((len - 1) / 2); 28 | return len % 2 == 0 ? (arr[mid] + arr[mid + 1]) / 2 : arr[mid]; 29 | } 30 | 31 | let data = [5, 2, 3, 4, 1, 6, 7, 0, 8]; 32 | 33 | for (let i = 0, len = data.length; i < len; i++) { 34 | Insert(data[i]); 35 | console.log(GetMedian()); 36 | } 37 | -------------------------------------------------------------------------------- /nowcoder/jz-offer/get-next.js: -------------------------------------------------------------------------------- 1 | // 二叉树的下一个结点 2 | 3 | // 题目描述 4 | // 给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。 5 | // 注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。 6 | 7 | function TreeLinkNode(x) { 8 | this.val = x; 9 | this.left = null; 10 | this.right = null; 11 | this.next = null; 12 | } 13 | 14 | /** 15 | * @param {TreeLinkNode} pHead 16 | * @return {TreeLinkNode} 17 | */ 18 | function GetNext(pNode) { 19 | if (pNode === null) return null; 20 | if (pNode.right !== null) { 21 | pNode = pNode.right; 22 | while (pNode.left !== null) { 23 | pNode = pNode.left; 24 | } 25 | return pNode; 26 | } 27 | while (pNode.next !== null) { 28 | if (pNode.next.left === pNode) { 29 | return pNode.next; 30 | } 31 | pNode = pNode.next; 32 | } 33 | return null; 34 | } -------------------------------------------------------------------------------- /nowcoder/jz-offer/get-ugly-number-solution.js: -------------------------------------------------------------------------------- 1 | // 丑数 2 | 3 | // 题目描述 4 | // 把只包含质因子2、3和5的数称作丑数(Ugly Number)。 5 | // 例如6、8都是丑数,但14不是,因为它包含质因子7。 6 | // 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。 7 | 8 | /** 9 | * @param {Number} index 10 | * @return {Number} 11 | */ 12 | function GetUglyNumber_Solution(index) { 13 | if (index < 7) { 14 | return index; 15 | } 16 | let res = [1]; 17 | let [r2, r3, r5] = [0, 0, 0]; 18 | for (let i = 1; i < index; i++) { 19 | res[i] = Math.min(res[r2] * 2, res[r3] * 3, res[r5] * 5); 20 | if (res[i] == res[r2] * 2) { 21 | r2++; 22 | } 23 | if (res[i] == res[r3] * 3) { 24 | r3++; 25 | } 26 | if (res[i] == res[r5] * 5) { 27 | r5++; 28 | } 29 | } 30 | return res[index - 1]; 31 | } 32 | 33 | console.log(GetUglyNumber_Solution(7)); 34 | -------------------------------------------------------------------------------- /nowcoder/jz-offer/inverse-pairs.js: -------------------------------------------------------------------------------- 1 | // 数组中的逆序对 2 | 3 | // 题目描述 4 | // 在数组中的两个数字,如果前面一个数字大于后面的数字, 5 | // 则这两个数字组成一个逆序对。输入一个数组, 6 | // 求出这个数组中的逆序对的总数P。 7 | // 并将P对1000000007取模的结果输出。 8 | // 即输出P%1000000007 9 | 10 | /** 11 | * @param {Number} index 12 | * @return {Number} 13 | */ 14 | function InversePairs(data) { 15 | if (!data || data.length < 2) return 0; 16 | return mergeSort(data, data.slice(), 0, data.length - 1) % 1000000007; 17 | } 18 | 19 | function mergeSort(arr, newArr, start, end) { 20 | if (start == end) return 0; 21 | let mid = (end + start) >> 1, 22 | left = mergeSort(newArr, arr, start, mid), 23 | right = mergeSort(newArr, arr, mid + 1, end), 24 | count = 0, 25 | index1 = mid, 26 | index2 = end, 27 | curIndex = end; 28 | while (index1 >= start && index2 >= mid + 1) { 29 | if (arr[index1] > arr[index2]) { 30 | count += index2 - mid; 31 | newArr[curIndex--] = arr[index1--]; 32 | } else { 33 | newArr[curIndex--] = arr[index2--]; 34 | } 35 | } 36 | while (index1 >= start) { 37 | newArr[curIndex--] = arr[index1--]; 38 | } 39 | while (index2 >= mid + 1) { 40 | newArr[curIndex--] = arr[index2--]; 41 | } 42 | return left + right + count; 43 | } 44 | 45 | let count = InversePairs([7, 5, 6, 4]); 46 | 47 | console.log(count); 48 | -------------------------------------------------------------------------------- /nowcoder/jz-offer/is-balanced-solution.js: -------------------------------------------------------------------------------- 1 | // 平衡二叉树 2 | 3 | // 题目描述 4 | // 输入一棵二叉树,判断该二叉树是否是平衡二叉树。 5 | 6 | function TreeNode(x) { 7 | this.val = x; 8 | this.left = null; 9 | this.right = null; 10 | } 11 | 12 | /** 13 | * @param {TreeNode} pRoot 14 | * @return {Boolean} 15 | */ 16 | 17 | function IsBalanced_Solution(pRoot) { 18 | return getDepth(pRoot) != -1; 19 | } 20 | 21 | function getDepth(root) { 22 | if (root === null) { 23 | return 0 24 | } 25 | let left = getDepth(root.left); 26 | if (left == -1) { 27 | return -1 28 | }; 29 | let right = getDepth(root.right); 30 | if (right == -1) { 31 | return -1 32 | }; 33 | return Math.abs(left - right) > 1 ? -1 : Math.max(left, right) + 1; 34 | } 35 | 36 | let a = new TreeNode(6); 37 | a.left = new TreeNode(4); 38 | a.right = new TreeNode(7); 39 | a.left.left = new TreeNode(3); 40 | a.left.right = new TreeNode(5); 41 | a.left.left.left = new TreeNode(2); 42 | 43 | console.log(IsBalanced_Solution(a)); -------------------------------------------------------------------------------- /nowcoder/jz-offer/is-continuous.js: -------------------------------------------------------------------------------- 1 | // 扑克牌顺子 2 | 3 | // 题目描述 4 | // LL今天心情特别好,因为他去买了一副扑克牌, 5 | // 发现里面居然有2个大王,2个小王(一副牌原本是54张^_^)... 6 | // 他随机从中抽出了5张牌,想测测自己的手气,看看能不能抽到顺子, 7 | // 如果抽到的话,他决定去买体育彩票,嘿嘿!!“红心A,黑桃3,小王,大王, 8 | // 方片5”,“Oh My God!”不是顺子.....LL不高兴了,他想了想, 9 | // 决定大\小 王可以看成任何数字,并且A看作1,J为11,Q为12,K为13。 10 | // 上面的5张牌就可以变成“1,2,3,4,5”(大小王分别看作2和4), 11 | // “So Lucky!”。LL决定去买体育彩票啦。 12 | // 现在,要求你使用这幅牌模拟上面的过程,然后告诉我们LL的运气如何, 13 | // 如果牌能组成顺子就输出true,否则就输出false。 14 | // 为了方便起见,你可以认为大小王是0。 15 | 16 | /** 17 | * @param {Array} numbers 18 | * @return {Boolean} 19 | */ 20 | function IsContinuous(numbers) { 21 | let [len, flag, max, min] = [numbers.length, 0, 0, 13]; 22 | if (len !== 5) { 23 | return false; 24 | } 25 | for (let i = 0; i < 5; i++) { 26 | let num = numbers[i]; 27 | if (num === 0) { 28 | continue; 29 | } 30 | if (num < 0 || num > 13 || ((flag >> num) & 1) == 1) { 31 | return false; 32 | } 33 | flag |= 1 << num; 34 | max = max > num ? max : num; 35 | min = min < num ? min : num; 36 | } 37 | return max - min < 5 ? true : false; 38 | } 39 | 40 | console.log(IsContinuous([1, 3, 2, 6, 4])); 41 | -------------------------------------------------------------------------------- /nowcoder/jz-offer/is-numeric.js: -------------------------------------------------------------------------------- 1 | // 表示数值的字符串 2 | 3 | // 题目描述 4 | // 请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。 5 | // 例如,字符串"+100","5e2","-123","3.1416"和"-1E-16"都表示数值。 6 | // 但是"12e","1a3.14","1.2.3","+-5"和"12e+4.3"都不是。 7 | 8 | /** 9 | * @param {String} s 10 | * @return {Boolean} 11 | */ 12 | function isNumeric(s) { 13 | // let num = Number(s); 14 | // return num == num; 15 | 16 | // RegExp: (+ / -) (1.23 / 0.23 / .23) (e (+ / -) 45) 17 | let reg = /^[+-]?(([1-9]\d*|0)(\.\d*)?|\.\d+)(e[+-]?\d+)?$/i; 18 | return reg.test(s); 19 | } 20 | 21 | console.log(isNumeric('-1E-16')); // true 22 | console.log(isNumeric('12e+4.3')); // false -------------------------------------------------------------------------------- /nowcoder/jz-offer/is-symmetrical.js: -------------------------------------------------------------------------------- 1 | // 对称的二叉树 2 | 3 | // 题目描述 4 | // 请实现一个函数,用来判断一颗二叉树是不是对称的。 5 | // 注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的。 6 | 7 | function TreeNode(x) { 8 | this.val = x; 9 | this.left = null; 10 | this.right = null; 11 | } 12 | 13 | /** 14 | * @param {TreeNode} pHead 15 | * @return {TreeNode} 16 | */ 17 | 18 | function isSymmetrical(pRoot) { 19 | if (pRoot === null) return true; 20 | return isEqual(pRoot.left, pRoot.right); 21 | } 22 | 23 | function isEqual(l, r) { 24 | if (l == null && r == null) return true; 25 | if (l !== null && r !== null) { 26 | return ( 27 | l.val === r.val && isEqual(l.left, r.right) && isEqual(l.right, r.left) 28 | ); 29 | } 30 | return false; 31 | } 32 | 33 | const tree = new TreeNode(1); 34 | tree.left = new TreeNode(2); 35 | tree.left.left = new TreeNode(3); 36 | tree.left.right = new TreeNode(4); 37 | tree.right = new TreeNode(2); 38 | tree.right.left = new TreeNode(4); 39 | tree.right.right = new TreeNode(3); 40 | 41 | console.log(isSymmetrical(tree)); 42 | -------------------------------------------------------------------------------- /nowcoder/jz-offer/jump-floor-2.js: -------------------------------------------------------------------------------- 1 | // 变态跳台阶 2 | 3 | // 题目描述 4 | // 一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。 5 | // 求该青蛙跳上一个n级的台阶总共有多少种跳法。 6 | 7 | /** 8 | * @param {Number} number 9 | * @return {number} 10 | */ 11 | function jumpFloorII(number) { 12 | return ( 13 | number <= 0 ? 0 : 14 | 2 ** (number - 1) 15 | ) 16 | } 17 | -------------------------------------------------------------------------------- /nowcoder/jz-offer/jump-floor.js: -------------------------------------------------------------------------------- 1 | // 跳台阶 2 | 3 | // 题目描述 4 | // 一只青蛙一次可以跳上1级台阶,也可以跳上2级。 5 | // 求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。 6 | 7 | /** 8 | * @param {Number} number 9 | * @return {number} 10 | */ 11 | function jumpFloor(number) { 12 | let core = (n, ac1 = 1, ac2 = 2) => { 13 | return ( 14 | n <= 0 ? 0 : 15 | n === 1 ? ac1 : 16 | n === 2 ? ac2 : 17 | core(n - 1, ac2, ac1 + ac2) 18 | ) 19 | } 20 | return core(number); 21 | } 22 | 23 | var a = jumpFloor(2); 24 | 25 | console.log(a); -------------------------------------------------------------------------------- /nowcoder/jz-offer/k-th-node.js: -------------------------------------------------------------------------------- 1 | // 二叉搜索树的第k个结点 2 | 3 | // 题目描述 4 | // 给定一棵二叉搜索树,请找出其中的第k小的结点。 5 | // 例如,(5,3,7,2,4,6,8)中,按结点数值大小顺序第三小结点的值为4。 6 | 7 | function TreeNode(x) { 8 | this.val = x; 9 | this.left = null; 10 | this.right = null; 11 | } 12 | 13 | /** 14 | * @param {TreeNode} pRoot 15 | * @return {TreeNode} 16 | */ 17 | function KthNode(pRoot, k) { 18 | if (!pRoot || k < 1) return null; 19 | let arr = []; 20 | function inorder(node, arr, k) { 21 | if (!node) return; 22 | if (arr.length == k) return; 23 | inorder(node.left, arr, k); 24 | arr.push(node); 25 | inorder(node.right, arr, k); 26 | } 27 | inorder(pRoot, arr, k); 28 | return arr[k - 1]; 29 | } 30 | 31 | const tree = new TreeNode(8); 32 | 33 | tree.left = new TreeNode(6); 34 | tree.left.left = new TreeNode(5); 35 | tree.left.right = new TreeNode(7); 36 | 37 | tree.right = new TreeNode(10); 38 | tree.right.left = new TreeNode(9); 39 | tree.right.right = new TreeNode(11); 40 | 41 | console.log(KthNode(tree, 1)); 42 | -------------------------------------------------------------------------------- /nowcoder/jz-offer/last-remaining-solution.js: -------------------------------------------------------------------------------- 1 | // 孩子们的游戏(圆圈中最后剩下的数) 2 | 3 | // 题目描述 4 | // 每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此。 5 | // HF作为牛客的资深元老,自然也准备了一些小游戏。 6 | // 其中,有个游戏是这样的:首先,让小朋友们围成一个大圈。 7 | // 然后,他随机指定一个数m,让编号为0的小朋友开始报数。 8 | // 每次喊到m-1的那个小朋友要出列唱首歌,然后可以在礼品箱中任意的挑选礼物, 9 | // 并且不再回到圈中,从他的下一个小朋友开始,继续0...m-1报数....这样下去.... 10 | // 直到剩下最后一个小朋友,可以不用表演, 11 | // 并且拿到牛客名贵的“名侦探柯南”典藏版(名额有限哦!!^_^)。 12 | // 请你试着想下,哪个小朋友会得到这份礼品呢?(注:小朋友的编号是从0到n-1) 13 | 14 | /** 15 | * @param {Number} n 16 | * @param {Number} m 17 | * @return {Number} 18 | */ 19 | function LastRemaining_Solution(n, m) { 20 | if (n <= 0) { 21 | return -1; 22 | } 23 | let [sum, index, count, arr] = [0, 0, n, []]; 24 | for (let i = 0; i < count; i++) { 25 | arr.push(i); 26 | } 27 | while (count > 1) { 28 | index = (m - 1 + index) % count; 29 | console.log(arr[index]); 30 | sum += arr[index]; 31 | arr.splice(index, 1); 32 | count--; 33 | } 34 | return (n * (n - 1)) / 2 - sum; 35 | } 36 | 37 | console.log(LastRemaining_Solution(5, 3)); 38 | -------------------------------------------------------------------------------- /nowcoder/jz-offer/left-rotate-string.js: -------------------------------------------------------------------------------- 1 | // 左旋转字符串 2 | 3 | // 题目描述 4 | // 汇编语言中有一种移位指令叫做循环左移(ROL), 5 | // 现在有个简单的任务,就是用字符串模拟这个指令的运算结果。 6 | // 对于一个给定的字符序列S,请你把其循环左移K位后的序列输出。 7 | // 例如,字符序列S=”abcXYZdef”,要求输出循环左移3位后的结果,即“XYZdefabc”。 8 | // 是不是很简单?OK,搞定它! 9 | 10 | /** 11 | * @param {String} str 12 | * @param {Number} n 13 | * @return {String} 14 | */ 15 | function LeftRotateString(str, n) { 16 | return substr(str, n) + substr(str, 0, n); 17 | } 18 | 19 | function substr(str, start, count) { 20 | if (typeof str != "string") return ""; 21 | let [s, len, st, en] = ["", str.length]; 22 | st = typeof start == "number" && start >= 0 ? start : 0; 23 | en = typeof count == "number" && count >= 0 ? count : len; 24 | while (st < en && st < len) { 25 | s += str[st]; 26 | st++; 27 | } 28 | return s; 29 | } 30 | 31 | console.log(LeftRotateString("abcdefg", 0)); 32 | -------------------------------------------------------------------------------- /nowcoder/jz-offer/match.js: -------------------------------------------------------------------------------- 1 | // 正则表达式匹配 2 | 3 | // 题目描述 4 | // 请实现一个函数用来匹配包括'.'和'*'的正则表达式。 5 | // 模式中的字符'.'表示任意一个字符, 6 | // 而'*'表示它前面的字符可以出现任意次(包含0次)。 7 | // 在本题中,匹配是指字符串的所有字符匹配整个模式。 8 | // 例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配, 9 | // 但是与"aa.a"和"ab*a"均不匹配 10 | 11 | /** 12 | * @param {String} s 13 | * @param {String} pattern 14 | * @return {boolean} 15 | */ 16 | function match(s, pattern) { 17 | let [sLen, pLen] = [s.length, pattern.length]; 18 | if (sLen === pLen && s === pattern) { 19 | return true; 20 | } else { 21 | return matchCore(s, pattern, 0, 0, sLen, pLen); 22 | } 23 | } 24 | 25 | function matchCore(s, p, sIndex, pIndex, sLen, pLen) { 26 | if (sIndex == sLen && pIndex == pLen) { 27 | return true; 28 | } 29 | if (sIndex != sLen && pIndex == pLen) { 30 | return false; 31 | } 32 | let [a, b, c] = [s[sIndex], p[pIndex], p[pIndex + 1]]; 33 | if (pIndex + 1 < pLen && c === '*') { 34 | if (sIndex !== sLen && a === b || b === '.' && sIndex !== sLen) { 35 | return matchCore(s, p, sIndex + 1, pIndex, sLen, pLen) || 36 | matchCore(s, p, sIndex, pIndex + 2, sLen, pLen) || 37 | matchCore(s, p, sIndex + 1, pIndex + 2, sLen, pLen); 38 | } else { 39 | return matchCore(s, p, sIndex, pIndex + 2, sLen, pLen); 40 | } 41 | } else { 42 | if (sIndex !== sLen && a === b || b === '.' && sIndex !== sLen) { 43 | return matchCore(s, p, sIndex + 1, pIndex + 1, sLen, pLen); 44 | } else { 45 | return false; 46 | } 47 | } 48 | } 49 | 50 | console.log(match("aaa", "ab*ac*a")); -------------------------------------------------------------------------------- /nowcoder/jz-offer/max-in-windows.js: -------------------------------------------------------------------------------- 1 | // 滑动窗口的最大值 2 | 3 | // 题目描述 4 | // 给定一个数组和滑动窗口的大小,找出所有滑动窗口里数值的最大值。 5 | // 例如,如果输入数组{2,3,4,2,6,2,5,1}及滑动窗口的大小3, 6 | // 那么一共存在6个滑动窗口,他们的最大值分别为{4,4,6,6,6,5}; 7 | // 针对数组{2,3,4,2,6,2,5,1}的滑动窗口有以下6个: 8 | // {[2,3,4],2,6,2,5,1}, {2,[3,4,2],6,2,5,1}, 9 | // {2,3,[4,2,6],2,5,1}, {2,3,4,[2,6,2],5,1}, 10 | // {2,3,4,2,[6,2,5],1}, {2,3,4,2,6,[2,5,1]}。 11 | 12 | /** 13 | * @param {Array} num 14 | * @param {Number} size 15 | * @return {Array} 16 | */ 17 | function maxInWindows(num, size) { 18 | let res = []; 19 | let s = []; 20 | for (let i = 0, l = num.length; i < l; i++) { 21 | while ( 22 | s.length && 23 | num[s[s.length - 1]] <= num[i] //从后面依次弹出队列中比当前num值小的元素,同时也能保证队列首元素为当前窗口最大值下标 24 | ) 25 | s.pop(); 26 | while ( 27 | s.length && 28 | i - s[0] + 1 > size //当当前窗口移出队首元素所在的位置,即队首元素坐标对应的num不在窗口中,需要弹出 29 | ) 30 | s.shift(); 31 | s.push(i); //把每次滑动的num下标加入队列 32 | if (size && i + 1 >= size) 33 | //当滑动窗口首地址i大于等于size时才开始写入窗口最大值 34 | res.push(num[s[0]]); 35 | } 36 | return res; 37 | } 38 | 39 | let a = maxInWindows([4, 2, 3, 2, 6, 2, 5, 1], 3); 40 | console.log(a); 41 | -------------------------------------------------------------------------------- /nowcoder/jz-offer/merging-two-sorted-lists.js: -------------------------------------------------------------------------------- 1 | // 合并两个排序的链表 2 | 3 | // 题目描述 4 | // 输入两个单调递增的链表,输出两个链表合成后的链表, 5 | // 当然我们需要合成后的链表满足单调不减规则。 6 | 7 | /*function ListNode(x){ 8 | this.val = x; 9 | this.next = null; 10 | }*/ 11 | 12 | /** 13 | * @param {ListNode} pHead1 14 | * @param {ListNode} pHead2 15 | * @return {ListNode} 16 | */ 17 | function Merge(pHead1, pHead2) 18 | { 19 | // write code here 20 | let node = new ListNode(-1); 21 | let p = node; 22 | while(pHead1 != null && pHead2 != null){ 23 | if(pHead1.val <= pHead2.val){ 24 | p.next = pHead1; 25 | pHead1 = pHead1.next; 26 | }else{ 27 | p.next = pHead2; 28 | pHead2 = pHead2.next; 29 | } 30 | p = p.next 31 | } 32 | if (pHead1 != null) { 33 | p.next = pHead1; 34 | }; 35 | if (pHead2 != null) { 36 | p.next = pHead2 37 | } 38 | return node.next; 39 | } -------------------------------------------------------------------------------- /nowcoder/jz-offer/more-than-half-num-solution.js: -------------------------------------------------------------------------------- 1 | // 数组中出现次数超过一半的数字 2 | 3 | // 题目描述 4 | // 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。 5 | // 例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。 6 | // 由于数字2在数组中出现了5次,超过数组长度的一半, 7 | // 因此输出2。如果不存在则输出0。 8 | 9 | /** 10 | * @param {Array []} numbers 11 | * @return {Number} 12 | */ 13 | 14 | function MoreThanHalfNum_Solution(numbers) { 15 | let len = numbers.length; 16 | if (len < 1) { 17 | return 0; 18 | } 19 | let count = 0, 20 | cur; 21 | for (let i = 0; i < len; i++) { 22 | if (count == 0) { 23 | cur = numbers[i]; 24 | count++; 25 | } else { 26 | cur === numbers[i] ? count++ : count--; 27 | } 28 | } 29 | for (let i = 0; i < len; i++) { 30 | if (numbers[i] === cur) { 31 | count++; 32 | } 33 | } 34 | return 2 * count > len ? cur : 0; 35 | } 36 | 37 | console.log(MoreThanHalfNum_Solution([1, 2, 3, 2, 2, 2, 5, 4, 2])); // 2 38 | -------------------------------------------------------------------------------- /nowcoder/jz-offer/multiply.js: -------------------------------------------------------------------------------- 1 | // 构建乘积数组 2 | 3 | // 题目描述 4 | // 给定一个数组A[0,1,...,n-1], 5 | // 请构建一个数组B[0,1,...,n-1], 6 | // 其中B中的元素B[i]=A[0]*A[1]*...*A[i-1]*A[i+1]*...*A[n-1]。 7 | // 不能使用除法。 8 | 9 | /** 10 | * @param {Array} array 11 | * @return {Boolean} 12 | */ 13 | function multiply(array) { 14 | const res = [1]; 15 | let tmp = 1; 16 | for (let i = 1, len = array.length; i < len; i++) { 17 | res[i] = res[i - 1] * array[i - 1] 18 | } 19 | for (let j = array.length - 2; j >= 0; j--) { 20 | tmp *= array[j + 1]; 21 | res[j] *= tmp; 22 | } 23 | return res; 24 | } 25 | 26 | let a = multiply([1,2,3,4,5]); 27 | 28 | console.log(a); 29 | -------------------------------------------------------------------------------- /nowcoder/jz-offer/number-of1-between1-and-n-solution.js: -------------------------------------------------------------------------------- 1 | // 整数中1出现的次数(从1到n整数中1出现的次数) 2 | 3 | // 题目描述 4 | // 求出1~13的整数中1出现的次数, 5 | // 并算出100~1300的整数中1出现的次数? 6 | // 为此他特别数了一下1~13中包含1的数字有1、10、11、12、13因此共出现6次, 7 | // 但是对于后面问题他就没辙了。 8 | // ACMer希望你们帮帮他,并把问题更加普遍化, 9 | // 可以很快的求出任意非负整数区间中1出现的次数(从1 到 n 中1出现的次数)。 10 | 11 | /** 12 | * @param {Number} n 13 | * @return {Number} 14 | */ 15 | function NumberOf1Between1AndN_Solution(n) { 16 | let [count, i, h, l] = [0, 1]; 17 | for (i = 1; i <= n; i *= 10) { 18 | h = Math.floor(n / i); 19 | l = n % i; 20 | if (h % 10 == 0) { 21 | count += Math.floor(h / 10) * i; 22 | } else if (h % 10 == 1) { 23 | count += Math.floor(h / 10) * i + (l + 1); 24 | } else { 25 | count += Math.floor(h / 10 + 1) * i; 26 | } 27 | } 28 | return count; 29 | } 30 | 31 | console.log(NumberOf1Between1AndN_Solution(123456)); 32 | -------------------------------------------------------------------------------- /nowcoder/jz-offer/number-of1.js: -------------------------------------------------------------------------------- 1 | // 二进制中1的个数 2 | 3 | // 题目描述 4 | // 输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。 5 | 6 | /** 7 | * @param {Number} n 8 | * @return {number} 9 | */ 10 | function NumberOf1(n) { 11 | let res = 0; 12 | while(n) { 13 | res += n & 1; 14 | n = n >>> 1; 15 | } 16 | return res; 17 | } 18 | 19 | // function NumberOf1(n) 20 | // { 21 | // // write code here 22 | // //-123的二进制表示为-1111011,123的为1111011,因此首先要得到负数二进制的补码表示 23 | // //其后面部分的补码0000101 = 122的正码1111011按位取反, 24 | // //这个正码加上前面的0即是再全部按位取反即得-123的补码表示 25 | // if(n < 0){ 26 | // n = -n; 27 | // n = n-1; 28 | // var str = (Array(32).join("0")+n.toString(2)).slice(-32); 29 | // str = exchange(str); 30 | // }else{ 31 | // var str = (Array(32).join("0")+n.toString(2)).slice(-32); 32 | // } 33 | 34 | // return cal(str); 35 | // } 36 | // //计算1的个数 37 | // function cal(str){ 38 | // var sum = 0; 39 | // for(var i = 0; i < str.length; i++){ 40 | // if(str[i] == 1){ 41 | // sum ++; 42 | // } 43 | // } 44 | // return sum; 45 | // } 46 | // //如果是负数,0变1,1变0 47 | // function exchange(str){ 48 | // var arr = str.split(''); 49 | // for(var i = 0; i < arr.length; i++){ 50 | // (arr[i] == 0)?arr[i] = 1:arr[i] = 0; 51 | // } 52 | // str = arr.join(""); 53 | // return str; 54 | // } 55 | 56 | var a = NumberOf1(-122) 57 | 58 | console.log(a) 59 | -------------------------------------------------------------------------------- /nowcoder/jz-offer/permutation.js: -------------------------------------------------------------------------------- 1 | // 字符串的排列 2 | 3 | // 题目描述 4 | // 输入一个字符串,按字典序打印出该字符串中字符的所有排列。 5 | // 例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串 6 | // abc,acb,bac,bca,cab和cba。 7 | 8 | /** 9 | * @param {String} str 10 | * @return {Array} 11 | */ 12 | 13 | function Permutation(str) { 14 | var res = []; 15 | var s = str 16 | .split("") 17 | .sort() 18 | .join(""); 19 | permutationRecursive(res, 0, s); 20 | return res; 21 | } 22 | 23 | function permutationRecursive(arr, k, str) { 24 | if (k == str.length - 1) arr.push(str); 25 | for (var i = k; i < str.length; i++) { 26 | if (i != k && str[k] == str[i]) continue; 27 | str = swap(str, i, k); 28 | permutationRecursive(arr, k + 1, str); 29 | } 30 | } 31 | 32 | function swap(str, i, k) { 33 | var arr = str.split(""); 34 | [arr[i], arr[k]] = [arr[k], arr[i]]; 35 | return arr.join(""); 36 | } 37 | 38 | var str = "abc"; 39 | console.log(Permutation(str)); // [ 'abc', 'acb', 'bac', 'bca', 'cab', 'cba' ] 40 | -------------------------------------------------------------------------------- /nowcoder/jz-offer/power.js: -------------------------------------------------------------------------------- 1 | // 数值的整数次方 2 | 3 | // 题目描述 4 | // 给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。 5 | 6 | /** 7 | * @param {Number} base 8 | * @param {Number} exponent 9 | * @return {number} 10 | */ 11 | function Power(base, exponent) { 12 | // return base**exponent; 13 | 14 | let res = 1; 15 | let cur = base; 16 | let exp = exponent > 0 ? exponent : -exponent; 17 | 18 | while (exp) { 19 | if (exp & 1) { 20 | res *= base; 21 | } 22 | base *= base; 23 | exp = exp >> 1; 24 | } 25 | return exponent > 0 ? res : 1 / res; 26 | } 27 | 28 | var a = Power(1.2, 4); 29 | 30 | console.log(a); 31 | -------------------------------------------------------------------------------- /nowcoder/jz-offer/print-binary-tree-from-top-to-bottom.js: -------------------------------------------------------------------------------- 1 | // 从上往下打印二叉树 2 | 3 | // 题目描述 4 | // 从上往下打印出二叉树的每个节点,同层节点从左至右打印。 5 | 6 | /* function TreeNode(x) { 7 | this.val = x; 8 | this.left = null; 9 | this.right = null; 10 | } */ 11 | 12 | /** 13 | * @param {TreeNode} root 14 | * @return {Array} 15 | */ 16 | function PrintFromTopToBottom(root) { 17 | // BFC 18 | let [queue, result, node] = [[root], []]; 19 | let node; 20 | if (!root) { 21 | return false; 22 | } 23 | while (queue.length > 0) { 24 | node = queue.shift(); 25 | if (node !== null) { 26 | result.push(node.val); 27 | } 28 | if (node.left !== null) { 29 | queue.push(node.left); 30 | } 31 | if (node.right !== null) { 32 | queue.push(node.right); 33 | } 34 | } 35 | return result; 36 | } 37 | -------------------------------------------------------------------------------- /nowcoder/jz-offer/print-list-from-tail-to-head.js: -------------------------------------------------------------------------------- 1 | // 从尾到头打印链表 2 | 3 | // 题目描述 4 | // 输入一个链表,按链表值从尾到头的顺序返回一个ArrayList。 5 | 6 | /*function ListNode(x){ 7 | this.val = x; 8 | this.next = null; 9 | }*/ 10 | 11 | /** 12 | * @param {ListNode} head 13 | * @return {Array} 14 | */ 15 | function printListFromTailToHead(head) { 16 | let res = []; 17 | while (head) { 18 | res.push(head.val); 19 | head = head.next; 20 | } 21 | return res.reverse(); 22 | } 23 | -------------------------------------------------------------------------------- /nowcoder/jz-offer/print-min-number.js: -------------------------------------------------------------------------------- 1 | // 把数组排成最小的数 2 | 3 | // 题目描述 4 | // 输入一个正整数数组,把数组里所有数字拼接起来排成一个数, 5 | // 打印能拼接出的所有数字中最小的一个。例如输入数组{3,32,321}, 6 | // 则打印出这三个数字能排成的最小数字为321323。 7 | 8 | /** 9 | * @param {Array} numbers 10 | * @return {String} 11 | */ 12 | function PrintMinNumber(numbers) { 13 | return numbers 14 | .sort((a, b) => a - b) 15 | .reduce( 16 | (total, cur) => (total + cur < cur + total ? total + cur : cur + total), 17 | "" 18 | ); 19 | } 20 | 21 | var a = PrintMinNumber([3, 32, 321]); 22 | 23 | console.log(a); 24 | -------------------------------------------------------------------------------- /nowcoder/jz-offer/print-serial-line.js: -------------------------------------------------------------------------------- 1 | // 把二叉树打印成多行 2 | 3 | // 题目描述 4 | // 从上到下按层打印二叉树,同一层结点从左至右输出。每一层输出一行。 5 | 6 | function TreeNode(x) { 7 | this.val = x; 8 | this.left = null; 9 | this.right = null; 10 | } 11 | 12 | /** 13 | * @param {TreeNode} pRoot 14 | * @return {Number} 15 | */ 16 | function Print(pRoot) { 17 | if (pRoot == null) return []; 18 | let res = []; 19 | let queue = [pRoot]; 20 | while (queue.length) { 21 | let values = []; 22 | let nodes = []; 23 | for (let i = 0, len = queue.length; i < len; i++) { 24 | let item = queue.shift(); 25 | values.push(item.val); 26 | if (item.left) { 27 | queue.push(item.left); 28 | } 29 | if (item.right) { 30 | queue.push(item.right); 31 | } 32 | } 33 | res.push(values); 34 | } 35 | return res; 36 | } 37 | 38 | const tree = new TreeNode(8); 39 | 40 | tree.left = new TreeNode(6); 41 | tree.left.left = new TreeNode(5); 42 | tree.left.right = new TreeNode(7); 43 | 44 | tree.right = new TreeNode(10); 45 | tree.right.left = new TreeNode(9); 46 | tree.right.right = new TreeNode(11); 47 | 48 | // console.log(tree); 49 | console.log(Print(tree)); 50 | -------------------------------------------------------------------------------- /nowcoder/jz-offer/re-construct-binary-tree.js: -------------------------------------------------------------------------------- 1 | // 重建二叉树 2 | 3 | // 题目描述 4 | // 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。 5 | // 假设输入的前序遍历和中序遍历的结果中都不含重复的数字。 6 | // 例如输入前序遍历序列{1,2,4,7,3,5,6,8} 7 | // 和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。 8 | 9 | /* function TreeNode(x) { 10 | this.val = x; 11 | this.left = null; 12 | this.right = null; 13 | } */ 14 | 15 | /** 16 | * @param {Array} pre 17 | * @param {Array} vin 18 | * @return {TreeNode} 19 | */ 20 | function reConstructBinaryTree(pre, vin) { 21 | if (pre.length <= 0) return null; 22 | let node = pre.shift(); 23 | let tree = new TreeNode(node); 24 | let i = vin.indexOf(node); 25 | tree.left = reConstructBinaryTree(pre.slice(0, i), vin.slice(0, i)); 26 | tree.right = reConstructBinaryTree(pre.slice(i), vin.slice(i + 1)); 27 | return tree; 28 | } 29 | 30 | function TreeNode(x) { 31 | this.val = x; 32 | this.left = null; 33 | this.right = null; 34 | } 35 | 36 | var a = reConstructBinaryTree([1, 2, 3, 4, 5, 6, 7], [3, 2, 4, 1, 6, 5, 7]); 37 | console.log(a); 38 | -------------------------------------------------------------------------------- /nowcoder/jz-offer/rect-cover.js: -------------------------------------------------------------------------------- 1 | // 矩形覆盖 2 | 3 | // 题目描述 4 | // 我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。 5 | // 请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法? 6 | 7 | /** 8 | * @param {Number} number 9 | * @return {number} 10 | */ 11 | function rectCover(number) { 12 | const core = (n, ac1 = 1, ac2 = 2) => { 13 | return n == 2 ? ac2 : core(--n, ac2, ac1 + ac2); 14 | } 15 | return number < 2 ? number : core(number); 16 | } 17 | 18 | var a = rectCover(5); 19 | 20 | console.log(a); -------------------------------------------------------------------------------- /nowcoder/jz-offer/reorder-array.js: -------------------------------------------------------------------------------- 1 | // 调整数组顺序使奇数位于偶数前面 2 | 3 | // 题目描述 4 | // 输入一个整数数组,实现一个函数来调整该数组中数字的顺序, 5 | // 使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分, 6 | // 并保证奇数和奇数,偶数和偶数之间的相对位置不变。 7 | 8 | /** 9 | * @param {Array} array 10 | * @return {Array} 11 | */ 12 | function reOrderArray(array) { 13 | let [odd, even] = [[], []]; 14 | array.forEach(v => v % 2 ? odd.push(v) : even.push(v)) 15 | return [...odd, ...even]; 16 | } -------------------------------------------------------------------------------- /nowcoder/jz-offer/repeated-number-in-array.js: -------------------------------------------------------------------------------- 1 | // 数组中重复的数 2 | 3 | // 题目描述 4 | // 在一个长度为n的数组里的所有数字都在0到n-1的范围内。 5 | // 数组中某些数字是重复的,但不知道有几个数字是重复的。 6 | // 也不知道每个数字重复几次。 7 | // 请找出数组中任意一个重复的数字。 8 | // 例如,如果输入长度为7的数组{2,3,1,0,2,5,3}, 9 | // 那么对应的输出是第一个重复的数字2。 10 | 11 | 12 | /** 13 | * @param {numbers[]} numbers 14 | * @return {boolean} 15 | */ 16 | 17 | // 巧用题目条件(数组内数字在0~n-1),不排序直接遍历 18 | function duplicate(numbers, duplication) 19 | { 20 | // write code here 21 | //这里要特别注意~找到任意重复的一个值并赋值到duplication[0] 22 | //函数返回True/False 23 | for ( let i= 0, len = numbers.length; i < len; i++) { 24 | if (numbers[i] !== i) { 25 | if (numbers[i] == numbers[numbers[i]]) { 26 | duplication[0] = numbers[i]; 27 | return true; 28 | } 29 | [numbers[numbers[i]],numbers[i]] = [numbers[i],numbers[numbers[i]]]; 30 | } 31 |     } 32 |     return false ;  33 | } 34 | 35 | // // 排序后遍历 36 | // function duplicate(numbers, duplication) 37 | // { 38 | // // write code here 39 | // //这里要特别注意~找到任意重复的一个值并赋值到duplication[0] 40 | // //函数返回True/False 41 | // numbers.sort(); 42 | // for (let i = 0, len = numbers.length; i < len; i ++) { 43 | // if (numbers[i] == numbers[i + 1]) { 44 | // duplication[0] = numbers[i]; 45 | // return true; 46 | // } 47 | // } 48 | // return false; 49 | // } 50 | 51 | 52 | -------------------------------------------------------------------------------- /nowcoder/jz-offer/replace-space.js: -------------------------------------------------------------------------------- 1 | // 替换空格 2 | 3 | // 题目描述 4 | // 请实现一个函数,将一个字符串中的每个空格替换成“%20”。 5 | // 例如,当字符串为We Are Happy. 6 | // 则经过替换之后的字符串为We%20Are%20Happy。 7 | 8 | /** 9 | * @param {String} str 10 | * @return {String} 11 | */ 12 | function replaceSpace(str) { 13 | // return encodeURI(str); 14 | return str.replace(/\s/g, '%20'); 15 | } 16 | -------------------------------------------------------------------------------- /nowcoder/jz-offer/reverse-list.js: -------------------------------------------------------------------------------- 1 | // 反转链表 2 | 3 | // 题目描述 4 | // 输入一个链表,反转链表后,输出新链表的表头。 5 | 6 | /*function ListNode(x){ 7 | this.val = x; 8 | this.next = null; 9 | }*/ 10 | 11 | /** 12 | * @param {ListNode} head 13 | * @return {ListNode} 14 | */ 15 | function ReverseList(pHead) { 16 | let pre = null; 17 | let next; 18 | while (pHead) { 19 | next = pHead.next; 20 | pHead.next = pre; 21 | pre = pHead; 22 | pHead = next; 23 | } 24 | return pre; 25 | } 26 | -------------------------------------------------------------------------------- /nowcoder/jz-offer/reverse-sentence.js: -------------------------------------------------------------------------------- 1 | // 翻转单词顺序列 2 | 3 | // 题目描述 4 | // 牛客最近来了一个新员工Fish, 5 | // 每天早晨总是会拿着一本英文杂志, 6 | // 写些句子在本子上。 7 | // 同事Cat对Fish写的内容颇感兴趣, 8 | // 有一天他向Fish借来翻看,但却读不懂它的意思。 9 | // 例如,“student. a am I”。 10 | // 后来才意识到,这家伙原来把句子单词的顺序翻转了, 11 | // 正确的句子应该是“I am a student.”。 12 | // Cat对一一的翻转这些单词顺序可不在行,你能帮助他么? 13 | 14 | /** 15 | * @param {String} str 16 | * @return {String} 17 | */ 18 | function ReverseSentence(str) { 19 | // return str.split(" ").reverse().join(" "); 20 | 21 | let [res, word] = ["", ""]; 22 | for (let i = 0, len = str.length; i < len; i++) { 23 | let c = str[i]; 24 | if (c !== " ") { 25 | word += c; 26 | } else { 27 | res = " " + word + res; 28 | word = ""; 29 | } 30 | } 31 | return word + res; 32 | } 33 | 34 | console.log(ReverseSentence("I am a student.")); 35 | -------------------------------------------------------------------------------- /nowcoder/jz-offer/serialize-and-deserialize-tree.js: -------------------------------------------------------------------------------- 1 | // 序列化二叉树 2 | 3 | // 题目描述 4 | // 请实现两个函数,分别用来序列化和反序列化二叉树 5 | 6 | function TreeNode(x) { 7 | this.val = x; 8 | this.left = null; 9 | this.right = null; 10 | } 11 | 12 | /** 13 | * @param {TreeNode} pRoot 14 | * @return {String} 15 | */ 16 | let arr = []; 17 | let treeToArr = (pRoot, arr) => { 18 | if (!pRoot) { 19 | arr.push("#"); 20 | return; 21 | } 22 | arr.push(pRoot.val); 23 | treeToArr(pRoot.left, arr); 24 | treeToArr(pRoot.right, arr); 25 | }; 26 | 27 | function Serialize(pRoot) { 28 | arr = []; 29 | treeToArr(pRoot, arr); 30 | return arr.join(""); 31 | } 32 | 33 | /** 34 | * @param {String} s 35 | * @return {TreeNode} 36 | */ 37 | let arrToTree = (arr, node) => { 38 | if (!arr.length) { 39 | return null; 40 | } 41 | let val = arr.shift(); 42 | if (val != "#") { 43 | node = new TreeNode(val); 44 | node.left = arrToTree(arr, node.left); 45 | node.right = arrToTree(arr, node.right); 46 | } 47 | return node; 48 | }; 49 | function Deserialize(s) { 50 | if (!arr.length) { 51 | return null; 52 | } 53 | let node = null; 54 | node = arrToTree(arr, node); 55 | return node; 56 | } 57 | 58 | const tree = new TreeNode(8); 59 | 60 | tree.left = new TreeNode(6); 61 | tree.left.left = new TreeNode(5); 62 | tree.left.right = new TreeNode(7); 63 | 64 | tree.right = new TreeNode(10); 65 | tree.right.left = new TreeNode(9); 66 | tree.right.right = new TreeNode(11); 67 | 68 | console.log(Serialize(tree)); 69 | console.log(Deserialize("")); 70 | -------------------------------------------------------------------------------- /nowcoder/jz-offer/stacks-and-queues.js: -------------------------------------------------------------------------------- 1 | // 用两个栈来实现队列 2 | 3 | // 题目描述 4 | // 用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。 5 | 6 | let inStack = []; 7 | let outStack = []; 8 | function push(node) { 9 | return inStack.push(node); 10 | } 11 | function pop() { 12 |     if (!outStack.length) { 13 |         while (inStack.length) { 14 |             outStack.push(inStack.pop()); 15 |         } 16 |     } 17 |     return outStack.pop(); 18 | } 19 | 20 | // let queue = []; 21 | // function push(node) { 22 | // queue.push(node); 23 | // } 24 | // function pop() { 25 | // return queue.length ? queue.shift() : false; 26 | // } -------------------------------------------------------------------------------- /nowcoder/jz-offer/str-to-int.js: -------------------------------------------------------------------------------- 1 | // 把字符串转换成整数 2 | 3 | // 题目描述 4 | // 将一个字符串转换成一个整数(实现Integer.valueOf(string)的功能,但是string不符合数字要求时返回0),要求不能使用字符串转换整数的库函数。 数值为0或者字符串不是一个合法的数值则返回0。 5 | // 输入描述: 6 | // 输入一个字符串,包括数字字母符号,可以为空 7 | // 输出描述: 8 | // 如果是合法的数值表达则返回该数字,否则返回0 9 | // 示例1 10 | // 输入: "+2147483647" 11 | // 输出: 2147483647 12 | 13 | // 输入: "1a33" 14 | // 输出: 0 15 | 16 | /** 17 | * @param {String} str 18 | * @return {Number} 19 | */ 20 | function StrToInt(str) { 21 | // var num = Number(str); 22 | // return num === num ? num : 0; 23 | 24 | // return /^([+-]\d+|[1-9]\d*|0)$/.test(str) ? -(-str) : 0; 25 | 26 | const len = str.length; 27 | if (len < 1) return 0; 28 | const s0 = str[0].charCodeAt() - 48; 29 | if ((s0 !== -5 && s0 !== -3 && s0 < 0) || s0 > 9) return 0; 30 | for (let i = 1; i < len; i++) { 31 | let val = str[i].charCodeAt() - 48; 32 | if (val < 0 || val > 9) return 0; 33 | } 34 | return -str === -str ? -(-str) : 0; 35 | } 36 | 37 | console.log(StrToInt("+")); 38 | -------------------------------------------------------------------------------- /nowcoder/jz-offer/the-mirror-of-the-two-forked-tree.js: -------------------------------------------------------------------------------- 1 | // 二叉树的镜像 2 | 3 | // 题目描述 4 | // 操作给定的二叉树,将其变换为源二叉树的镜像。 5 | // 输入描述: 6 | // 二叉树的镜像定义:源二叉树 7 | // 8 8 | // / \ 9 | // 6 10 10 | // / \ / \ 11 | // 5 7 9 11 12 | // 镜像二叉树 13 | // 8 14 | // / \ 15 | // 10 6 16 | // / \ / \ 17 | // 11 9 7 5 18 | 19 | /* function TreeNode(x) { 20 | this.val = x; 21 | this.left = null; 22 | this.right = null; 23 | } */ 24 | 25 | /** 26 | * @param {TreeNode} root 27 | */ 28 | function Mirror(root) { 29 | // write code here 30 | if (root === null || (root.left === null && root.right === null)) { 31 | return; 32 | } 33 | [root.left, root.right] = [root.right, root.left]; 34 | Mirror(root.right); 35 | Mirror(root.left); 36 | } 37 | -------------------------------------------------------------------------------- /nowcoder/jz-offer/the-sequence-of-the-stack-push-and-pop.js: -------------------------------------------------------------------------------- 1 | // 栈的压入与弹出序列 2 | 3 | // 题目描述 4 | // 输入两个整数序列,第一个序列表示栈的压入顺序, 5 | // 请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。 6 | // 例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈序列对应的一个弹出序列, 7 | // 但4,3,5,1,2就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的) 8 | 9 | /** 10 | * @param {Array []} pushV 11 | * @param {Array []} popV 12 | * @return {Boolean} 13 | */ 14 | 15 | function IsPopOrder(pushV, popV) { 16 | let [i, j, len, arr] = [0, 0, popV.length, []]; 17 | while (j < len) { 18 | if (i < len) { 19 | arr.push(pushV[i++]); 20 | if (pushV[i - 1] === popV[j]) { 21 | arr.pop(); 22 | j++; 23 | } 24 | } else { 25 | if (arr.pop() !== popV[j]) { 26 | return false; 27 | } else { 28 | j++; 29 | } 30 | } 31 | } 32 | return true; 33 | } 34 | 35 | console.log(IsPopOrder([1, 2, 3, 4, 5], [4, 5, 3, 2, 1])); 36 | -------------------------------------------------------------------------------- /nowcoder/jz-offer/the-smallest-number-of-rotating-arrays.js: -------------------------------------------------------------------------------- 1 | // 旋转数组的最小数字 2 | 3 | // 题目描述 4 | // 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 5 | // 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。 6 | // 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 7 | // NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。 8 | 9 | 10 | /** 11 | * @param {number[]} rotateArray 12 | * @return {number} 13 | */ 14 | function minNumberInRotateArray(rotateArray) { 15 | if (rotateArray.length == 0) { return 0 }; 16 | let [low,high,mid] = [0, rotateArray.length - 1]; 17 | while (low < high) { 18 | let mid = low + Math.floor((high - low) / 2); 19 | if (rotateArray[mid] > rotateArray [high]) { 20 | low = mid + 1; 21 | } else if (rotateArray[mid] == rotateArray[high]) { 22 | high--; 23 | } else { 24 | high = mid; 25 | } 26 | } 27 | return rotateArray[low]; 28 | } 29 | 30 | let arr = [6501,6828,6963,7036,7422,7674,8146,8468,8704,8717,9170,9359,9719,9895,9896,9913,9962,154,293,334,492,1323,1479,1539,1727,1870,1943,2383,2392,2996,3282,3812,3903,4465,4605,4665,4772,4828,5142,5437,5448,5668,5706,5725,6300,6335]; 31 | 32 | console.log(minNumberInRotateArray(arr)); 33 | 34 | // function minNumberInRotateArray(rotateArray) { 35 | // let len = rotateArray.length; 36 | // if (len == 0) { return 0 }; 37 | // while (len--) { 38 | // if (len == 0) { 39 | // return rotateArray[0]; 40 | // } 41 | // if (rotateArray[len] < rotateArray [len - 1]) { 42 | // return rotateArray[len]; 43 | // } 44 | // } 45 | // } -------------------------------------------------------------------------------- /nowcoder/jz-offer/the-substructure-of-a-tree.js: -------------------------------------------------------------------------------- 1 | // 树的子结构 2 | 3 | // 题目描述 4 | // 输入两棵二叉树A,B,判断B是不是A的子结构。 5 | // (ps:我们约定空树不是任意一个树的子结构) 6 | 7 | /* function TreeNode(x) { 8 | this.val = x; 9 | this.left = null; 10 | this.right = null; 11 | } */ 12 | 13 | /** 14 | * @param {TreeNode} pHead1 15 | * @param {TreeNode} pHead2 16 | * @return {Boolean} 17 | */ 18 | function HasSubtree(pRoot1, pRoot2) { 19 | // write code here 20 | if (pRoot2 == null || pRoot1 == null) { 21 | return false; 22 | } 23 | return ( 24 | isSubtree(pRoot1, pRoot2) || 25 | isSubtree(pRoot1.left, pRoot2) || 26 | isSubtree(pRoot1.right, pRoot2) 27 | ); 28 | } 29 | 30 | // 判断函数 31 | function isSubtree(pRoot1, pRoot2) { 32 | if (pRoot2 == null) { 33 | return true; 34 | } 35 | if (pRoot1 == null) { 36 | return false; 37 | } 38 | if (pRoot1.val == pRoot2.val) { 39 | return ( 40 | isSubtree(pRoot1.left, pRoot2.left) && 41 | isSubtree(pRoot1.right, pRoot2.right) 42 | ); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /nowcoder/jz-offer/tree-depth.js: -------------------------------------------------------------------------------- 1 | // 二叉树的深度 2 | 3 | // 题目描述 4 | // 输入一棵二叉树,求该树的深度。 5 | // 从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径, 6 | // 最长路径的长度为树的深度。 7 | 8 | /* function TreeNode(x) { 9 | this.val = x; 10 | this.left = null; 11 | this.right = null; 12 | } */ 13 | 14 | /** 15 | * @param {TreeNode} pRoot 16 | * @return {Number} 17 | */ 18 | function TreeDepth(pRoot){ 19 | return pRoot === null ? 0 : Math.max(TreeDepth(pRoot.left), TreeDepth(pRoot.right)) + 1; 20 | } -------------------------------------------------------------------------------- /nowcoder/jz-offer/verify-squence-of-BST.js: -------------------------------------------------------------------------------- 1 | // 二叉搜索树的后序遍历序列 2 | 3 | // 题目描述 4 | // 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。 5 | // 如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。 6 | 7 | /** 8 | * @param {Array []} sequence 9 | * @return {Boolean} 10 | */ 11 | function VerifySquenceOfBST(sequence) { 12 | let [len, i] = [sequence.length, 0]; 13 | if (len == 0) { 14 | return false; 15 | } 16 | while (--len) { 17 | while (sequence[i++] < sequence[len]); 18 | while (sequence[i++] > sequence[len]); 19 | if (i < len) return false; 20 | i = 0; 21 | } 22 | return true; 23 | } 24 | 25 | // // recursive 26 | // function VerifySquenceOfBST(sequence) { 27 | // if (sequence.length == 0) { return false; } 28 | // return recursive(sequence, 0, sequence.length - 1, ); 29 | // } 30 | 31 | // function recursive (arr, start, root) { 32 | // if (start >= root) { return true; } 33 | // while (arr[start] < arr[root]) { start++; } 34 | // let l = start - 1; 35 | // while (arr[start] > arr[root]) { start++;} 36 | // return start < root ? false : recursive(arr, 0, l) && recursive(arr, l + 1, root - 1); 37 | // } 38 | 39 | // var a = [4,8,6,12,16,14,10]; 40 | // console.log(VerifySquenceOfBST(a)); 41 | -------------------------------------------------------------------------------- /others/SAIMAWANG.js: -------------------------------------------------------------------------------- 1 | /* 2 | * util 赛码网 3 | */ 4 | var date = "" 5 | var index = 0; 6 | var pattLine = /(.+(?=\n))/; 7 | function read_line() { 8 | var line = date.substr(index).match(pattLine); 9 | // var line = pattLine.exec(date.substr(index)); 10 | index = line ? index + line[1].length + 1 : index; 11 | return line ? line[1] : line; 12 | } 13 | var pattInt = /(\d+(?=\ |\n))/; 14 | function readInt() { 15 | var _int = date.substr(index).match(pattInt); 16 | // var _int = pattInt.exec(date.substr(index)) 17 | index = _int ? index + _int[1].length + 1 : index; 18 | return _int ? parseInt(_int[1]) : _int; 19 | } 20 | var print = function () { 21 | var args = (arguments.length === 1 ? [arguments[0]] : Array.apply(null, arguments)); 22 | console.log(args.join(' ')); 23 | } 24 | 25 | // set your date 26 | date =` 27 | 3 28 | 1 29 | 5 30 | 21 31 | `; 32 | 33 | // write code here 34 | var a, b; 35 | var solveMeFirst = (a,b) => a+b; 36 | while((a=readInt())!=null && (b=readInt())!=null){ 37 | let c = solveMeFirst(a, b); 38 | print(c); 39 | } -------------------------------------------------------------------------------- /others/TEST.js: -------------------------------------------------------------------------------- 1 | function add() { 2 | let sum = 0; 3 | let arr = [].slice.call(arguments); 4 | let getSum = (arr) => { 5 | for (let i = 0, len = arr.length; i < len; i++) { 6 | sum += arr[i]; 7 | } 8 | return sum; 9 | } 10 | console.log(getSum(arr)); 11 | let f = function () { 12 | let arr = [].slice.call(arguments); 13 | console.log(getSum(arr)); 14 | return f; 15 | } 16 | return f; 17 | } 18 | 19 | // add(1, 2)(3)(...[2,3,4]) 20 | 21 | var arr = [213,211,229,201,224,201,203,196,203,185,203,191,216,201,203,196,203,203,203,203,198,221,201,196,198,208,218,196,208]; 22 | var obj = {}; 23 | 24 | arr.forEach((v) => { 25 | if (obj[v]) { 26 | obj[v]++; 27 | } else { 28 | obj[v] = 1; 29 | } 30 | }) 31 | 32 | console.log(obj); -------------------------------------------------------------------------------- /others/array-remove-repeat-item.js: -------------------------------------------------------------------------------- 1 | // 数组去重 2 | 3 | function removeRepeat(array) { 4 | if (Array.from && Set) { 5 | return Array.from(new Set(array)); 6 | } else { 7 | var result = []; 8 | for(var i=0; i { 18 | console.log(1); 19 | cb && cb(); 20 | }, 300); 21 | } 22 | 23 | function fun2(cb) { 24 | setTimeout(() => { 25 | console.log(2); 26 | cb && cb(); 27 | }, 150); 28 | } 29 | 30 | function fun3(cb) { 31 | setTimeout(() => { 32 | console.log(3); 33 | cb && cb(); 34 | }, 100); 35 | } 36 | 37 | function queen(list, count) { 38 | while (count > 0) { 39 | if (list.length > 0) { 40 | var f = list.shift(); 41 | count--; 42 | let p = new Promise((resolve, reject)=>{ 43 | f(resolve); 44 | }) 45 | p.then(() => { 46 | count++; 47 | return queen(list, count); 48 | }) 49 | } else { 50 | return; 51 | } 52 | } 53 | } 54 | 55 | 56 | queen([fun1, fun2, fun3], 2); -------------------------------------------------------------------------------- /others/cvte3.js: -------------------------------------------------------------------------------- 1 | // 输出杨辉三角 2 | 3 | // 实例 4 | // 输入: 5 | // 5 6 | // 输出: 7 | // 1 8 | // 1 1 9 | // 1 2 1 10 | // 1 3 3 1 11 | // 1 4 6 4 1 12 | 13 | /** 14 | * @param {Number} n 15 | * @return {String}*n 16 | */ 17 | function printYanHui(n) { 18 | var arr = []; 19 | for (let i = 0; i < n; i++) { 20 | arr[i] = []; 21 | for (let j = 0; j < i + 1; j++) { 22 | if (j >= 1 && j < i) { 23 | arr[i].push(arr[i - 1][j - 1] + arr[i - 1][j]) 24 | } else { 25 | arr[i].push(1); 26 | } 27 | } 28 | console.log(arr[i].join(' ')); 29 | } 30 | } 31 | 32 | printYanHui(5) -------------------------------------------------------------------------------- /others/parsing-string-into-integer.js: -------------------------------------------------------------------------------- 1 | // 将整数字符串解析成数字 2 | 3 | // 给定一个字符串类型的整数,把它转换成对应的数字类型 4 | 5 | // 例: 6 | // 输入:"12345", 7 | // 输出:12345 8 | 9 | /** 10 | * @param {string} str 11 | * @return {number} 12 | */ 13 | 14 | function parseStrToInt(str) { 15 | // // 若存在parseInt(),则直接转换 16 | // if (Number.parseInt) { 17 | // return Number.parseInt(str); 18 | // } 19 | let len = str.length; 20 | let res = 0; 21 | for (let i = 0; i < len; i++) { 22 | // 遍历字符串,若存在charCodeAt(),则手动获取字符对应的ASCII码 23 | // 0~9对应的ASCII码为48~57 24 | // 使用ASCII码-48,再乘以倍数,结果累加,即是转换后的数字类型 25 | if (String.prototype.charCodeAt) { 26 | res += (str[i].charCodeAt() - 48) * 10 ** (len - i - 1); 27 | } else { 28 | res += str[i] * 10 ** (len - i - 1); 29 | } 30 | } 31 | return res; 32 | } 33 | 34 | var a = parseStrToInt("12345"); 35 | 36 | console.log(a); -------------------------------------------------------------------------------- /others/render-array-to-tree.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 将数组转换为二叉树 3 | * 4 | * [1, 2, 3, null, 4, 5] 5 | * 6 | * || 7 | * || 8 | * \||/ 9 | * \/ 10 | * 11 | * 1 12 | * / \ 13 | * 2 3 14 | * \ / 15 | * 4 5 16 | * 17 | */ 18 | /** 19 | * Definition for a binary tree node. 20 | * function TreeNode(val) { 21 | * this.val = val; 22 | * this.left = this.right = null; 23 | * } 24 | */ 25 | /** 26 | * @param {Array} arr 27 | * @return {TreeNode} 28 | */ 29 | var renderArrayToTree = function(arr) { 30 | let len = arr.length; 31 | if (!len) return null; 32 | 33 | let count = 0; 34 | let res = new TreeNode(arr[count++]); 35 | let node; 36 | let queue = [res]; 37 | let nextLevel = []; 38 | while (queue.length > 0) { 39 | node = queue.shift(); 40 | if (node !== null) { 41 | count < len && nextLevel.push(node.left = new TreeNode(arr[count++])); 42 | count < len && nextLevel.push(node.right = new TreeNode(arr[count++])); 43 | } 44 | if (queue.length === 0 && nextLevel.length > 0) { 45 | queue = nextLevel; 46 | nextLevel = []; 47 | } 48 | } 49 | return res; 50 | }; 51 | 52 | module.exports = { 53 | renderArrayToTree: renderArrayToTree 54 | }; 55 | 56 | // // test 57 | // function TreeNode(val) { 58 | // this.val = val; 59 | // this.left = this.right = null; 60 | // } 61 | 62 | // console.log(renderArrayToTree([1, 2, 3, null, 4, 5])) -------------------------------------------------------------------------------- /others/sf1.js: -------------------------------------------------------------------------------- 1 | // 从两个字符串(只包含0-9a-zA-Z)中获取两者不同的字符按顺序生成对称字符串 2 | 3 | // 题目描述: 4 | // 1.获取两个字符串中不同的字符(区分大小写,本身字符串中有重复的也要去除)(例:abc与bcd -》 ad) 5 | // 2.得到的字符根据ASCII码从小到大排序 6 | // 3.根据第3步的结果生成一个对称字符串(例:abc -》abccba) 7 | 8 | 9 | function compare(str, str1) { 10 | var s = str + str1; 11 | var code = []; 12 | var arr = []; 13 | for (var i = 0, len = s.length; i < len; i++) { 14 | var char = s[i].charCodeAt(); 15 | if (code[char] != null) { 16 | code[char]++; 17 | } else { 18 | code[char] = 1; 19 | } 20 | } 21 | code.forEach(function (v, i) { 22 | if (v == 1) { 23 | arr.push(String.fromCharCode(i)); 24 | } 25 | }) 26 | return arr.join('')+arr.reverse().join(''); 27 | } 28 | 29 | console.log(compare("aAs185B23df","wqe12rd")); -------------------------------------------------------------------------------- /others/tenxun1.js: -------------------------------------------------------------------------------- 1 | // 判断数字是否被整除 2 | 3 | // 题目描述 4 | // 对于一个正整数n(0 <= n <= 10e9),若n各个数位之和能被n整除,则输出'Yes',否则输出'No'. 5 | 6 | // 输入描述 7 | // 每组有t+1行字符串 8 | // 第一行为整数t(表示接下来还有t行) 9 | // 剩下每行为一个整数n 10 | 11 | // 输出描述 12 | // 输出一个整数表示最多的掰法 13 | 14 | // 示例 15 | // 输入: 16 | // 7 17 | // 34 18 | // 66 19 | // 72 20 | // 6 21 | // 32 22 | // 33 23 | // 86 24 | 25 | // 输出: 26 | // No 27 | // No 28 | // Yes 29 | // Yes 30 | // No 31 | // No 32 | // No 33 | 34 | /* 35 | * util 牛客网 36 | */ 37 | var date = "" 38 | var patt = /(.+(?=\n))/g; 39 | 40 | function readline() { 41 | var line = patt.exec(date) 42 | return line ? line[1] : line; 43 | } 44 | var print = function (s) { 45 | console.log(s); 46 | } 47 | 48 | // set your date 49 | date = ` 50 | 7 51 | 34 52 | 66 53 | 72 54 | 6 55 | 32 56 | 33 57 | 86 58 | `; 59 | 60 | // write code here 61 | var t = parseInt(readline()); 62 | var sum, n, tmp; 63 | for(var i = 0;i < t; i++){ 64 | n = parseInt(readline()); 65 | tmp = n; 66 | sum = 0; 67 | while (tmp > 0) { 68 | sum += tmp % 10; 69 | tmp = Math.floor(tmp / 10); 70 | } 71 | print(n % sum == 0 ? 'Yes' : 'No' ); 72 | } -------------------------------------------------------------------------------- /others/tenxun2.js: -------------------------------------------------------------------------------- 1 | // 掰巧克力 2 | 3 | // 题目描述 4 | // 对于一段长度为t 的巧克力,最多可以掰成t段 5 | // 巧克力上随机有饼干球('1' 为有球,'0'为无球); 6 | // 现要求保证掰开的巧克力每段有且只有1个饼干球 7 | // 问最多有几种掰法? 8 | 9 | // 输入描述 10 | // 每组数据输入两行字符串,第一行为整数t 11 | // 第二行由t个0'或'1'组成(由' '分隔开) 12 | 13 | // 输出描述 14 | // 输出一个整数表示最多的掰法 15 | 16 | // 示例 17 | // 输入: 18 | // 4 19 | // 1 0 1 1 20 | 21 | // 输出: 22 | // 2 23 | 24 | 25 | /* 26 | * util 牛客网 27 | */ 28 | var date = "" 29 | var patt = /(.+(?=\n))/g; 30 | 31 | function readline() { 32 | var line = patt.exec(date) 33 | return line ? line[1] : line; 34 | } 35 | var print = function (s) { 36 | console.log(s); 37 | } 38 | 39 | // set your date 40 | date = ` 41 | 7 42 | 1 0 0 0 1 0 1 43 | `; 44 | 45 | // write code here 46 | var t = parseInt(readline()); 47 | var arr = readline().split(" "); 48 | var res = 0; 49 | var isFirst = true; 50 | var flag = false; 51 | var count = 1; 52 | for (let i = 0; i < t; i++) { 53 | var val = arr[i]; 54 | if (flag && val == '0') { 55 | count++; 56 | } else if (flag && val == '1') { 57 | res *= count; 58 | count = 1; 59 | } else if (val == '1') { 60 | flag = true; 61 | if (isFirst) { 62 | res = 1; 63 | isFirst = false; 64 | } 65 | } 66 | } 67 | print(res); -------------------------------------------------------------------------------- /others/tenxun3.js: -------------------------------------------------------------------------------- 1 | /* 2 | * util 牛客网 3 | */ 4 | var date = "" 5 | var patt = /(.+(?=\n))/g; 6 | 7 | function readline() { 8 | var line = patt.exec(date) 9 | return line ? line[1] : line; 10 | } 11 | var print = function (s) { 12 | console.log(s); 13 | } 14 | 15 | // set your date 16 | date = ` 17 | aaa 18 | aa 19 | `; 20 | 21 | // write code here 22 | var s = readline(); 23 | var p = readline().split(""); 24 | var arr = [p.join('')]; 25 | var len = p.length; 26 | var j = len - 1; 27 | for (let i = 0; i < len; i++) { 28 | if (p[i] == p[j]) { 29 | var s = p.concat(p.slice(i)); 30 | arr.push(s); 31 | } 32 | } 33 | for (let i = 0, l = arr.length; i < l; i++) { 34 | var r = new RegExp('(' + arr[i] + ')', g); 35 | console.log(r.exec(str)); 36 | } 37 | 38 | print(arr); 39 | --------------------------------------------------------------------------------