题目:
给定一位研究者论文被引用次数的数组(被引用次数是非负整数)。编写一个方法,计算出研究者的 h 指数。
h 指数的定义:h 代表“高引用次数”(high citations),一名科研人员的 h 指数是指他(她)的 (N 篇论文中)总共有 h 篇论文分别被引用了至少 h 次。(其余的 N - h 篇论文每篇被引用次数 不超过 h 次。)
例如:某人的 h 指数是 20,这表示他已发表的论文中,每篇被引用了至少 20 次的论文总共有 20 篇。
思路:先对数组排序,因为对于某篇论文而言,大于等于该论文次数的论文数量,就是它后面的论文数量之和,所以找到第一个论文引用次数大于后续论文数量的论文,它的前一个论文的数量就是H指数
时间复杂度:O(n),空间复杂度O(1)
/** * @param {number[]} citations * @return {number} */ var hIndex = function(citations) { const l = citations.length; if (!l) return 0; citations.sort((a, b) => b - a); for (let i = 0; i < l; i++) { if (i + 1 > citations[i]) return i; } return l; };题目:
给定一位研究者论文被引用次数的数组(被引用次数是非负整数),数组已经按照 升序排列 。编写一个方法,计算出研究者的 h 指数。
h 指数的定义: “h 代表“高引用次数”(high citations),一名科研人员的 h 指数是指他(她)的 (N 篇论文中)总共有 h 篇论文分别被引用了至少 h 次。(其余的 N - h 篇论文每篇被引用次数不多于 h 次。)"
思路:和前一题完全一样,不同的是可以二分
时间复杂度:O(n),空间复杂度O(1)
/** * @param {number[]} citations * @return {number} */ var hIndex = function(citations) { const l = citations.length; for (let i = 0; i < l; i++) { if (citations[i] >= l - i) return l - i; } return 0 };题目:给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, ...)使得它们的和等于 n。你需要让组成和的完全平方数的个数最少。
思路:动态规划。某个数n对应的完全平方数的个数,最大的时候就是n(n个1相加),最小的时候,可以找出小于它的单个最大完全平方数,这个数是完全平方数,个数是1,然后计算两个数之差,相加即可
时间复杂度:O(n2),空间复杂度:O(n)
/** * @param {number} n * @return {number} */ var numSquares = function(n) { const list = new Array(n + 1).fill(0); for (let i = 1; i <= n; i++) { list[i] = i; for (let j = 1; i - j * j >= 0; j++) { list[i] = Math.min(list[i], list[i - j * j] + 1); } } return list[n]; };题目:
你在和朋友一起玩 猜数字(Bulls and Cows)游戏,该游戏规则如下:
你写出一个秘密数字,并请朋友猜这个数字是多少。 朋友每猜测一次,你就会给他一个提示,告诉他的猜测数字中有多少位属于数字和确切位置都猜对了(称为“Bulls”, 公牛),有多少位属于数字猜对了但是位置不对(称为“Cows”, 奶牛)。 朋友根据提示继续猜,直到猜出秘密数字。 请写出一个根据秘密数字和朋友的猜测数返回提示的函数,返回字符串的格式为 xAyB ,x 和 y 都是数字,A 表示公牛,用 B 表示奶牛。
xA 表示有 x 位数字出现在秘密数字中,且位置都与秘密数字一致。 yB 表示有 y 位数字出现在秘密数字中,但位置与秘密数字不一致。 请注意秘密数字和朋友的猜测数都可能含有重复数字,每位数字只能统计一次。
思路:分别统计两种数字的情况,为了去除重复数字,在每一次匹配奶牛数字时候,去掉该数字
时间复杂度:O(n2),空间复杂度:O(n)
/** * @param {string} secret * @param {string} guess * @return {string} */ var getHint = function(secret, guess) { const l = `${secret}`.length; let a = 0; let b = 0; const stack = []; const list = []; for (let i = 0; i < l; i++) { if (secret[i] === guess[i]) { a++; } else { stack.push(secret[i]); list.push(guess[i]); } } list.forEach((i) => { const index = stack.findIndex((item) => i == item); if (index >= 0) { b++; stack.splice(index, 1); } }); return `${a}A${b}B`; };题目:给定一个无序的整数数组,找到其中最长上升子序列的长度。
思路:动态规划。对于某一个数,他的最长上升子序列,是它之前的数字中,小于它数的上升子序列的长度+1,然后取max
时间复杂度:O(nlogn),空间复杂度:O(n)
/** * @param {number[]} nums * @return {number} */ var lengthOfLIS = function(nums) { const l = nums.length; if (!l) return 0; const list = new Array(l); list[0] = 1; for (let i = 1; i < l; i++) { list[i] = 1; for (let j = 0; j < i; j++) { if (nums[j] < nums[i]) { list[i] = Math.max(list[i], list[j] + 1); } } } return Math.max(...list); };