原文链接:Jack Pu's Blog

虽说我们很多时候前端很少有机会接触到算法。实际上学习数据结构与算法对于工程师去理解和分析问题都是有帮助的。如果将来当我们面对较为复杂的问题,这些基础知识的积累可以帮助我们更好的优化解决思路。

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):

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

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 绘制一个有限度的斐波那契数列的曲线?

数列长度限定在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)是指一棵空树或者具有下列性质的二叉树:

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

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

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;

完整代码 Github

JS常见的算法的更多相关文章

  1. JS常见排序算法

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  2. js 常见数组算法

    数组方法概述 1.不改变原数组,返回新数组 concat() 连接两个或多个数组,两边的原始数组都不会变化,返回被连接数组的一个副本. join() 把数组中所有元素放入一个字符串中,返回字符串. s ...

  3. 常见排序算法(JS版)

    常见排序算法(JS版)包括: 内置排序,冒泡排序,选择排序,插入排序,希尔排序,快速排序(递归 & 堆栈),归并排序,堆排序,以及分析每种排序算法的执行时间. index.html <! ...

  4. 常见排序算法原理及JS代码实现

    目录 数组 sort() 方法 冒泡排序 选择排序 插入排序 希尔排序 归并排序 堆排序 快速排序 创建时间:2020-08-07 本文只是将作者学习的过程以及算法理解进行简单的分享,提供多一个角度的 ...

  5. JavaScript版几种常见排序算法

    今天发现一篇文章讲“JavaScript版几种常见排序算法”,看着不错,推荐一下原文:http://www.w3cfuns.com/blog-5456021-5404137.html 算法描述: * ...

  6. JS数据结构与算法——栈

    JS数据结构与算法--栈 1.栈结构概念 栈(Stack)是一种先进后出(LIFO Last in First out)的线性表,先进栈的将会比后进栈的先出栈. 栈的限制是仅允许在一端进行插入和删除运 ...

  7. js 实现各种算法 APP

    js 实现各种算法 APP 常见算法: 排序,搜索/查找,枚举,遍历,最短路径,二叉树 open source web app desktop app react native app flutter ...

  8. JS数据结构与算法-概述

    JS数据结构与算法概述 数据结构: 计算机存储, 组织数据的方式, 就像锅碗瓢盆 算法: 一系列解决问题的清晰指令, 就像食谱 两者关系: 程序 = 数据结构 + 算法 邂逅数据结构与算法 什么是数据 ...

  9. 常见排序算法(附java代码)

    常见排序算法与java实现 一.选择排序(SelectSort) 基本原理:对于给定的一组记录,经过第一轮比较后得到最小的记录,然后将该记录与第一个记录的位置进行交换:接着对不包括第一个记录以外的其他 ...

随机推荐

  1. 将System.Drawing.Bitmap转换为Direct2D.D2DBitmap

    最近在尝试Direct2D编程,挺好玩的. 但是有时候还是会用到GDI+来生成图片,但D2D绘图需要用到自己的D2DBitmap类. 因此需要转换,查阅了下网上的资料,写了这么一个方法: using ...

  2. 基础数据类型-set

    Set是无序不重复元素的序列,基本功能是删除重复元素和测试成员关系, 创建一个集合可以用set()或者({}),但是创建一个空集合只能用set(): s1 = set() print("s1 ...

  3. canvas学习(二):渐变与曲线的绘制

    canvas学习(二):渐变与曲线的绘制 一:createLinearGradient()线性渐变: 二:createLinearGradient() 放射状/圆形渐变: 三:createPatter ...

  4. “Hello World!”团队召开的第十二次会议

    今天是我们团队“Hello World!”团队召开的第十二次会议.博客内容: 一.会议时间 二.会议地点 三.会议成员 四.会议内容 五.todo list 六.会议照片 七.燃尽图 一.会议时间 2 ...

  5. M2迭代分数分配

    M2中仍然依据每个成员的工作量,贡献度分配相应得分. 成员 得分 申开亮 25 王皓南 24 许晋 21 黄玉冰 20 王宇杰 18 吴润凡 17 巴丹益昔 15

  6. aria2 on ubuntu

    http://www.5yun.org/9102.html http://jpollo.logdown.com/posts/160847-aria2c-and-yaaw aria2c --enable ...

  7. 第二部分shell编程2正则(grepegrepsedawk)

    一.grep/egrep 1. 语法+选项语法: grep [-cinvABC] 'word' filename -c :打印符合要求的行数-n :在输出符合要求的行的同时连同行号一起输出 -v :打 ...

  8. 重载和const参数

    const仅能用于在定义函数签名时,区分是为引用定义参数,还是为指针定义参数.定义基本类型type(如int等),从重载的观点来看,const int和int是相同的. const long& ...

  9. [计算机网络] TCP的拥塞控制

    引言 计算机网络中的带宽.交换结点中的缓存和处理机等,都是网络的资源.在某段时间,若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络的性能就会变坏.这种情况就叫做拥塞. 拥塞控制就是防止过多 ...

  10. 当要将其他类型转成String类型时候 看String的方法

    当要将其他类型转成String类型时候 看String的方法进行转换