FCC上的javascript算法题之中级篇
FCC中的javascript中级算法题解答
中级算法的题目中用到了很多js的知识点,比如迭代,闭包,以及对json数据的使用等等,现在将自己中级算法的解答思路整理出来供大家参考讨论。欢迎大家提出新的思路,写出更简单的解法。
1.给一个包含两个数字的数组。返回这两个数字和它们之间所有数字的和。
说明:最小的数字并非总在最前面
如:sumAll([4, 1])
应该返回 10。
sumAll([5, 10])
应该返回 45。
function sumAll(arr) {
var max=Math.max(arr[0],arr[1]);
var min=Math.min(arr[0],arr[1]);
var num=0;
for(var i=min; i<=max; i++){
num+=i;
}
return num;
}
2.比较两个数组,然后返回一个新数组,该数组的元素为两个给定数组中所有独有的数组元素。换言之,返回两个数组的差异。
如:[1, 2, 3, 5], [1, 2, 3, 4, 5]
应该返回 [4]
。
[1, "calf", 3, "piglet"], [1, "calf", 3, 4]
应该返回 ["piglet", 4]
。
function diff(arr1, arr2) {
var newArr = [];
//过滤数组1中与数组2相等的项
var arr1Filtered=arr1.filter(function(num){
for(var i=0; i<arr2.length; i++){
if(num==arr2[i]){
return false;
}
}
return true;
});
//过滤数组2中与数组1相等的项
var arr2Filtered=arr2.filter(function(num){
for(var i=0; i<arr1.length; i++){
if(num==arr1[i]){
return false;
}
}
return true;
});
//连接两个数组
newArr=arr1Filtered.concat(arr2Filtered);
return newArr;
}
3.将给定的数字转换成罗马数字。
说明:关于罗马数字请参考 http://www.baike.com/wiki/%E7%BD%97%E9%A9%AC%E6%95%B0%E5%AD%97&prd=so_1_doc
如:convert(2)
应该返回 "II"。
convert(16)
应该返回 "XVI"。
convert(501)
应该返回 "DI"。
convert(3999)
应该返回 "MMMCMXCIX"。
function convert(num) {
var one='';
var two='';
var three='';
var four='';
var arr=num.toString().split('');
//对不同位数传入不同参数,调用toRomChar函数
one=toRomChar(arr[arr.length-1],'I','V','X');
two=toRomChar(arr[arr.length-2],'X','L','C');
three=toRomChar(arr[arr.length-3],'C','D','M');
four=toRomChar(arr[arr.length-4],'M','',''); return four+three+two+one;
} function toRomChar(oneNum,char1,char2,char3){
var rom="";
//数字小于4时,输出'III'形式
if(oneNum<4){
for(var i=0; i<oneNum; i++){
rom+=char1;
}
}
//数字等于于4时,输出'IV'形式
else if(oneNum==4){
rom=char1+char2;
}
//数字大于4小于9时,输出'VIII'形式
else if(4<oneNum&&oneNum<=8){
rom=char2;
for(var k=0; k<oneNum-5; k++){
rom+=char1;
}
}
//数字等于9时,输出'I '形式
else if(oneNum==9){
rom=char1+char3;
}
return rom;
}
4.写一个 function,它遍历一个对象数组(第一个参数)并返回一个包含相匹配的属性-值对(第二个参数)的所有对象的数组。如果返回的数组中包含 source 对象的属性-值对,那么此对象的每一个属性-值对都必须存在于 collection 的对象中。
说明:例如,如果第一个参数是 [{ first: "Romeo", last: "Montague" }, { first: "Mercutio", last: null }, { first: "Tybalt", last: "Capulet" }]
,第二个参数是 { last: "Capulet" }
,那么你必须从数组(第一个参数)返回其中的第三个对象,因为它包含了作为第二个参数传递的属性-值对。
如:where([{ first: "Romeo", last: "Montague" }, { first: "Mercutio", last: null }, { first: "Tybalt", last: "Capulet" }], { last: "Capulet" })
应该返回 [{ first: "Tybalt", last: "Capulet" }]
。
where([{ "a": 1 }, { "a": 1 }, { "a": 1, "b": 2 }], { "a": 1 })
应该返回 [{ "a": 1 }, { "a": 1 }, { "a": 1, "b": 2 }]
。
where([{ "a": 1, "b": 2 }, { "a": 1 }, { "a": 1, "b": 2, "c": 2 }], { "a": 1, "b": 2 })
应该返回 [{ "a": 1, "b": 2 }, { "a": 1, "b": 2, "c": 2 }]
。
where([{ "a": 1, "b": 2 }, { "a": 1 }, { "a": 1, "b": 2, "c": 2 }], { "a": 1, "c": 2 })
应该返回 [{ "a": 1, "b": 2, "c": 2 }]
。
注:此题目描述不易理解,可结合参数及要返回的值进行理解
function where(collection, source) {
var arr = [];
var porp=Object.keys(source);
arr=collection.filter(function(obj){
for(var i=0; i<porp.length; i++){
if(obj[porp[i]]!==source[porp[i]]){
//判断参数1中各个对象的porp属性的值是否与参数二中的porp属性值相等
return false;
}
}
return true;
});
return arr;
}
5.使用给定的参数对句子执行一次查找和替换,然后返回新句子。
说明:
第一个参数是将要对其执行查找和替换的句子。
第二个参数是将被替换掉的单词(替换前的单词)。
第三个参数用于替换第二个参数(替换后的单词)。
注意:替换时保持原单词的大小写。例如,如果你想用单词 "dog" 替换单词 "Book" ,你应该替换成 "Dog"。
如:myReplace("Let us go to the store", "store", "mall")
应该返回 "Let us go to the mall"。
myReplace("His name is Tom", "Tom", "john")
应该返回 "His name is John"。
function myReplace(str, before, after) {
//判断before字符串首字母是否大写,若是,则将after字符串首字母也替换为大写;
if(before.charAt(0)<'a'){
var a=after.charAt(0);
after=after.replace(a,a.toUpperCase());
}
str=str.replace(before,after);
return str;
}
6.把指定的字符串翻译成 pig latin。
说明:PIg latin是把一个英文单词的第一个辅音或辅音丛(consonant cluster)移到词尾,然后加上后缀 "ay"。如果单词以元音开始,你只需要在词尾添加 "way" 就可以了。
如:translate("california")
应该返回 "aliforniacay"。
translate("eight")
应该返回 "eightway"。
translate("glove")
应该返回 "oveglay"。
function translate(str) {
var p=/[^aeiou]/;
var index=0;
//计算出第一个元音字母在字符串中的位置
for(var i=0; i<str.length; i++){
if(p.test(str.charAt(i))){
continue;
}
index = i;
break;
}
//元音字母为首字母时,给字符串加way后缀
if(index===0){
str+='way';
}
//将辅音丛加至结尾,并加上'ay'后缀
else{
var arr=str.split('');
var del=arr.splice(0,index);
arr=arr.concat(del);
str=arr.join('') + 'ay';
}
return str;
}
7.Base pairs 是一对 AT 和 CG,为给定的字母匹配缺失的碱基。
说明:例如,对于输入的 GCG,相应地返回 [["G", "C"], ["C","G"],["G", "C"]]
如:pair("ATCGA")
应该返回 [["A","T"],["T","A"],["C","G"],["G","C"],["A","T"]]
。
pair("CTCTA")
应该返回 [["C","G"],["T","A"],["C","G"],["T","A"],["A","T"]]
。
function pair(str) {
var newArr=[];
var arr=str.split('');
for(var i=0; i<arr.length; i++){
switch(arr[i]){
case 'A':
newArr.push(['A','T']);
break;
case 'T':
newArr.push(['T','A']);
break;
case 'G':
newArr.push(['G','C']);
break;
case 'C':
newArr.push(['C','G']);
break;
}
}
return newArr;
}
8.从传递进来的字母序列中找到缺失的字母并返回它。
如:fearNotLetter("abce")
应该返回 "d"。
function fearNotLetter(str) {
//将字符串转为ASCII码,并存入数组
var arr=[];
for(var i=0; i<str.length; i++){
arr.push(str.charCodeAt(i));
}
for(var j=1; j<arr.length; j++){
var num=arr[j]-arr[j-1];
//判断后一项减前一项是否为1,若不为1,则缺失该字符的前一项
if(num!=1){
//将缺失字符ASCII转为字符并返回
return String.fromCharCode(arr[j]-1);
}
}
return undefined;
}
9.检查一个值是否是基本布尔类型,并返回 true 或 false。
function boo(bool) {
// What is the new fad diet for ghost developers? The Boolean.
if(bool===false){
return true;
}
else if(bool===true){
return true;
}
else{
return false;
}
}
10.写一个 function,传入两个或两个以上的数组,返回一个以给定的原始数组排序的不包含重复值的新数组。
说明:所有数组中的所有值都应该以原始顺序被包含在内,但是在最终的数组中不包含重复值。
如:unite([1, 3, 2], [5, 2, 1, 4], [2, 1])
应该返回 [1, 3, 2, 5, 4]
。
unite([1, 2, 3], [5, 2, 1, 4], [2, 1], [6, 7, 8])
应该返回 [1, 2, 3, 5, 4, 6, 7, 8]
。
function unite(arr1, arr2, arr3) {
for(var j=1; j<arguments.length; j++){
//过滤掉第j个数组中已经在前面出现过的值
var filteredArr=arguments[j].filter(function(num){
for(var i=0; i<arr1.length; i++){
if(arr1[i]==num){
return false;
}
}
return true;
});
arr1=arr1.concat(filteredArr);
}
return arr1;
}
11.将字符串中的字符 &
、<
、>
、"
(双引号), 以及 '
(单引号)转换为它们对应的 HTML 实体。
如:convert("Dolce & Gabbana")
应该返回 Dolce & Gabbana
。
convert("Sixty > twelve")
应该返回 Sixty > twelve
。
function convert(str) {
var p=/[&<>"']/g;
str=str.replace(p,function(char){
switch(char){
case '&':
return '&';
case '<':
return '<';
case '>':
return '>';
case '"':
return '"';
case "'":
return ''';
}
});
return str;
}
12.将字符串转换为 spinal case。Spinal case 是 all-lowercase-words-joined-by-dashes 这种形式的,也就是以连字符连接所有小写单词。
如:spinalCase("The_Andy_Griffith_Show")
应该返回 "the-andy-griffith-show"
。
spinalCase("This Is Spinal Tap")
应该返回 "this-is-spinal-tap"
。
function spinalCase(str) {
// "It's such a fine line between stupid, and clever."
// --David St. Hubbins
var newStr='';
var p=/[\s_]/g; if(!p.test(str)){
var arr=str.split('');
for(var i=0; i<arr.length; i++){
if(arr[i]<'a'){
newStr=newStr+' ';
}
newStr=newStr+arr[i];
}
str=newStr;
}
//判断传入字符串中间是否含有空字符,若没有则在各单词间加入空格
str=str.toLowerCase();
str=str.replace(p,'-');
//将字符串转为小写并将其中的空格及下划线替换为中划线
return str;
}
13.给一个正整数num
,返回小于或等于num
的斐波纳契奇数之和。
说明:斐波纳契数列中的前几个数字是 1、1、2、3、5 和 8,随后的每一个数字都是前两个数字之和。
如:sumFibs(4)应该返回 5。
sumFibs(1000)
应该返回 1785。
sumFibs(75025)
应该返回 135721。function sumFibs(num) {
//求得小于num的斐波那契数列 注意:此数组最后一项大于num
var arr=[1,1];
for(var i=0; i<num; i++){
arr[i+2]=arr[i]+arr[i+1];
if (arr[i+2]>num){
break;
}
}
//删除最后一项,过滤掉数列中的偶数项
arr.splice(-1,1);
arr=arr.filter(function(n){
if(n%2===0){
return false;
}
return true;
});
//对数列进行求和
var result=arr.reduce(function(a,b){
return a+b;
});
return result;
}
14.求小于等于给定数值的质数之和。
说明:只有 1 和它本身两个约数的数叫质数。例如,2 是质数,因为它只能被 1 和 2 整除。1 不是质数,因为它只能被自身整除。给定的数不一定是质数。
如:sumPrimes(10)
应该返回 17。
function sumPrimes(num) {
//将所有小于等于num的质数放进一个数组
var arr=[];
//1不是质数,从2开始循环,需算上num
for(var i=2; i<=num; i++){
var j=2;
//判断i能否被从2开始的数整除
while(i%j!==0){
j++;
}
//判断这个数是不是自身,是则加进数组
if(i==j){
arr.push(i);
}
}
//对数组求和
var result=arr.reduce(function (a,b){return a+b;}); return result;
}
15.找出能被两个给定参数和它们之间的连续数字整除的最小公倍数。
说明:范围是两个数字构成的数组,两个数字不一定按数字顺序排序。例如对 1 和 3 —— 找出能被 1 和 3 和它们之间所有数字整除的最小公倍数。
如:smallestCommons([1, 5])
应该返回 60。
smallestCommons([5, 1])
应该返回 60。
smallestCommons([1, 13])
应该返回 360360。
function smallestCommons(arr) {
/*
*此算法的思路是,先将传入的数组排序并补全,然后用数组的最后一项依次除以数组的其它各项,如果不能整
*除则给最后一项加上原来数组的最后一项的值,重新进行前面的判断,直到数组中所有项均可被整除,即可
*得到传入数组中所包含的数的最小公倍数
*/
//对数组排序
arr.sort(function(a,b){return a-b;});
//补全数组
var arrLast=arr[arr.length-1];
for(var j=1; j<arrLast-arr[0]; j++){
arr.splice(j,0,arr[0]+j);
} var k=0;
var num=arr[arr.length-1];
while(k===0){
for(var i=0; i<arr.length-1 ;i++){
//判断数组中从第一个数起至倒数第二个数,能否被最后一个数整除,若不能则跳出内部循环
if(num%arr[i]!==0){
break;
}
//如果这个数可以被整除,而且这个数是数组的倒数第二个数时,结束外部循环
else if(i==arr.length-2){
k=1;
}
}
//不能整除时,给num加上数组的最后一项的值
num+=arr[arr.length-1];
} return num-arr[arr.length-1];
}
16.写一个 function,它浏览数组(第一个参数)并返回数组中第一个通过某种方法(第二个参数)验证的元素。
如:find([1, 3, 5, 8, 9, 10], function(num) { return num % 2 === 0; })
应该返回 8。
find([1, 3, 5, 9], function(num) { return num % 2 === 0; })
应该返回 undefined。
function find(arr, func) {
var newArr=arr.filter(func);
return newArr[0];
}
17.弃数组(arr)的元素,从左边开始,直到回调函数return true就停止。
说明:第二个参数,func
,是一个函数。用来测试数组的第一个元素,如果返回fasle,就从数组中抛出该元素(注意:此时数组已被改变),继续测试数组的第一个元素,如果返回fasle,继续抛出,直到返回true。最后返回数组的剩余部分,如果没有剩余,就返回一个空数组。
如:drop([1, 2, 3, 4], function(n) {return n >= 3;})
应该返回 [3, 4]
。
drop([1, 2, 3, 9, 2], function(n) {return n > 2;})
应该返回 [3, 9, 2]
。
function drop(arr, func) {
// Drop them elements.
var i=0;
do{
for(; i<arr.length; i++){
//遍历数组,若不满足回调函数,则将该项从数组中删除
if(!func.call(func,arr[i])){
//执行splice后数组长度减少1
arr.splice(i,1);
break;
}
}
}
//判断减少一项后数组的第i项(即原数组中的第i+1项)是否满足回调函数,若不满足则继续循环,直到满足为止
while(!func.call(func,arr[i]));
return arr;
}
18.对嵌套的数组进行扁平化处理。你必须考虑到不同层级的嵌套。
如:steamroller([1, [2], [3, [[4]]]])
应该返回 [1, 2, 3, 4]
。
steamroller([1, [], [3, [[4]]]])
应该返回 [1, 3, 4]
。
steamroller([1, {}, [3, [[4]]]])
应该返回 [1, {}, 3, 4]
。
function steamroller(arr) {
var newArr=[];
for(var i=0; i<arr.length; i++){
if(!Array.isArray(arr[i])){
newArr.push(arr[i]);
}else{
newArr=newArr.concat(steamroller(arr[i]));
}
}
return newArr;
}
此题的解法是在一个for循环中使用了递归,在for循环中使用递归时,不会影响for循环的进程。
19.传入二进制字符串,翻译成英语句子并返回
说明:二进制字符串是以空格分隔的。
如:binaryAgent("01000001 01110010 01100101 01101110 00100111 01110100 00100000 01100010 01101111 01101110 01100110 01101001 01110010 01100101 01110011 00100000 01100110 01110101 01101110 00100001 00111111")
应该返回 "Aren't bonfires fun!?"
binaryAgent("01001001 00100000 01101100 01101111 01110110 01100101 00100000 01000110 01110010 01100101 01100101 01000011 01101111 01100100 01100101 01000011 01100001 01101101 01110000 00100001")
应该返回 "I love FreeCodeCamp!"
function binaryAgent(str) {
var result='';
var arr=str.split(' ');
for(var i=0; i<arr.length; i++){
//二进制转化为十进制
var num=parseInt(arr[i],2);
str=String.fromCharCode(num);
result+=str;
}
return result;
}
20.完善编辑器中的every函数,如果集合(collection)中的所有对象都存在对应的属性(pre),并且属性(pre)对应的值为真。函数返回ture。反之,返回false。
如:every([{"user": "Tinky-Winky", "sex": "male"}, {"user": "Dipsy", "sex": "male"}, {"user": "Laa-Laa", "sex": "female"}, {"user": "Po", "sex": "female"}], "sex")
应该返回 true。
every([{"user": "Tinky-Winky", "sex": "male"}, {"user": "Dipsy"}, {"user": "Laa-Laa", "sex": "female"}, {"user": "Po", "sex": "female"}], "sex")
应该返回 false。
every([{"single": "double"}, {"single": undefined}], "single")
应该返回 false。
function every(collection, pre) {
var result=collection.every(function(obj){
return obj[pre];
});
return result;
}
21.创建一个计算两个参数之和的 function。如果只有一个参数,则返回一个 function,该 function 请求一个参数然后返回求和的结果
说明:例如,add(2, 3)
应该返回 5
,而 add(2)
应该返回一个 function。
如:add(2, 3)
应该返回 5。
add(2)(3)
应该返回 5。
add(2, "3")
应该返回 undefined。
function add() {
if(arguments.length==1&&typeof arguments[0]=='number'){
var num = arguments[0];
return function(a){
if(typeof a=='number') return a+num;
};
}else if(typeof arguments[0]=='number'&&typeof arguments[1]=='number'){
return arguments[0]+arguments[1];
}else{
return undefined;
}
}
具体题目可参考FCC中文网:https://freecodecamp.cn
总结一下,中级算法对js的很多概念的理解还是很有帮助的,推荐对js不够熟悉的同学练习一下。
文中的算法已尽可能的做到简洁高效,但依然有很大的改进空间,例如16题找出最小公倍数,我最初使用的方法是从1开始判断1是否是这个数组所有元素的最小公倍数,若不是则判断2是否为此数组的最小公倍数,以此递增,最终找出数组中所有元素的最小公倍数。此方法虽然可行,但性能极差,经过改进后的算法如文中16题中所给的代码,但这绝不是最优解,我相信大家都会有更好的思路。欢迎大家指出其中的不足,并给出自己的宝贵意见。
感谢阅读。
FCC上的javascript算法题之中级篇的更多相关文章
- FCC上的初级算法题
核心提示:FCC的算法题一共16道.跟之前简单到令人发指的基础题目相比,难度是上了一个台阶.主要涉及初步的字符串,数组等运算.仍然属于基础的基础,官方网站给出的建议完成时间为50小时,超出了之前所有非 ...
- JavaScript算法题之–随机数的生成
JavaScript算法题之–随机数的生成 需求描述:从一组有序的数据中生成一组随机并且不重复的数,类似于简单的抽奖程序的实现. 先来生成一个有序的数组: 1 var arr = [], 2 ...
- javascript算法题判断输入年份是否是闰年
用户输入一个年份,判断这个年是否是闰年.判断闰年条件:① 非整百年数除以4,无余为闰,有余不闰:② 整百年数除以400,无余为闰,有余不闰.比如:2000年,整百数年,就要用②公式,除以400,无余数 ...
- JavaScript算法题(二) && 数组filter使用
1.Let's implement the reject() function... 例: var odds = reject([1, 2, 3, 4, 5, 6], function(num){ r ...
- JavaScript算法题(一) && 数组reduce使用
可参考Array.reduce用法 1. 请编写getMissingElement函数,返回给定数组中缺少的元素(数组里的元素为0~9,只会缺失一个). Example: getMissingElem ...
- FCC的javascript初级算法题解答
FCC上的javascript基础算法题 前一阵子做的基础算法题,感觉做完后收获还蛮大的,现在将自己的做法总结出来,供大家参考讨论.基本上做到尽量简短有效,但有些算法还可以继续简化,比如第七题若采用正 ...
- 简单的算法题, Find Minimum in Rotated Sorted Array 的Python实现。
简单的算法题, Find Minimum in Rotated Sorted Array 的Python实现. 题目: Suppose a sorted array is rotated at som ...
- [2]十道算法题【Java实现】
前言 清明不小心就拖了两天没更了-- 这是十道算法题的第二篇了-上一篇回顾:十道简单算法题 最近在回顾以前使用C写过的数据结构和算法的东西,发现自己的算法和数据结构是真的薄弱,现在用Java改写一下, ...
- LeetCode算法题-Number of Lines To Write String(Java实现)
这是悦乐书的第319次更新,第340篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第188题(顺位题号是806).我们要将给定字符串S的字母从左到右写成行.每行最大宽度为 ...
随机推荐
- Spring注解大全,汇总版
Spring使用的注解大全和解释 注解 解释 @Controller 组合注解(组合了@Component注解),应用在MVC层(控制层),DispatcherServlet会自动扫描注解了此注解的类 ...
- BiliBili, ACFun… And More!【递归算法】
题源:http://acm.uestc.edu.cn/#/problem/show/3 题解: 题意:播放一段视频文件,有播放速度和缓冲速度两种,因为作者的癖好,播放前要缓冲几秒钟(这段时间不计算在总 ...
- 防止过拟合:L1/L2正则化
正则化方法:防止过拟合,提高泛化能力 在训练数据不够多时,或者overtraining时,常常会导致overfitting(过拟合).其直观的表现如下图所示,随着训练过程的进行,模型复杂度增加,在tr ...
- Linux - iptables firewalld
目录 iptables firewalld iptables 1.iptables 的基本使用 启动: service start iptabls 关闭: service stopiptabls 查看 ...
- Service层异常处理
1.在service方法里面如果对异常进行了捕获的话,该事务是不会进行回滚的 * 默认spring事务只在发生未被捕获的 runtime excetpion()时才回滚. * * spring aop ...
- weiFenLuo.winFormsUI.Docking.dll学习
引用方法: 1.建立一个WinForm工程,默认生成了一个WinForm窗体. 2.引用—>添加引用—>浏览—>weiFenLuo.winFormsUI.Docking.dll. 3 ...
- 一张图说清楚SQL的Join
话不多说..看图
- [Xamarin.Android] 如何使用Google Map V2 (转帖)
Google Map v1已經在2013年的3月開始停止支援了,目前若要在你的Android手機上使用到Google Map,就必須要使用 到Google Map v2的版本.在Xamarin要使用G ...
- MongoDB与c#(二)简单例子 使用1.7版本驱动
//创建数据库链接 在1.7的版本驱动中这样写是会报 MongoServer方法已过时的 //MongoServer server = MongoDB.Driver.Mongo ...
- hibernate核心开发接口_Configuration
AnnotationConfiguration继承自Configuration,这里以AnnotationConfiguration为例: new AnnotationConfiguration(). ...