JavaScript 面试中常见算法问题详解,翻译自 https://github.com/kennymkchan/interview-questions-in-javascript。下文提到的很多问题从算法角度并不一定要么困难,不过用 JavaScript 内置的 API 来完成还是需要一番考量的。

 JavaScript Specification

  阐述下 JavaScript 中的变量提升

  所谓提升,顾名思义即是 JavaScript 会将所有的声明提升到当前作用域的顶部。这也就意味着我们可以在某个变量声明前就使用该变量,不过虽然 JavaScript 会将声明提升到顶部,但是并不会执行真的初始化过程。

  阐述下 use strict; 的作用

  use strict; 顾名思义也就是 JavaScript 会在所谓严格模式下执行,其一个主要的优势在于能够强制开发者避免使用未声明的变量。对于老版本的浏览器或者执行引擎则会自动忽略该指令。

// Example of strict mode
"use strict";catchThemAll();
function catchThemAll() {x = 3.14; // Error will be thrownreturn x * x;
}

  解释下什么是 Event Bubbling 以及如何避免

  Event Bubbling 即指某个事件不仅会触发当前元素,还会以嵌套顺序传递到父元素中。直观而言就是对于某个子元素的点击事件同样会被父元素的点击事件处理器捕获。避免 Event Bubbling 的方式可以使用event.stopPropagation() 或者 IE 9 以下使用event.cancelBubble。

  == 与 === 的区别是什么

  === 也就是所谓的严格比较,关键的区别在于=== 会同时比较类型与值,而不是仅比较值。

// Example of comparators
0 == false; // true
0 === false; // false2 == '2'; // true
2 === '2'; // false

  解释下 null 与 undefined 的区别

  JavaScript 中,null 是一个可以被分配的值,设置为 null 的变量意味着其无值。而 undefined 则代表着某个变量虽然声明了但是尚未进行过任何赋值。

  解释下 Prototypal Inheritance 与 Classical Inheritance 的区别

  在类继承中,类是不可变的,不同的语言中对于多继承的支持也不一样,有些语言中还支持接口、final、abstract 的概念。而原型继承则更为灵活,原型本身是可以可变的,并且对象可能继承自多个原型。

 数组

  找出整型数组中乘积最大的三个数

  给定一个包含整数的无序数组,要求找出乘积最大的三个数。

var unsorted_array = [-10, 7, 29, 30, 5, -10, -70];computeProduct(unsorted_array); // 21000function sortIntegers(a, b) {return a - b;
}// greatest product is either (min1 * min2 * max1 || max1 * max2 * max3)
function computeProduct(unsorted) {var sorted_array = unsorted.sort(sortIntegers),product1 = 1,product2 = 1,array_n_element = sorted_array.length - 1;// Get the product of three largest integers in sorted arrayfor (var x = array_n_element; x > array_n_element - 3; x--) {product1 = product1 * sorted_array[x];}product2 = sorted_array[0] * sorted_array[1] * sorted_array[array_n_element];if (product1 > product2) return product1;return product2
};

  寻找连续数组中的缺失数

  给定某无序数组,其包含了 n 个连续数字中的 n - 1 个,已知上下边界,要求以O(n)的复杂度找出缺失的数字。

// The output of the function should be 8
var array_of_integers = [2, 5, 1, 4, 9, 6, 3, 7];
var upper_bound = 9;
var lower_bound = 1;findMissingNumber(array_of_integers, upper_bound, lower_bound); //8function findMissingNumber(array_of_integers, upper_bound, lower_bound) {// Iterate through array to find the sum of the numbersvar sum_of_integers = 0;for (var i = 0; i < array_of_integers.length; i++) {sum_of_integers += array_of_integers[i];}// 以高斯求和公式计算理论上的数组和// Formula: [(N * (N + 1)) / 2] - [(M * (M - 1)) / 2];// N is the upper bound and M is the lower boundupper_limit_sum = (upper_bound * (upper_bound + 1)) / 2;lower_limit_sum = (lower_bound * (lower_bound - 1)) / 2;theoretical_sum = upper_limit_sum - lower_limit_sum;//return (theoretical_sum - sum_of_integers)
}

  数组去重

  给定某无序数组,要求去除数组中的重复数字并且返回新的无重复数组。

// ES6 Implementation
var array = [1, 2, 3, 5, 1, 5, 9, 1, 2, 8];
Array.from(new Set(array)); // [1, 2, 3, 5, 9, 8]// ES5 Implementation
var array = [1, 2, 3, 5, 1, 5, 9, 1, 2, 8];
uniqueArray(array); // [1, 2, 3, 5, 9, 8]
function uniqueArray(array) {var hashmap = {};var unique = [];for(var i = 0; i < array.length; i++) {// If key returns null (unique), it is evaluated as false.if(!hashmap.hasOwnProperty([array[i]])) {hashmap[array[i]] = 1;unique.push(array[i]);}}return unique;
}

  数组中元素最大差值计算

  给定某无序数组,求取任意两个元素之间的最大差值,注意,这里要求差值计算中较小的元素下标必须小于较大元素的下标。譬如[7, 8, 4, 9, 9, 15, 3, 1, 10]这个数组的计算值是 11( 15 - 4 ) 而不是 14(15 - 1),因为 15 的下标小于 1。

var array = [7, 8, 4, 9, 9, 15, 3, 1, 10];
// [7, 8, 4, 9, 9, 15, 3, 1, 10] would return `11` based on the difference between `4` and `15`
// Notice: It is not `14` from the difference between `15` and `1` because 15 comes before 1.findLargestDifference(array);
function findLargestDifference(array) {// 如果数组仅有一个元素,则直接返回 -1if (array.length <= 1) return -1;// current_min 指向当前的最小值var current_min = array[0];var current_max_difference = 0;// 遍历整个数组以求取当前最大差值,如果发现某个最大差值,则将新的值覆盖 current_max_difference// 同时也会追踪当前数组中的最小值,从而保证 `largest value in future` - `smallest value before it`for (var i = 1; i < array.length; i++) {if (array[i] > current_min && (array[i] - current_min > current_max_difference)) {current_max_difference = array[i] - current_min;} else if (array[i] <= current_min) {current_min = array[i];}}// If negative or 0, there is no largest differenceif (current_max_difference <= 0) return -1;return current_max_difference;
}

  数组中元素乘积

  给定某无序数组,要求返回新数组 output ,其中 output[i] 为原数组中除了下标为 i 的元素之外的元素乘积,要求以 O(n) 复杂度实现:

var firstArray = [2, 2, 4, 1];
var secondArray = [0, 0, 0, 2];
var thirdArray = [-2, -2, -3, 2];productExceptSelf(firstArray); // [8, 8, 4, 16]
productExceptSelf(secondArray); // [0, 0, 0, 0]
productExceptSelf(thirdArray); // [12, 12, 8, -12]function productExceptSelf(numArray) {var product = 1;var size = numArray.length;var output = [];// From first array: [1, 2, 4, 16]// The last number in this case is already in the right spot (allows for us)// to just multiply by 1 in the next step.// This step essentially gets the product to the left of the index at index + 1for (var x = 0; x < size; x++) {output.push(product);product = product * numArray[x];}// From the back, we multiply the current output element (which represents the product// on the left of the index, and multiplies it by the product on the right of the element)var product = 1;for (var i = size - 1; i > -1; i--) {output[i] = output[i] * product;product = product * numArray[i];}return output;
}

  数组交集

  给定两个数组,要求求出两个数组的交集,注意,交集中的元素应该是唯一的。

var firstArray = [2, 2, 4, 1];
var secondArray = [1, 2, 0, 2];intersection(firstArray, secondArray); // [2, 1]function intersection(firstArray, secondArray) {// The logic here is to create a hashmap with the elements of the firstArray as the keys.// After that, you can use the hashmap's O(1) look up time to check if the element exists in the hash// If it does exist, add that element to the new array.var hashmap = {};var intersectionArray = [];firstArray.forEach(function(element) {hashmap[element] = 1;});// Since we only want to push unique elements in our case... we can implement a counter to keep track of what we already addedsecondArray.forEach(function(element) {if (hashmap[element] === 1) {intersectionArray.push(element);hashmap[element]++;}});return intersectionArray;// Time complexity O(n), Space complexity O(n)
}

 字符串

  颠倒字符串

  给定某个字符串,要求将其中单词倒转之后然后输出,譬如"Welcome to this Javascript Guide!" 应该输出为 "emocleW ot siht tpircsavaJ !ediuG"。

var string = "Welcome to this Javascript Guide!";// Output becomes !ediuG tpircsavaJ siht ot emocleW
var reverseEntireSentence = reverseBySeparator(string, "");// Output becomes emocleW ot siht tpircsavaJ !ediuG
var reverseEachWord = reverseBySeparator(reverseEntireSentence, " ");function reverseBySeparator(string, separator) {return string.split(separator).reverse().join(separator);
}

  乱序同字母字符串

  给定两个字符串,判断是否颠倒字母而成的字符串,譬如Mary与Army就是同字母而顺序颠倒:

var firstWord = "Mary";
var secondWord = "Army";isAnagram(firstWord, secondWord); // truefunction isAnagram(first, second) {// For case insensitivity, change both words to lowercase.var a = first.toLowerCase();var b = second.toLowerCase();// Sort the strings, and join the resulting array to a string. Compare the resultsa = a.split("").sort().join("");b = b.split("").sort().join("");return a === b;
}

  会问字符串

  判断某个字符串是否为回文字符串,譬如racecar与race car都是回文字符串:

isPalindrome("racecar"); // true
isPalindrome("race Car"); // truefunction isPalindrome(word) {// Replace all non-letter chars with "" and change to lowercasevar lettersOnly = word.toLowerCase().replace(/\s/g, "");// Compare the string with the reversed version of the stringreturn lettersOnly === lettersOnly.split("").reverse().join("");
}

 栈与队列

  使用两个栈实现入队与出队

var inputStack = []; // First stack
var outputStack = []; // Second stack// For enqueue, just push the item into the first stack
function enqueue(stackInput, item) {return stackInput.push(item);
}function dequeue(stackInput, stackOutput) {// Reverse the stack such that the first element of the output stack is the// last element of the input stack. After that, pop the top of the output to// get the first element that was ever pushed into the input stackif (stackOutput.length <= 0) {while(stackInput.length > 0) {var elementToOutput = stackInput.pop();stackOutput.push(elementToOutput);}}return stackOutput.pop();
}

  判断大括号是否闭合

  创建一个函数来判断给定的表达式中的大括号是否闭合:

var expression = "{{}}{}{}"
var expressionFalse = "{}{{}";isBalanced(expression); // true
isBalanced(expressionFalse); // false
isBalanced(""); // truefunction isBalanced(expression) {var checkString = expression;var stack = [];// If empty, parentheses are technically balancedif (checkString.length <= 0) return true;for (var i = 0; i < checkString.length; i++) {if(checkString[i] === '{') {stack.push(checkString[i]);} else if (checkString[i] === '}') {// Pop on an empty array is undefinedif (stack.length > 0) {stack.pop();} else {return false;}}}// If the array is not empty, it is not balancedif (stack.pop()) return false;return true;
}

 递归

  二进制转换

  通过某个递归函数将输入的数字转化为二进制字符串:

decimalToBinary(3); // 11
decimalToBinary(8); // 1000
decimalToBinary(1000); // 1111101000function decimalToBinary(digit) {if(digit >= 1) {// If digit is not divisible by 2 then recursively return proceeding// binary of the digit minus 1, 1 is added for the leftover 1 digitif (digit % 2) {return decimalToBinary((digit - 1) / 2) + 1;} else {// Recursively return proceeding binary digitsreturn decimalToBinary(digit / 2) + 0;}} else {// Exit conditionreturn '';}
}

  二分搜索

function recursiveBinarySearch(array, value, leftPosition, rightPosition) {// Value DNEif (leftPosition > rightPosition) return -1;var middlePivot = Math.floor((leftPosition + rightPosition) / 2);if (array[middlePivot] === value) {return middlePivot;} else if (array[middlePivot] > value) {return recursiveBinarySearch(array, value, leftPosition, middlePivot - 1);} else {return recursiveBinarySearch(array, value, middlePivot + 1, rightPosition);}
}

 数字

  判断是否为 2 的指数值

isPowerOfTwo(4); // true
isPowerOfTwo(64); // true
isPowerOfTwo(1); // true
isPowerOfTwo(0); // false
isPowerOfTwo(-1); // false// For the non-zero case:
function isPowerOfTwo(number) {// `&` uses the bitwise n.// In the case of number = 4; the expression would be identical to:// `return (4 & 3 === 0)`// In bitwise, 4 is 100, and 3 is 011. Using &, if two values at the same// spot is 1, then result is 1, else 0. In this case, it would return 000,// and thus, 4 satisfies are expression.// In turn, if the expression is `return (5 & 4 === 0)`, it would be false// since it returns 101 & 100 = 100 (NOT === 0)return number & (number - 1) === 0;
}// For zero-case:
function isPowerOfTwoZeroCase(number) {return (number !== 0) && ((number & (number - 1)) === 0);
}

转载于:https://www.cnblogs.com/woodyliang/p/6438222.html

JavaScript 面试中常见算法问题详解相关推荐

  1. PHP开发中常见的安全问题详解和解决方法

    PHP开发中常见的安全问题详解和解决方法 参考文章: (1)PHP开发中常见的安全问题详解和解决方法 (2)https://www.cnblogs.com/walblog/articles/83313 ...

  2. JavaScript数组结构与算法——数组详解(中)

    迭代器方法 在上篇中,我们探讨了很多数组方法,接下来总结一下最后一组方法--迭代器方法.这些方法对数组的每个元素应用一个函数,可以返回一个值.一组值.或者一个新数组. 1.不生成新数组的迭代器方法 以 ...

  3. web中常见乱码问题详解

    基本讲解: 1.UTF-8国际编码,GBK中文编码.GBK包含GB2312,即如果通过GB2312编码后可以通过GBK解码,反之可能不成立; 2.web tomcat:默认是ISO8859-1,不支持 ...

  4. C语言中常见字符串API详解

    以下均为笔记,草率见谅,首先介绍下在字符串章节所用的函数,再介绍几个常见的api malloc 函数原型:void *malloc(size_t size) C库函数void *malloc(size ...

  5. JavaScript 数组中的 indexOf 方法详解

    最近项目遇到一个小问题代码我会简化成小例子展示给大家. 用心看到最后会有收获哈,基础扎实的童鞋可以直接跳到数组类型使用. 说到 indexOf 大家并不陌生,判断字符串是否包涵子字符串时特别常用(正则 ...

  6. JavaScript数据结构与算法——链表详解(下)

    在JavaScript数据结构与算法--链表详解(上)中,我们探讨了一下链表的定义.实现原理以及单链表的实现.接下来我们进一步了解一下链表的其他内容. 1.双向链表 双向链表实现原理图: 与单向链表不 ...

  7. JavaScript数据结构与算法——链表详解(上)

    注:与之前JavaScript数据结构与算法系列博客不同的是,从这篇开始,此系列博客采用es6语法编写,这样在学数据结构的同时还能对ECMAScript6有进一步的认识,如需先了解es6语法请浏览ht ...

  8. JavaScript数据结构与算法——队列详解(下)

    接下来会借助本人另一篇文章JavaScript数据结构与算法--队列详解(上)中实现的队列类及其方法实现一个应用. 配对问题 需求分析:在一个文件中保存着一份男女混合的数据,名称前以B开头表示男士,以 ...

  9. JavaScript数据结构与算法——列表详解(下),基于Nodejs实现一个列表应用

    1.上篇回顾: 上篇我们实现了一个列表类,并添加了一些属性,实现了比较多的方法,本文章将与大家一起使用列表实现一个图书借阅查询系统.需要使用JavaScript数据结构与算法--列表详解(上)中写好的 ...

最新文章

  1. iphone降级 无需电脑_App 降级无需电脑,手机直接搞
  2. 关于 react的生命周期
  3. 全息过山车:巨蚁数字全息刺激体验
  4. 推进牛仔服装的高质量发展
  5. 基于Jsp+Servlet的在线考试系统
  6. php网站xiazai工具,php程序员工具箱下载_php程序员工具箱v1.0版本-php中文网工具下载...
  7. python已停止工作请关闭该程序_解决PyCharm的Python.exe已经停止工作的问题
  8. 无线网络技术:GPS(美国全球定位系统)的发展史
  9. win8专业版和win8.1专业版安装密钥key及其永久激活工具
  10. 【论文阅读】DeepIM: Deep Iterative Matching for 6D Pose Estimation
  11. 教你如何复制别人的QQ空间为自己用
  12. 分享在Linux下编译Android源代码并修改调试系统自带应用的方法
  13. 曾扬言 机器人合法公民_简直荒谬!这个机器人被授予合法公民身份,并公开嘲笑马斯克!...
  14. halocn标定找旋转中心_对摄像头进行标定
  15. 一个产品经理的自我认识
  16. Ubuntu上安装mujoco
  17. html点击弹出登录注册表单提交代码
  18. C++ 图片完整性校验
  19. Springboot事件监听机制:工作原理
  20. 上海2月住宅供应剧减七成 房企捂盘保价

热门文章

  1. PayPal宣布退出虚拟货币组织Libra协会
  2. 系统学习机器学习之决策树
  3. java可比较的和比较器的区别_Java中Compareable和Comparator两种比较器的区别
  4. 虚拟服务器设置upnp,TP-Link路由器如何设置UPNP开启【设置步骤】
  5. 最长回文子串动态规划_九章算法 | 微软面试题:最长回文子串
  6. python编程语言继承_python应用:学习笔记(Python继承)
  7. python给函数设置超时时间_在 Linux/Mac 下为Python函数添加超时时间的方法
  8. 云服务器 架设传奇_传奇手游-战神引擎架设教程
  9. python3模块socket怎么安装_Python中socket模块的使用方法(一)
  10. 云南初中生计算机相关赛事,第14届中国大学生计算机设计大赛云南赛区决赛举行...