JS常见算法题目

最近收集了几个经典JS题目,比较有代表性,分享一下:

1.j-dra-gon 变为驼峰jDraGon

function getCamelCase(str) {    
  var arr = str.split( '-' );    
  return arr.map( 
    function( item, index ) {        
    console.log(item)        
    if( index === 0 ){           
      return item;       
    }else{            
      return item.charAt(0).toUpperCase() + item.slice( 1 );
    }   
  }).join('');
}
console.log(getCamelCase("j-dra-gon"))复制代码

正则写法:

function getCamelCase( str ){
  return str.replace( /-([a-z])/g , function( all, i){ 
    // 注意正则中的(),这里可以匹配到  -s 和s
    return i.toUpperCase();
  }
)}复制代码

如果这道题要求反向转化

function getCase(str) {
  var arr = str.split('');  
  // 每一个字符组成数组    
  str = arr.map(function ( item ){
    if( item.toUpperCase() === item ){
      return '-' + item.toLowerCase();        
    }else{
      return item; 
    }   
  }).join( '' );
  return str; 
}
console.log(getCamelCase("jDraGon"))复制代码

正则写法

function getCase(){
  return str.replace( /[A-Z]/g  , function(i) {      
    retrun '-' + i.toLowerCase(); 
  })
}复制代码

2.数组去重

ES6 set法:

var arry =[1,25,15,1,2,15,5,15,25,35,1]
var set =new Set(arry)
console.log([...set])复制代码

或者 简写为

[...new Set(arr)]复制代码

传统写法之一:

function qc(arr){
  var n = [];
  //一个新数组  
  for(var i = 0;i<array.length;i++){         
    //也可以写x in array   x是迭代序号      
    if(n.indexOf(array[i) === -1){  
      //检测到没有 则添加           
      n.push(array[i])       
    }
  }   
  return n;
}复制代码

3.统计字符串中出现最多的字母

循环一下字符串,第一次出现

/**
* 获取字符串中出现次数最多的字母
* @param {String} str
*/
function getChar(str) {    
  if (typeof str !== 'string') return  // 判断参数是否为字符串    
  const obj = new Object()  // 键为字母,值为次数    
  for (let i = 0; i < str.length; i ++) {  // 遍历字符串每一个字母        
    let char = str.charAt(i) // 当前字母        
    obj[char] = obj[char] || 0  // 保证初始值为0        
    obj[char] ++  // 次数加1   
  }    
  let maxChar // 存储字母    
  let maxNum = 0 // maxChar字母对应的次数    
  for(let key in obj) { // 遍历obj        
    if (obj[key] > maxNum) {            
      maxChar = key // 比较后存储次数多的字母       
      maxNum = obj[key] // 以及它对应的次数   
    }
  }  
  return maxChar // 返回结果
} 
let str = 'aabbbccdd'
console.log('出现次数最多的字母为:' + getChar(str))复制代码

4.字符串反序

首先将字符串序列化成数组,通过数组方法对数组反序,最后把数组转换成字符串。

'say I love U'.split('').reverse().join('')   //  U evol I yas复制代码

5.深拷贝

浅拷贝只需要Object.assign();

符合json要求(双引号)的对象深拷贝:

JSON.parse(JSON.stringify(obj)复制代码

不严格符合json的对象的深拷贝:

 function  deepCopy(src, r) {
   var r = r || {};
   for(var prop in src){
     // console.log(prop)        
     if(typeof src[prop] === 'object'){ 
       // 是对象  需要深拷贝           
       if (src[prop].constructor === Array){              
         // console.log("数组"); 
         r[prop]=[]; 
       }else{ 
        // console.log("对象");     
         r[prop]={};
       } 
       deepCopy(src[prop], r[prop]);
     }else{ 
       // 非对象,直接拷贝      
       r[prop] = src[prop];
     }    
  }  
  return r;
}复制代码

6.合并多个有序数组

不考虑去重:

var arr = [[1, 2], [0, 3, 5], [-1, 4]];

// 如果需要从小到大排序加上这个 
arr = arr.reduce((a, b) => a.concat(b), []).sort((a, b) => a - b);

console.log(arr);   //  输出 [-1, 0, 1, 2, 3, 4, 5]复制代码

考虑去重(数组转化为对象,利用对象键名唯一性,然后.keys一次性取键名)

var arr = [[1, 2], [0, 3, 5], [-1, 4]];var obj = {};

arr = arr
.forEach(item => item.forEach(function(num) {    
  obj[num] = true;    
}));

arr = Object
.keys(obj)
.map(num => +num)// 这行主要是将键名取出来之后,数组中全部是字符串,将其都转成数字,以便后面排序   
.sort((a, b) => a - b);

 console.log(arr);复制代码

7.数组排序

var arr = [1,25,3,85,4,0]

arr.sort((m,n)=>{
  if(m>n){ 
    return 1       //顺序改变  
  }else{    
    return -1        //顺序不改变  
  }
})

console.log(arr)  // [0, 1, 3, 4, 25, 85]复制代码

也可以简化为

var arr = [1,25,3,85,4,0]

arr.sort((m,n)=>{
  if(m>n){  
    return m-n   // m若大于n,m-n则是正数,反正是负数  和上面一样道理
  }
})

console.log(arr)  // [0, 1, 3, 4, 25, 85]复制代码

同理:
[{'name': '张三', age: 16},{'name': '李四', age: 45},{'name': '王五', age: 19},{'name': '赵六', age: 6}] 按年龄排序

var arr = [
  {'name': '张三', age: 16},
  {'name': '李四', age: 45},
  {'name': '王五', age: 19},
  {'name': '赵六', age: 6}
]
arr.sort((m,n)=>{
  if(m.age>n.age){
    return m.age-n.age
  }
})
console.log(arr)   
/* 
[{name: "赵六", age: 6},
{name: "张三", age: 16},
{name: "王五", age: 19},
{name: "李四", age: 45}]
*/复制代码

8.约瑟夫环问题

编号为1到100的一百个人围成一圈,以123123的方式进行报数,数到3的人自动退出圈子,剩下的人继续报数,问最后剩下的人编号为几?

递归解法:
参考:
根据这2篇文章可得到下面的思路:
设:n为总人数 报数出环数字为k(123123的3) i为第i次出环
当i=1时, f(n,k,i) = (n+k-1)%n
当i!=1时, f(n,k,i)= ( f(n-1,k,i-1)+k )%n
简单来说, 这一轮=(上一轮+k)%n
按照这个公式,递归就很好写了。


编号为1到100,报数逢3退出,注意解法中数组下标是从0开始的

// 总人数n  报数出环数字k   n=100 k=3 第i个人出环
    function josephus(n,k,i) {
        if(i==1){
            return (n+k-1)%n;
        }else{
            return (josephus(n-1, k,i-1) + k)%n;
        }
    }
   for(var i=1;i<=100;i++){
        console.log("第"+i+"次出环,下标为:"+josephus(100,3,i))
   }
   // 第100次:下标为90的人出环  他的编号是91 (别忘了加1)复制代码

另一种解法:
这种方式比较简单,把编号组装为一个数组,设置一个浮标k,123的循环。每到3时将指向的值移除即可。
编号为1到100,报数逢3退出

function josephus2 (n,k){
  var players = [];
  for(var i=1;i<=n;i++){   // 组成数组
     players.push(i);
  }
  var flag=0;
  while(players.length>1){
    var outNum = 0;  //本次循环已出局人数,便于定位元素位置
    var len = players.length;
    for(var i=0;i<len;i++){
       flag++;
       if(flag==k){
         flag=0;
         console.log("出局:"+players[i-outNum]+"本次循环已出局人数:"+outNum);
         // i循环时受数组长度影响 每从头开始时i变为0; 但flag始终是123..k  123..k 固定循环,不受数组影响  ,
         players.splice(i-outNum,1);
         outNum++;
       }
    }
 }
 return players[0];
}
console.log(josephus2(100,3));复制代码


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值