1.一年中的第几天
题目:
给你一个按 YYYY-MM-DD 格式表示日期的字符串 date,请你计算并返回该日期是当年的第几天。
通常情况下,我们认为 1 月 1 日是每年的第 1 天,1 月 2 日是每年的第 2 天,依此类推。每个月的天数与现行公元纪年法(格里高利历)一致。
思路:用Date转换为日期对象,获取时间戳,根据时间戳的差值来计算
/*** @param {string} date* @return {number}*/
var dayOfYear = function(date) {const time = 24 * 3600 * 1000;const cur = new Date(date).getTime();const start = new Date(`${date.slice(0, 4)}-01-01`).getTime();return (cur - start) / time + 1;
};
2.拼写单词
题目:
给你一份『词汇表』(字符串数组) words 和一张『字母表』(字符串) chars。
假如你可以用 chars 中的『字母』(字符)拼写出 words 中的某个『单词』(字符串),那么我们就认为你掌握了这个单词。
注意:每次拼写(指拼写词汇表中的一个单词)时,chars 中的每个字母都只能用一次。
返回词汇表 words 中你掌握的所有单词的 长度之和。
思路:记录字母表中的字符及出现的次数,遍历单词, 判断单词的字符有没有超过字母表
/*** @param {string[]} words* @param {string} chars* @return {number}*/
var countCharacters = function(words, chars) {const map1 = {};for (const s of chars) {map1[s] = (map1[s] || 0) + 1;}return words.filter((item) => {const a = JSON.parse(JSON.stringify(map1));for (const n of item) {if (!a[n]) return false;a[n]--;}return true}).reduce((a, b) => a + b.length, 0);
};
3.比较字符串最小字母出现频次
题目:
我们来定义一个函数 f(s),其中传入参数 s 是一个非空字符串;该函数的功能是统计 s 中(按字典序比较)最小字母的出现频次。
例如,若 s = "dcce",那么 f(s) = 2,因为最小的字母是 "c",它出现了 2 次。
现在,给你两个字符串数组待查表 queries 和词汇表 words,请你返回一个整数数组 answer 作为答案,其中每个 answer[i] 是满足 f(queries[i]) < f(W) 的词的数目,W 是词汇表 words 中的词。
思路:先封装方法,找到最小字母出现的次数
/*** @param {string[]} queries* @param {string[]} words* @return {number[]}*/
const f = (s) => {if(!s)return 0s = s.split("").sort((a, b) => a.charCodeAt() - b.charCodeAt());return s.filter((i) => i == s[0]).length;
};
var numSmallerByFrequency = function (queries, words) {words = words.map(f);return queries.map((item) => {const ci = f(item);return words.filter((i) => i > ci).length;});
};
4.指数排列
题目:
请你帮忙给从 1 到 n 的数设计排列方案,使得所有的「质数」都应该被放在「质数索引」(索引从 1 开始)上;你需要返回可能的方案总数。
让我们一起来回顾一下「质数」:质数一定是大于 1 的,并且不能用两个小于它的正整数的乘积来表示。
由于答案可能会很大,所以请你返回答案 模 mod 10^9 + 7 之后的结果即可。
思路:结果是质数的排列可能*非质数的排列可能,所以先计算是否是质数,然后计算质数和非质数的数量,最后排列组合。为了解决数字过大的问题,可以在每一步乘法里面都对mod取余
/*** @param {number} n* @return {number}*/
var numPrimeArrangements = function(n) {if (n < 3) return 1;let mod = 1000000007;let primeCount = 0;for (let i = 2; i <= n; i++) {if (isPrime(i)) primeCount++;}let a = total(primeCount);const noPrimeCount=n-primeCount;for (let i = 2; i <= noPrimeCount; i++) {a = (a * i) % mod;}return a;function isPrime(n) {for (let i = 2; i <= n / i; i++) {if (n % i === 0) return false;}return true;}function total(n) {if (n < 3) return n;return (total(n - 1) * n) % mod;}
};
5.公交站间的距离
题目:
环形公交路线上有 n 个站,按次序从 0 到 n - 1 进行编号。我们已知每一对相邻公交站之间的距离,distance[i] 表示编号为 i 的车站和编号为 (i + 1) % n 的车站之间的距离。
环线上的公交车都可以按顺时针和逆时针的方向行驶。
返回乘客从出发点 start 到目的地 destination 之间的最短距离。
思路:分别计算顺时针怎和逆时针时候的距离,取较小值
/*** @param {number[]} distance* @param {number} start* @param {number} destination* @return {number}*/
var distanceBetweenBusStops = function(distance, start, destination) {const l = distance.length;let a = 0,b = 0;for (let i = start; i != destination; i = (i + 1) % l) {a += distance[i];}for (let i = start; i != destination; i = (i - 1 + l) % l) {b += distance[(i - 1 + l) % l];}return Math.min(a, b);
};