# JS算法题之leetcode(11~20)

## 盛最多水的容器

### 示例

``````输入: [1,8,6,2,5,4,8,3,7]

``````

### 解答

``````var maxFunc = (a, b) => {
return a >= b ? a : b;
}

var minFunc = (a, b) => {
return a <= b ? a : b;
}

var maxArea = function(height) {
let max = 0;

for(let i = 0; i < height.length - 1; i++){
for(let j = i + 1; j < height.length ; j++){
let temp = (j - i) * minFunc(height[i], height[j]);
max = maxFunc(max, temp);
}
}

return max;
};
``````

## 整数转罗马数字

### 题目描述

``````字符          数值
I             1
V             5
X             10
L             50
C             100
D             500
M             1000
``````

``````I 可以放在 V (5) 和 X (10) 的左边，来表示 4 和 9。
X 可以放在 L (50) 和 C (100) 的左边，来表示 40 和 90。
C 可以放在 D (500) 和 M (1000) 的左边，来表示 400 和 900。
``````

### 示例

``````输入: 3

``````
``````输入: 4

``````
``````输入: 9

``````
``````输入: 58

``````
``````输入: 1994

``````

### 解答

``````var intToRoman = function(num) {
let divisor = 0, remainder = 0, str = '';
// M,1000
divisor = Math.floor(num / 1000);
remainder = num % 1000;
while(divisor){
str += 'M';
divisor--;
}
if(remainder >= 900){
str += 'CM';
remainder -= 900;
}
// D,500
divisor = Math.floor(remainder / 500);
remainder = remainder % 500;
while(divisor){
str += 'D';
divisor--;
}
if(remainder >= 400){
str += 'CD';
remainder -= 400;
}
// C,100
divisor = Math.floor(remainder / 100);
remainder = remainder % 100;
while(divisor){
str += 'C';
divisor--;
}
if(remainder >= 90){
str += 'XC';
remainder -= 90;
}
// L,50
divisor = Math.floor(remainder / 50);
remainder = remainder % 50;
while(divisor){
str += 'L';
divisor--;
}
if(remainder >= 40){
str += 'XL';
remainder -= 40;
}
// X,10
divisor = Math.floor(remainder / 10);
remainder = remainder % 10;
while(divisor){
str += 'X';
divisor--;
}
if(remainder >= 9){
str += 'IX';
remainder -= 9;
}
// V,5
divisor = Math.floor(remainder / 5);
remainder = remainder % 5;
while(divisor){
str += 'V';
divisor--;
}
if(remainder >= 4){
str += 'IV';
remainder -= 4;
}
// I,1
divisor = remainder;
while(divisor){
str += 'I';
divisor--;
}

return str;
};
``````

## 罗马数字转整数

### 题目描述

``````字符          数值
I             1
V             5
X             10
L             50
C             100
D             500
M             1000
``````

``````I 可以放在 V (5) 和 X (10) 的左边，来表示 4 和 9。
X 可以放在 L (50) 和 C (100) 的左边，来表示 40 和 90。
C 可以放在 D (500) 和 M (1000) 的左边，来表示 400 和 900。
``````

### 示例

``````输入: "III"

``````
``````输入: "IV"

``````
``````输入: "IX"

``````
``````输入: "LVIII"

``````
``````输入: "MCMXCIV"

``````

### 解答

``````var romanToInt = function(s) {
if(s.length == 0){
return 0;
}
else if(s.lenght == 1){
switch(s){
case "I":
return 1;
case "V":
return 5;
case "X":
return 10;
case "L":
return 50;
case "C":
return 100;
case "D":
return 500;
case "M":
return 1000;
}
}
else{
let str = s.substring(0, 2);
if(str == "IV" || str == "IX" || str == "XL" || str == "XC" || str == "CD" || str == "CM"){
switch(str){
case "IV":
return 4 + romanToInt(s.slice(2));
case "IX":
return 9 + romanToInt(s.slice(2));
case "XL":
return 40 + romanToInt(s.slice(2));
case "XC":
return 90 + romanToInt(s.slice(2));
case "CD":
return 400 + romanToInt(s.slice(2));
case "CM":
return 900 + romanToInt(s.slice(2));
}
}
else{
switch(s[0]){
case "I":
return 1 + romanToInt(s.slice(1));
case "V":
return 5 + romanToInt(s.slice(1));
case "X":
return 10 + romanToInt(s.slice(1));
case "L":
return 50 + romanToInt(s.slice(1));
case "C":
return 100 + romanToInt(s.slice(1));
case "D":
return 500 + romanToInt(s.slice(1));
case "M":
return 1000 + romanToInt(s.slice(1));
}
}
}
};
``````

## 最长公共前缀

### 示例

``````输入: ["flower","flow","flight"]

``````
``````输入: ["dog","racecar","car"]

``````

### 解答

``````var longestCommonPrefix = function(strs) {
if(strs.length == 0){
return "";
}
if(strs.length == 1){
return strs[0];
}

let minLen = -1, prefix = '', char = '';
strs.forEach(ele => {
if(minLen == -1){
minLen = ele.length;
}
else{
minLen = ele.length < minLen ? ele.length : minLen;
}
});
if(minLen == 0){
return "";
}

for(let i = 0; i < minLen; i++){
char = strs[0][i];
// 用于标记该字符是否为前缀
let flag = true;
for(let j = 1; j < strs.length; j++){
if(strs[j][i] != char){
flag = false;
}
}
if(flag){
prefix += char;
}
else{
return prefix;
}
}
return prefix;
};
``````

## 三数之和

### 题目描述

``````例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4]，

[
[-1, 0, 1],
[-1, -1, 2]
]
``````

### 解答

``````var threeSum = function(nums) {
if(nums.length < 3){
return [];
}

let res = [];
// 排序
nums.sort((a, b) => a - b);
for(let i = 0; i < nums.length; i++){
if(i > 0 && nums[i] == nums[i-1]){
// 去重
continue;
}
if(nums[i] > 0){
// 若当前元素大于0，则三元素相加之后必定大于0
break;
}
// l为左下标，r为右下标
let l = i + 1; r = nums.length - 1;
while(l<r){
let sum = nums[i] + nums[l] + nums[r];
if(sum == 0){
res.push([nums[i], nums[l], nums[r]]);
while(l < r && nums[l] == nums[l+1]){
l++
}
while(l < r && nums[r] == nums[r-1]){
r--;
}
l++;
r--;
}
else if(sum < 0){
l++;
}
else if(sum > 0){
r--;
}
}
}

return res;
};
``````

## 最接近的三数之和

### 题目描述

``````例如，给定数组 nums = [-1，2，1，-4], 和 target = 1.

``````

### 解答

``````var threeSumClosest = function(nums, target) {
if(nums.length == 0){
return 0;
}
else if(nums.length < 4){
return nums.reduce((a, b) => a + b)
}
else {
let min = -1, res;
nums.sort((a, b) => a - b);
for(let i = 0; i < nums.length - 2; i++){
if(i > 0 && nums[i] == nums[i - 1]){
// 去重
continue;
}
let l = i + 1, r = nums.length - 1;
while(l < r){
let sum = nums[i] + nums[l] + nums[r];
if(sum == target){
// 差距为0，直接出结果
return sum;
}
else if(sum > target){
if(min == -1){
min = sum - target;
res = sum;
}
else if(sum - target < min){
min = sum - target;
res = sum;
}
r--;
}
else if(sum < target){
if(min == -1){
min = target - sum;
res = sum;
}
else if(target - sum< min){
min = target - sum;
res = sum;
}
l++;
}
}
}
return res;
}
};
``````

## 电话号码的字母组合

### 示例

``````输入："23"

``````

### 解答

``````const numMap = {
2: ['a', 'b', 'c'],
3: ['d', 'e', 'f'],
4: ['g', 'h', 'i'],
5: ['j', 'k', 'l'],
6: ['m', 'n', 'o'],
7: ['p', 'q', 'r', 's'],
8: ['t', 'u', 'v'],
9: ['w', 'x', 'y', 'z']
}

var letterCombinations = function(digits) {
if(digits.length == 0){
return []
}
let res = [...numMap[digits[0]]];
for(let i = 1; i < digits.length; i++){
let temp = [];
for(let j = 0; j < res.length; j++){
for(let k = 0; k < numMap[digits[i]].length; k++){
temp.push(res[j]+numMap[digits[i]][k]);
}
}
res = [...temp]
}
return res;
};
``````

## 四数之和

### 示例

``````给定数组 nums = [1, 0, -1, 0, -2, 2]，和 target = 0。

[
[-1,  0, 0, 1],
[-2, -1, 1, 2],
[-2,  0, 0, 2]
]
``````

### 解答

``````if(nums.length < 4){
return [];
}
let res = [];
nums.sort((a, b) => a - b);
for(let i = 0; i < nums.length - 3; i++){
if(i > 0 && nums[i] == nums[i-1]){
continue;
}
for(let j = i + 1; j < nums.length - 2; j++){
if(j > i + 1 && nums[j] == nums[j-1]){
continue;
}
let l = j + 1, r = nums.length - 1;
while(l < r){
let sum = nums[i] + nums[j] + nums[l] + nums[r];
if(sum == target){
res.push([nums[i], nums[j], nums[l], nums[r]])
while(l<r && nums[l] == nums[l+1]){
l++;
}
while(l<r && nums[r] == nums[r-1]){
r--;
}
l++;
r--;
}
else if(sum < target){
l++;
}
else if(sum > target){
r--;
}
}
}
}
return res;
``````

};

## 删除链表的倒数第N个节点

### 示例

``````给定一个链表: 1->2->3->4->5, 和 n = 2.

``````

### 解答

``````var removeNthFromEnd = function(head, n) {
while(cur.next){
cur.next.prev = cur;
cur = cur.next;
}
if(n == 1){
// 删除最后一个节点
if(!cur.prev){
return null;
}
else{
cur.prev.next = null;
}
}
while(n > 0 && cur){
if(n == 1){
if(!cur.prev){
// 删除第一个节点
cur.next.prev = null;
return cur.next
}
else{
cur.prev.next = cur.next;
cur.next.prev = cur.prev;
}
}
cur = cur.prev;
n--;
}
};
``````

## 有效的括号

### 示例

``````输入: "()"

``````
``````输入: "()[]{}"

``````
``````输入: "(]"

``````
``````输入: "([)]"

``````
``````输入: "{[]}"

``````

### 解答

``````var isValid = function(s) {
if(s.length == 0){
return true;
}
let stack = [];
for(let i = 0; i < s.length; i++){
if(s[i] == "(" || s[i] == "{"  || s[i] == "["){
// 左括号，入栈
stack.push(s[i]);
}
else if(s[i] == ")" || s[i] == "}" || s[i] == "]"){
let char = stack.pop();
if((char == "(" && s[i] == ")") || (char == "{" && s[i] == "}") || (char == "[" && s[i] == "]")){
continue
}
else{
return false
}
}
}
if(stack.length == 0){
return true
}
else{
return false;
}
};
``````

## 小结

Node.js 2014这一年发生了什么
Node.js 的 2014 年充满了不幸和争议. 这一年 Noder 们经历了太多的伤心事, 经历了漫长的等待, 经历了沉重的分裂之痛. 也许 Noder 们不想回忆14年 Node.js land 发生的事情, 但正因为痛才更有铭记的价...
2015-11-12
jsdom 中文文档（纯翻译）
jsdom是一个纯粹由 javascript 实现的一系列 web标准，特别是 WHATWG 组织制定的DOM和 HTML 标准，用于在 nodejs 中使用。大体上来说，该项目的目标是模拟足够的Web浏览器子集，以便用于测试和挖掘真实世界...
2018-05-14
Vue.js组件tab实现选项卡切换

2017-03-13
React.js编程思想
2015-11-12

&lt;font face=&quot;寰�杞�闆呴粦, Arial, sans-serif &quot;&gt;2014骞达紝杞�浠惰�屼笟鍙戝睍杩呴€燂紝鍚勭�嶈��瑷€灞傚嚭涓嶇┓锛屼互婊¤冻鐢ㄦ埛涓嶆柇鍙樺寲鐨勯渶姹傘€傝繖浜涜��...
2015-11-12
three.js实现围绕某物体旋转

2017-02-17
JS中的语音合成——Speech Synthesis API
JS中的语音合成——Speech Synthesis API 简介 HTML5中和Web Speech相关的API实际上有两类，一类是“语音识别(Speech Recognition)”，另外一个就是“语音合成(Speech Synthes...
2018-05-17
JavaScript教程：JS中的原型
Keith Peters 几年前发表的一篇博文，关于学习没有“new”的世界，其中解释了使用原型继承代替构造函数。两者都是纯粹的原型编码。 标准方法（The Standard Way） 一直以来，我们学习的在 JavaScript 里创建对...
2015-11-12
canvas图片绘制跨域问题解决方案Tainted canvases may not be exported

2018-04-19
NodeJS参考手册pdf版

2015-11-12