全排列 II
全排列 II
给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列。
输入:nums = [1,1,2]输出:[[1,1,2],[1,2,1],[2,1,1]]
输入:nums = [1,2,3]输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
1234567891011121314151617181920212223242526272829var permuteUnique = function(nums) { const res = []; const used = new Array(nums.length); nums.sort((a, b) => a - b); // 升序排序 const helper = (path) => { if (path.length == nums.length) { // 个数选够了 res.push(path.slice()); // pat ...
环形子数组的最大和
环形子数组的最大和
给定一个长度为 n 的环形整数数组 nums ,返回 nums 的非空 子数组 的最大可能和 。环形数组 意味着数组的末端将会与开头相连呈环状。形式上, nums[i] 的下一个元素是 nums[(i + 1) % n] , nums[i] 的前一个元素是 nums[(i - 1 + n) % n] 。子数组 最多只能包含固定缓冲区 nums 中的每个元素一次。形式上,对于子数组 nums[i], nums[i + 1], …, nums[j] ,不存在 i <= k1, k2 <= j 其中 k1 % n == k2 % n 。
输入:nums = [1,-2,3,-2]输出:3解释:从子数组 [3] 得到最大和 3
输入:nums = [5,-3,5]输出:10解释:从子数组 [5,5] 得到最大和 5 + 5 = 10
12345678910111213141516var maxSubarraySumCircular = function(nums) { const sum = nums.reduce((a,b)=> ...
子数组的最小值之和
子数组的最小值之和
给定一个整数数组 arr,找到 min(b) 的总和,其中 b 的范围为 arr 的每个(连续)子数组。由于答案可能很大,因此 返回答案模 10^9 + 7 。
输入:arr = [3,1,2,4]输出:17解释:子数组为 [3],[1],[2],[4],[3,1],[1,2],[2,4],[3,1,2],[1,2,4],[3,1,2,4]。最小值为 3,1,2,4,1,1,2,1,1,1,和为 17。
输入:arr = [11,81,94,43,3]输出:444
1234567891011121314151617var sumSubarrayMins = function(arr) { let ans = 0; let len = arr.length; let stack = [len]; let every = 0; for(let i=len-1;i>=0;i--){ while(stack.length && arr[stack[stack.length-1]] ...
零钱兑换
零钱兑换
给定不同面额的硬币 coins 和一个总金额 amount。编写一个函数来计算可以凑成总金额所需的最少的硬币个数。如果没有任何一种硬币组合能组成总金额,返回 -1。你可以认为每种硬币的数量是无限的。
输入:coins = [1, 2, 5], amount = 11输出:3解释:11 = 5 + 5 + 1
输入:coins = [2], amount = 3输出:-1
12345678910111213141516var coinChange = function(coins, amount) { // 初始化一个dp数组,为了方便初始化为Infinity,其实大于amount的都行吧 let dp = new Array(amount + 1).fill(Infinity); dp[0] = 0; // 面额为0的需要0个硬币兑换 for(let i = 1; i <= amount; i++) { // 循环面额 for(let coin of coins) { // 循环硬币数组 ...
组合总和 II
组合总和 II
给定一个可能有重复数字的整数数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。candidates 中的每个数字在每个组合中只能使用一次,解集不能包含重复的组合。
输入:candidates = [10,1,2,7,6,1,5], target = 8输出:[[1,1,6],[1,2,5],[1,7],[2,6]]
123456789101112131415161718var trainWays = function(n) { if (n < 2) return 1 let p = 1 let q = 1 let res = 2 for(let i = 2; i<n;i++){ // 每一次多加一步,前面的种类都不会变,因为新加的都是一步走了就行 // 那么只需要考虑最后一步是2步的情况,那么前面n-2的步数种类我也是知道的 // 那么n的种类就是fn(n - 2) + fn(n - ...
2出现的次数
2 出现的次数
编写一个方法,计算从 0 到 n (含 n) 中数字 2 出现的次数。
输入: 25输出: 9解释: (2, 12, 20, 21, 22, 23, 24, 25)(注意 22 应该算作两次)
1234567891011121314var numberOf2sInRange = function(n) { if(n < 2) return 0 let high = n / 10 >> 0, cur = n % 10, digit = 1, low = 0 , ans = 0 while(high || cur){ if(cur < 2) ans += high*digit else if(cur == 2) ans += high*digit + low + 1 else ans += high*digit + digit low += cur*digit cur=high%10 high = high/ ...
递归乘法
递归乘法
递归乘法。 写一个递归函数,不使用 * 运算符, 实现两个正整数的相乘。可以使用加号、减号、位移,但要吝啬一些。
输入:A = 1, B = 10输出:10示例 2:
输入:A = 3, B = 4输出:12
12345678910var multiply = function(A, B) {let min = Math.min(A,B); let max = Math.max(A,B); let count = 0; while (min) { count += max; min--; } return count;};
三步问题
三步问题
三步问题。有个小孩正在上楼梯,楼梯有 n 阶台阶,小孩一次可以上 1 阶、2 阶或 3 阶。实现一种方法,计算小孩有多少种上楼梯的方式。结果可能很大,你需要对结果模 1000000007。
输入:n = 3输出:4说明: 有四种走法
输入:n = 5输出:13
12345678var waysToStep = function(n) { const mod = 1000000007; const dp = [null, 1, 2, 4]; for (let i = 4; i <= n; i++) { dp[i] = (dp[i - 1] + dp[i - 2] + dp[i - 3]) % mod; } return dp[n];};
去掉最低工资和最高工资后的工资平均值
去掉最低工资和最高工资后的工资平均值
给你一个整数数组 salary ,数组里每个数都是 唯一 的,其中 salary[i] 是第 i 个员工的工资。请你返回去掉最低工资和最高工资以后,剩下员工工资的平均值。
输入:salary = [4000,3000,1000,2000]输出:2500.00000解释:最低工资和最高工资分别是 1000 和 4000 。去掉最低工资和最高工资以后的平均工资是 (2000+3000)/2= 2500
输入:salary = [1000,2000,3000]输出:2000.00000解释:最低工资和最高工资分别是 1000 和 3000 。去掉最低工资和最高工资以后的平均工资是 (2000)/1= 2000
123456789var average = function(salary) { let max = 0,min = 100010,sum=0; for(let i = 0 , len = salary.length;i < len;i++){ max = Math.max(max,sala ...
砍竹子 I
砍竹子 I
现需要将一根长为正整数 n 的竹子砍为若干段,每段长度均为正整数。请返回每段竹子长度的最大乘积是多少。
输入: n = 12输出: 81
123456789var cuttingBamboo = function(n) { const dp = new Array(n + 1).fill(1); for(let i = 2; i < n + 1; i++){ for(let j = 1; j < i; j++){ dp[i] = Math.max(Math.max((i - j) * j, j * dp[i - j]), dp[i]); } } return dp[n];};