前端JS面试中常见的算法问题总结


Posted in Javascript onDecember 23, 2016

前言

学习数据结构与算法对于工程师去理解和分析问题都是有帮助的。如果将来当我们面对较为复杂的问题,这些基础知识的积累可以帮助我们更好的优化解决思路。下面罗列在前端面试中经常撞见的几个问题吧。

Q1 判断一个单词是否是回文?

回文是指把相同的词汇或句子,在下文中调换位置或颠倒过来,产生首尾回环的情趣,叫做回文,也叫回环。比如 mamam redivider .

很多人拿到这样的题目非常容易想到用for 将字符串颠倒字母顺序然后匹配就行了。其实重要的考察的就是对于reverse的实现。其实我们可以利用现成的函数,将字符串转换成数组,这个思路很重要,我们可以拥有更多的自由度去进行字符串的一些操作。

function checkPalindrom(str) { 
  return str == str.split('').reverse().join('');
}

Q2 去掉一组整型数组重复的值

比如输入: [1,13,24,11,11,14,1,2]

输出: [1,13,24,11,14,2]

需要去掉重复的11 和 1 这两个元素。

这道问题出现在诸多的前端面试题中,主要考察个人对Object的使用,利用key来进行筛选。

/**
* unique an array 
**/
let unique = function(arr) { 
 let hashTable = {};
 let data = [];
 for(let i=0,l=arr.length;i<l;i++) {
  if(!hashTable[arr[i]]) {
   hashTable[arr[i]] = true;
   data.push(arr[i]);
  }
 }
 return data

}

module.exports = unique;

Q3 统计一个字符串出现最多的字母

给出一段英文连续的英文字符窜,找出重复出现次数最多的字母

输入 : afjghdfraaaasdenas

输出 : a

前面出现过去重的算法,这里需要是统计重复次数。

function findMaxDuplicateChar(str) { 
 if(str.length == 1) {
  return str;
 }
 let charObj = {};
 for(let i=0;i<str.length;i++) {
  if(!charObj[str.charAt(i)]) {
   charObj[str.charAt(i)] = 1;
  }else{
   charObj[str.charAt(i)] += 1;
  }
 }
 let maxChar = '',
   maxValue = 1;
 for(var k in charObj) {
  if(charObj[k] >= maxValue) {
   maxChar = k;
   maxValue = charObj[k];
  }
 }
 return maxChar;

}

module.exports = findMaxDuplicateChar;

Q4 排序算法

如果抽到算法题目的话,应该大多都是比较开放的题目,不限定算法的实现,但是一定要求掌握其中的几种,所以冒泡排序,这种较为基础并且便于理解记忆的算法一定需要熟记于心。冒泡排序算法就是依次比较大小,小的的大的进行位置上的交换。

function bubbleSort(arr) { 
  for(let i = 0,l=arr.length;i<l-1;i++) {
    for(let j = i+1;j<l;j++) { 
     if(arr[i]>arr[j]) {
        let tem = arr[i];
        arr[i] = arr[j];
        arr[j] = tem;
      }
    }
  }
  return arr;
}
module.exports = bubbleSort;

除了冒泡排序外,其实还有很多诸如 插入排序,快速排序,希尔排序等。每一种排序算法都有各自的特点。全部掌握也不需要,但是心底一定要熟悉几种算法。 比如快速排序,其效率很高,而其基本原理如图(来自wiki):

前端JS面试中常见的算法问题总结

算法参考某个元素值,将小于它的值,放到左数组中,大于它的值的元素就放到右数组中,然后递归进行上一次左右数组的操作,返回合并的数组就是已经排好顺序的数组了。

function quickSort(arr) {

  if(arr.length<=1) {
    return arr;
  }

  let leftArr = [];
  let rightArr = [];
  let q = arr[0];
  for(let i = 1,l=arr.length; i<l; i++) {
    if(arr[i]>q) {
      rightArr.push(arr[i]);
    }else{
      leftArr.push(arr[i]);
    }
  }

  return [].concat(quickSort(leftArr),[q],quickSort(rightArr));
}

module.exports = quickSort;

安利大家一个学习的地址,通过动画演示算法的实现。

HTML5 Canvas Demo: Sorting Algorithms

Q5 不借助临时变量,进行两个整数的交换

输入 a = 2, b = 4 输出 a = 4, b =2

这种问题非常巧妙,需要大家跳出惯有的思维,利用 a , b进行置换。

主要是利用 + - 去进行运算,类似 a = a + ( b - a) 实际上等同于最后 的 a = b;

function swap(a , b) { 
 b = b - a;
 a = a + b;
 b = a - b;
 return [a,b];
}

module.exports = swap;

Q6 使用canvas 绘制一个有限度的斐波那契数列的曲线?

前端JS面试中常见的算法问题总结 

数列长度限定在9.

斐波那契数列,又称黄金分割数列,指的是这样一个数列:0、1、1、2、3、5、8、13、21、34、……在数学上,斐波纳契数列主要考察递归的调用。我们一般都知道定义

fibo[i] = fibo[i-1]+fibo[i-2];

生成斐波那契数组的方法

function getFibonacci(n) { 
 var fibarr = [];
 var i = 0;
 while(i<n) {
  if(i<=1) {
   fibarr.push(i);
  }else{
   fibarr.push(fibarr[i-1] + fibarr[i-2])
  }
  i++;
 }

 return fibarr;
}

剩余的工作就是利用canvas arc方法进行曲线绘制了

DEMO

Q7 找出下列正数组的最大差值比如:

输入 [10,5,11,7,8,9]

输出 6

这是通过一道题目去测试对于基本的数组的最大值的查找,很明显我们知道,最大差值肯定是一个数组中最大值与最小值的差。

function getMaxProfit(arr) {

  var minPrice = arr[0];
  var maxProfit = 0;

  for (var i = 0; i < arr.length; i++) {
    var currentPrice = arr[i];

    minPrice = Math.min(minPrice, currentPrice);

    var potentialProfit = currentPrice - minPrice;

    maxProfit = Math.max(maxProfit, potentialProfit);
  }

  return maxProfit;
}

Q8 随机生成指定长度的字符串

实现一个算法,随机生成指制定长度的字符窜。

比如给定 长度 8  输出 4ldkfg9j

function randomString(n) { 
 let str = 'abcdefghijklmnopqrstuvwxyz9876543210';
 let tmp = '',
   i = 0,
   l = str.length;
 for (i = 0; i < n; i++) {
  tmp += str.charAt(Math.floor(Math.random() * l));
 }
 return tmp;
}

module.exports = randomString;

Q9 实现类似getElementsByClassName 的功能

自己实现一个函数,查找某个DOM节点下面的包含某个class的所有DOM节点?不允许使用原生提供的 getElementsByClassName querySelectorAll 等原生提供DOM查找函数。

function queryClassName(node, name) { 
 var starts = '(^|[ \n\r\t\f])',
    ends = '([ \n\r\t\f]|$)';
 var array = [],
    regex = new RegExp(starts + name + ends),
    elements = node.getElementsByTagName("*"),
    length = elements.length,
    i = 0,
    element;

  while (i < length) {
    element = elements[i];
    if (regex.test(element.className)) {
      array.push(element);
    }

    i += 1;
  }

  return array;
}

Q10 使用JS 实现二叉查找树(Binary Search Tree)

一般叫全部写完的概率比较少,但是重点考察你对它的理解和一些基本特点的实现。 二叉查找树,也称二叉搜索树、有序二叉树(英语:ordered binary tree)是指一棵空树或者具有下列性质的二叉树:

  1. 任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
  2. 任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
  3. 任意节点的左、右子树也分别为二叉查找树;
  4. 没有键值相等的节点。二叉查找树相比于其他数据结构的优势在于查找、插入的时间复杂度较低。为O(log n)。二叉查找树是基础性数据结构,用于构建更为抽象的数据结构,如集合、multiset、关联数组等。

前端JS面试中常见的算法问题总结

在写的时候需要足够理解二叉搜素树的特点,需要先设定好每个节点的数据结构

class Node { 
 constructor(data, left, right) {
  this.data = data;
  this.left = left;
  this.right = right;
 }

}

树是有节点构成,由根节点逐渐延生到各个子节点,因此它具备基本的结构就是具备一个根节点,具备添加,查找和删除节点的方法.

class BinarySearchTree {

 constructor() {
  this.root = null;
 }

 insert(data) {
  let n = new Node(data, null, null);
  if (!this.root) {
   return this.root = n;
  }
  let currentNode = this.root;
  let parent = null;
  while (1) {
   parent = currentNode;
   if (data < currentNode.data) {
    currentNode = currentNode.left;
    if (currentNode === null) {
     parent.left = n;
     break;
    }
   } else {
    currentNode = currentNode.right;
    if (currentNode === null) {
     parent.right = n;
     break;
    }
   }
  }
 }

 remove(data) {
  this.root = this.removeNode(this.root, data)
 }

 removeNode(node, data) {
  if (node == null) {
   return null;
  }

  if (data == node.data) {
   // no children node
   if (node.left == null && node.right == null) {
    return null;
   }
   if (node.left == null) {
    return node.right;
   }
   if (node.right == null) {
    return node.left;
   }

   let getSmallest = function(node) {
    if(node.left === null && node.right == null) {
     return node;
    }
    if(node.left != null) {
     return node.left;
    }
    if(node.right !== null) {
     return getSmallest(node.right);
    }

   }
   let temNode = getSmallest(node.right);
   node.data = temNode.data;
   node.right = this.removeNode(temNode.right,temNode.data);
   return node;

  } else if (data < node.data) {
   node.left = this.removeNode(node.left,data);
   return node;
  } else {
   node.right = this.removeNode(node.right,data);
   return node;
  }
 }

 find(data) {
  var current = this.root;
  while (current != null) {
   if (data == current.data) {
    break;
   }
   if (data < current.data) {
    current = current.left;
   } else {
    current = current.right
   }
  }
  return current.data;
 }

}

module.exports = BinarySearchTree;

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。

Javascript 相关文章推荐
JavaScript 继承机制的实现(待续)
May 18 Javascript
jQuery实现鼠标经过图片预览大图效果
Apr 10 Javascript
node.js中的fs.lchmod方法使用说明
Dec 16 Javascript
Node.js程序中的本地文件操作用法小结
Mar 06 Javascript
JS日程管理插件FullCalendar中文说明文档
Feb 06 Javascript
vue 实现复制内容到粘贴板clipboard的方法
Mar 17 Javascript
Bootstrap Table中的多选框删除功能
Jul 15 Javascript
vue异步axios获取的数据渲染到页面的方法
Aug 09 Javascript
微信小程序实现消息框弹出动画
Apr 18 Javascript
vue递归组件实战之简单树形控件实例代码
Aug 27 Javascript
Vue中jsx不完全应用指南小结
Nov 01 Javascript
微信小程序实现签字功能
Dec 23 Javascript
Bootstrap源码解读导航条(7)
Dec 23 #Javascript
livereload工具实现前端可视化开发【推荐】
Dec 23 #Javascript
浅谈jQuery操作类数组的工具方法
Dec 23 #Javascript
jquery pagination插件动态分页实例(Bootstrap分页)
Dec 23 #Javascript
详解jQuery中的DOM操作
Dec 23 #Javascript
Bootstrap table两种分页示例
Dec 23 #Javascript
理解AngularJs篇:30分钟快速掌握AngularJs
Dec 23 #Javascript
You might like
简单分析ucenter 会员同步登录通信原理
2014/08/25 PHP
php删除数组指定元素实现代码
2017/05/03 PHP
ThinkPHP框架实现导出excel数据的方法示例【基于PHPExcel】
2018/05/12 PHP
常用js脚本
2006/12/03 Javascript
用jscript启动sqlserver
2007/06/21 Javascript
js操作ajax返回的json的注意问题!
2010/02/23 Javascript
23个Javascript弹出窗口特效整理
2011/02/25 Javascript
妙用Jquery的val()方法
2012/06/27 Javascript
require.js深入了解 require.js特性介绍
2014/09/04 Javascript
在Mac OS下使用Node.js的简单教程
2015/06/24 Javascript
js简单实现Select互换数据的方法
2015/08/17 Javascript
怎么引入(调用)一个JS文件
2016/05/26 Javascript
AngularJS 基础ng-class-even指令用法
2016/08/01 Javascript
遍历js中对象的属性和值的实例
2016/11/21 Javascript
TypeScript入门-接口
2017/03/30 Javascript
webpack学习--webpack经典7分钟入门教程
2017/06/28 Javascript
vue-cli3中配置alias和打包加hash值操作
2020/09/04 Javascript
jquery实现穿梭框功能
2021/01/19 jQuery
Python3基础之基本运算符概述
2014/08/13 Python
Python多进程并发(multiprocessing)用法实例详解
2015/06/02 Python
基于Python对象引用、可变性和垃圾回收详解
2017/08/21 Python
Numpy 将二维图像矩阵转换为一维向量的方法
2018/06/05 Python
django orm 通过related_name反向查询的方法
2018/12/15 Python
Python OS模块实例详解
2019/04/15 Python
利用python实现周期财务统计可视化
2019/08/25 Python
Pycharm中如何关掉python console
2020/10/27 Python
用python写PDF转换器的实现
2020/10/29 Python
澳大利亚在线家具、灯饰和家居装饰店:LivingStyles
2018/11/20 全球购物
体育专业求职信
2014/07/16 职场文书
处级干部反四风个人对照检查材料思想汇报
2014/09/27 职场文书
党的群众路线教育实践活动个人批评与自我批评
2014/10/16 职场文书
中学推普周活动总结
2015/05/07 职场文书
小平您好观后感
2015/06/09 职场文书
JVM入门之类加载与字节码技术(类加载与类的加载器)
2021/06/15 Java/Android
nodejs利用readline提示输入内容实例代码
2021/07/15 NodeJs
正则表达式基础与常用验证表达式
2022/06/16 Javascript