牛客网约定:
输入: readline
输出: print, console.log
87,40, 59,
76,85
60
96

let reserveNumToString = (num) => { return num.toString().split('').reverse().join('') } let input = readline(); // 获取输入 print(reserveNumToString(input)) // 输出复制成功
let reverseStr = (str) => { return str.split('').reverse().join('') } let string = readline() print(reverseStr(string))复制成功
console.log(eval(readline()))复制成功
API:

动态规划 dp[i] & max

let short = readline() let long = readline() if(short.length > long.length) { let temp = short short = long long = temp } // let dp = new Array(short.length).fill(0) let dp = [] let max = 0 for(let i=0; i < short.length; i++) { for(let j=0; j <= i; j++) { let str = short.slice(j, i+1) if(long.indexOf(str) > -1) { dp[i] = Math.max(str.length, dp[i] || 0) max = Math.max(max, dp[i] || 0) } } } print(max)复制成功
let isNico = (num) => { let total = Math.pow(num,3) let arr = [] let firstIndex = Math.pow(num,2) - (num -1) let lastIndex = Math.pow(num,2) + (num -1) for(let i=firstIndex; i <= lastIndex; i+=2) { arr.push(`${i}`) } // while(num--) { // arr.push(`${firstIndex}`) // firstIndex += 2 // } return arr.join('+') } let number = readline() print(isNico(number))复制成功
const judge = (str) => { return str === str.split('').reverse().join('') } const dp = [] let max = 0 const getSubstrLength = (str) => { for(let i=0; i < str.length; i++) { for(let j=i+1; j <= str.length; j++) { let tempStr = str.slice(i,j) if(judge(tempStr)) { dp[i] = Math.max(tempStr.length, dp[i]||0) max = Math.max(max, dp[i]||0) } } } } getSubstrLength(readline()) console.log(max)复制成功
let input = readline() let getNumTimes = (number) => { let arr = parseInt(number).toString(2).split('0') let result = 0 for(let i=0; i < arr.length; i++) { if(arr[i].length > result) { result = arr[i].length } } return result } console.log(getNumTimes(input))复制成功
diu 这么长
直接抄题解
function getScore(str) { const length = str.length; const map = { len: length, upperCaseLetters: 0, lowerCaseLetters: 0, symbols: 0, numbers: 0, }; let score = 0; for (let i = 0; i < length; i++) { const code = str[i].charCodeAt(0); if (code >= 48 && code <= 57) { map.numbers++; } else if (code >= 65 && code <= 90) { map.upperCaseLetters++; } else if (code >= 97 && code <= 122) { map.lowerCaseLetters++; } else { map.symbols++; } } // 长度 if (map.len >= 8) { score += 25; } else if (map.len >= 5 && map.len <= 7) { score += 10; } else { score += 5; } // 数字 if (map.numbers === 1) { score += 10; } else if (map.numbers > 1) { score += 20; } // 字母 if (map.upperCaseLetters > 0 && map.lowerCaseLetters > 0) { score += 20; } else if (map.upperCaseLetters > 0 || map.lowerCaseLetters > 0) { score += 10; } // 符号 if (map.symbols === 1) { score += 10; } else if (map.symbols > 1) { score += 25; } // 奖励 if (map.numbers > 0) { if ( map.upperCaseLetters > 0 && map.lowerCaseLetters > 0 && map.symbols > 0 && map.numbers > 0 ) { score += 5; } else if ( (map.upperCaseLetters > 0 || map.lowerCaseLetters > 0) && map.symbols > 0 && map.numbers > 0 ) { score += 3; } else if (map.upperCaseLetters > 0 || map.lowerCaseLetters > 0) { score += 2; } } if (score >= 90) { return "VERY_SECURE"; } else if (score >= 80) { return "SECURE"; } else if (score >= 70) { return "VERY_STRONG"; } else if (score >= 60) { return "STRONG"; } else if (score >= 50) { return "AVERAGE"; } else if (score >= 25) { return "WEAK"; } else { return "VERY_WEAK"; } }复制成功
an = a1 + (n-1)d
while(line = readline()) { const num = parseInt(line); let total = 0; for (let i = 2; i <= 2 + 3*(num-1); i = i+3) { total += i; } print(total); }复制成功
let line = readline() let result = line.split('').reverse().join('') print(result)复制成功
parseInt(data, radix)
const hexTodec = (hex) => parseInt(hex,16) let result = hexTodec(readline()) print(result)复制成功
let line = readline() let result = new Set(line.split('')).size print(result)复制成功
let input = parseInt(readline()) function sortWordList(num) { const wordList = [] while(num--) { wordList.push(readline()) } wordList.sort((a,b) => a > b ? 1:-1).forEach(item => {console.log(item)}) } sortWordList(input)复制成功
function countChar(str) { const arr = str.split('') let map = { letters: 0, space: 0, numbers: 0, symbols:0 } for(let item of arr){ let code = item.charCodeAt() if(code >=65 && code <=90 || code >=97 && code <=122) { map.letters++ } else if(code >=48 && code <=57 ) { map.numbers++ } else if(code === 32) { map.space++ }else { map.symbols++ } } print(map.letters) print(map.space) print(map.numbers) print(map.symbols) } countChar(readline())复制成功
function mySlice(str, end) { return str.slice(0, end) } const result = mySlice(readline(), readline()) print(result)复制成功
注意输入。第一行输入n和k,相当于输入有空格的字符串啦
let [n, k] = readline().split(' ') let multies = readline() const getSortedArr = (str) => { const arr = str.trim().split(' ') return arr.sort((a, b) => a - b) } let result = getSortedArr(multies).slice(0, k).join(' ') print(result) // let [n, k] = readline().split(' ') let secArr = readline().split(' ') secArr = secArr.sort((a, b) => a - b).slice(0, k) print(secArr.join(' '))复制成功
${str[i]}, 'g')
function getOnceFirstChar(str) { let res = -1 for(let i=0; i < str.length; i++){ let reg = new RegExp(`${str[i]}`,'g') if(str.match(reg).length == 1){ res = str[i] break } } return res } let result = getOnceFirstChar(readline()) print(result)复制成功
i < Math.ceil(n / ``2``)function isPrime(num) { const temp = Math.floor(Math.sqrt(num)) //为什么是2 for(let i=2; i <= temp; i++) { if(num % i === 0) { return false } } return true } function getPrimesFromEven(num) { let result = [] for(let i=2; i <= Math.floor(num / 2); i++) { if(isPrime(i) && isPrime(num-i)) { result = [i, num-i] } } print(result[0]) print(result[1]) } getPrimesFromEven(readline())复制成功
const short = readline() const long = readline() function cook(short='', long) { let arr = short.split('') return arr.every(item => long.includes(item)) //both okay //return short.split('').every(char => long.indexOf(char) !== -1) } let result = cook(short, long) print(result)复制成功
正则
string.replace(regExp, function)
function padStar(str) { return str.replace(/[0-9]+/g, val => `*${val}*`) } print(padStar(readline()))复制成功
/** * @param {number} n * @param {number} m * @return {number} */ var lastRemaining = function(n, m) { // 迭代 f(n) = [f(n-1) + m] % n // i <= n 的解释:两个人就要通过迭代来找,需要参与循环 let now = 0 for(let i=2; i <= n; i++) { now = (now + m ) % i } return now };复制成功
let left = 0, right = 0; while (right < s.size()) { // 增大窗口 window.add(s[right]); right++; while (window needs shrink) { // 缩小窗口 window.remove(s[left]); left++; } }复制成功
套入即可
这里的题意隐藏条件 没有给定具体的数组num 我们可以通过下标关联[1,2,3,4,5,6,7....]
/** * @param {number} target * @return {number[][]} */ // 没有参照物数组 但是可以根据下标 // 滑动窗口(双指针) var findContinuousSequence = function(target) { let l=1 let r=2 let sum = 3 let res=[] // 滑动窗口框架 while(l<r){ if(sum===target){ let ans =[] for(let k=l;k<=r;k++){ ans[k-l]=k } res.push(ans) // 等于的情况 我们可以继续窗口往右搜索 同时缩小左边的 sum=sum-l l++ } else if(sum>target){ // 大于的条件 缩小窗口 sum已经加过了 sum=sum-l l++ } else { // 小于的情况 滑动窗口继续扩大 r++ sum=sum+r } } return res }; //[题解链接](https://leetcode-cn.com/problems/he-wei-sde-lian-xu-zheng-shu-xu-lie-lcof/solution/song-gei-qian-duan-tong-xue-tong-su-yi-d-u7z9/)复制成功
var lengthOfLongestSubstring = function(s) { // 哈希集合,记录每个字符是否出现过 const occ = new Set(); const n = s.length; // 右指针,初始值为 -1,相当于我们在字符串的左边界的左侧,还没有开始移动 let rk = -1, ans = 0; for (let i = 0; i < n; ++i) { if (i != 0) { // 左指针向右移动一格,移除一个字符 occ.delete(s.charAt(i - 1)); } while (rk + 1 < n && !occ.has(s.charAt(rk + 1))) { // 不断地移动右指针 occ.add(s.charAt(rk + 1)); ++rk; } // 第 i 到 rk 个字符是一个极长的无重复字符子串 ans = Math.max(ans, rk - i + 1); } return ans; };复制成功
时间复杂度:O(N)O(N),其中 NN 是字符串的长度。左指针和右指针分别会遍历整个字符串一次。
空间复杂度:O(|\Sigma|)O(∣Σ∣),其中 \SigmaΣ 表示字符集(即字符串中可以出现的字符),|\Sigma|∣Σ∣ 表示字符集的大小。在本题中没有明确说明字符集,因此可以默认为所有 ASCII 码在 [0, 128)[0,128) 内的字符,即 |\Sigma| = 128∣Σ∣=128。我们需要用到哈希集合来存储出现过的字符,而字符最多有 |\Sigma|∣Σ∣ 个,因此空间复杂度为 O(|\Sigma|)O(∣Σ∣)。
/** * @param {string[]} strs * @return {string} */ var longestCommonPrefix = function(strs) { if(strs.length === 1) return strs[0] let ans = strs[0] for(let i=1; i < strs.length; i++) { let j=0 for(; j < ans.length; j++) { if(ans[j] !== strs[i][j]) { break } } ans = ans.slice(0, j) } return ans };复制成功
//待定复制成功
https://leetcode-cn.com/problems/reverse-words-in-a-string/solution/151-fan-zhuan-zi-fu-chuan-li-de-dan-ci-j-zle0/
/** * @param {string} s * @return {number} */ var countSegments = function(s) { // return s.split(' ').filter(c => c).length let segmentCount = 0 for(let i=0; i < s.length; i++) { if((i === 0 || s[i-1] === ' ') && s[i]!== ' ' ) { segmentCount++ } } return segmentCount };复制成功
解题思路 这道题最难的地方在于,读懂题目!!!“如果对这个子数组进行升序排序,那么整个数组都会变为升序排序”,理解了这句话就很简单了。
数组复制一份,从小到大排序,用两个指针分别从左右开始移动,如果原数组中的元素和排序后一致,就可以继续移动,否则退出。最后判断一下两个指针的位置就可以了。
original: [2,6,4,8,10,9,15] sorted : [2,4,6,8,9,10,15] i ->
<- j 代码
/** * @param {number[]} nums * @return {number} */ var findUnsortedSubarray = function(nums) { const copied = nums.slice(0).sort((a, b) => a - b) let i = 0 let j = nums.length - 1 while (copied[i] === nums[i] && i < nums.length) { i++ } while (copied[j] === nums[j] && j >= 0) { j-- } if (i >= j) { return 0 } return j - i + 1 };复制成功
https://leetcode-cn.com/problems/greatest-common-divisor-of-strings/solution/1071-zi-fu-chuan-de-zui-da-gong-yin-zi-by-wonderfu/
看到标题里面有最大公因子这个词,于是先默写一下 gcd 算法
const gcd = (a, b) => (0 === b ? a : gcd(b, a % b))
总有一种好像顺手就能用上的感觉呢。
其实看起来两个字符串之间能有这种神奇的关系是挺不容易的,我们希望能够找到一个简单的办法识别是否有解。
如果它们有公因子 abc,那么 str1 就是 mm 个 abc 的重复,str2 是 nn 个 abc 的重复,连起来就是 m+nm+n 个 abc,好像 m+nm+n 个 abc 跟 n+mn+m 个 abc 是一样的。
所以如果 str1 + str2 === str2 + str1 就意味着有解。
我们也很容易想到 str1 + str2 !== str2 + str1 也是无解的充要条件。
当确定有解的情况下,最优解是长度为 gcd(str1.length, str2.length) 的字符串。
这个理论最优长度是不是每次都能达到呢?是的。
因为如果能循环以它的约数为长度的字符串,自然也能够循环以它为长度的字符串,所以这个理论长度就是我们要找的最优解。
把刚刚写的那些拼起来就是解法了。
var gcdOfStrings = function(str1, str2) { if (str1 + str2 !== str2 + str1) return '' const gcd = (a, b) => (0 === b ? a : gcd(b, a % b)) return str1.substring(0, gcd(str1.length, str2.length)) };复制成功
// 不知道干嘛的,先照抄吧 let mid=max>>1; return arr.map(item=>item>mid?1:0);复制成功
先计算seq每个位置i对应的深度arr[i] 在arr中最大深度max 取深度的一半mid,若某个点arr[i]>mid,那么将其分配给B,否则分配给A 例如:最大深度为4,无论如何取值max(deepth(A),deepth(B))都不可能比2小了,那么将所有深度大于2的都分配给B,深度小于2的都分配给A,那么此时的max(deepth(A),deepth(B))最小并为:2
var maxDepthAfterSplit = function(seq) { let deep=0; let arr=new Array(seq.length); let max=0; for(let i=0;i<seq.length;i++){ if(seq[i]==="("){ deep++; } arr[i]=deep; max=Math.max(max,deep) if(seq[i]===")"){ deep--; } } let mid=max>>1; return arr.map(item=>item>mid?1:0); }; //链接:https://leetcode-cn.com/problems/maximum-nesting-depth-of-two-valid-parentheses-strings/solution/javascript-by-wanyan/复制成功
也是通过排序+二分法获取最大子串长度解决的。
将height升序排列,如果遇到同值,将对应序列的weight进行降序排列 使用二分法获取weight的最大子串的长度,就是最终结果(有关二分法获取最大子串长度可以参考第300题的题解)
/** * @param {number[]} height * @param {number[]} weight * @return {number} */ var bestSeqAtIndex = function(height, weight) { const data = []; const dp = []; for(let i = 0;i < height.length;i++) { const item = { height: height[i], weight: weight[i] }; data.push(item); } data.sort(function(a, b) { if(a.height === b.height) { return b.weight - a.weight; } return a.height - b.height; }); // 利用二分法获取weight的最长子串的值就是结果 let res = 0; for(let index in data) { index = Number(index); let w = data[index].weight; let i = 0; let j = res; while(i < j) { const m = parseInt((i + j) / 2); if(dp[m] < w) { i = m + 1; } else { j = m; } } dp[i] = w; if(j === res) res++; } return res; };复制成功