-
Notifications
You must be signed in to change notification settings - Fork 39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
一些特别棒的面试题[4] #245
Comments
只出现一次的数字给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
示例 1:
输入: [2,2,1]
输出: 1
示例 2:
输入: [4,1,2,1,2]
输出: 4 答案/**
* @param {number[]} nums
* @return {number}
*/
var singleNumber = function (nums) {
/** 解法1:暴力遍历
* 性能:704ms 40.5MB
*/
let numsSet = Array.from(new Set(nums));
let numsMap = numsSet.map((num) => ({
num,
count: 0,
}));
nums.forEach((num, i) => {
numsMap.forEach((numM, j) => {
if (numM.num === num) {
numM.count++;
}
});
});
let filterArr = numsMap.filter((num) => num.count === 1);
return filterArr[0].num;
/** 解法2:Set 首次出现add 二次出现delete
* 性能: 72 ms 38MB
*/
let numsSet = new Set();
for (let i = 0; i < nums.length; i++) {
if (!numsSet.has(nums[i])) {
numsSet.add(nums[i]);
} else {
numsSet.delete(nums[i]);
}
}
return [...numsSet][0];
}; 这是一道leetcode 简单难度的题。 |
汇总区间给定一个乱序整形数组[0,1,7,13,15,16,2,4,5],找出其中连续出现的数字区间为如下:["0->2", "4->5", "7", "13", "15->16"] 答案function continuous(arr) {
arr.sort((a, b) => a - b);
let stack = [];
let result = [];
for (let i = 0; i < arr.length; i++) {
if (stack.length === 0 || arr[i] - stack[stack.length - 1] === 1) {
stack.push(arr[i]);
} else {
if (stack.length > 1) {
result.push(`${stack[0]}->${stack[stack.length - 1]}`);
} else {
result.push(`${stack[0]}`);
}
stack = [];
stack.push(arr[i]);
}
if (i === arr.length - 1) {
if (stack.length > 1) {
result.push(`${stack[0]}->${stack[stack.length - 1]}`);
} else {
result.push(`${stack[0]}`);
}
}
}
return result;
}
console.log(continuous([0, 1, 7, 13, 15, 16, 2, 4, 5])); 这是一道leetcode 中等难度的题。 |
实现红绿灯效果实现红绿灯效果,使用console 输出 “红”、“绿”、“黄”示意,等待时间分别为 3s、2s、1s 答案function trafficCtrl() {
// timeline 红0~2 绿3~4 黄5
const borders = { red: 3, green: 5, yellow: 6 };
let current = 0;
setInterval(() => {
if (current >= 0 && current <= 2) {
console.log('红', borders.red - current);
} else if (current >= 3 && current <= 4) {
console.log('绿', borders.green - current);
} else {
console.log('黄', borders.yellow - current);
}
current++;
if (current > 5) {
current = 0;
}
}, 1000);
}
trafficCtrl(); 红 3 |
数组去重输入:
['1', '2', '3', 1, '2', undefined, undefined, null, null, 1, 'a','b','b'];
输出:
["1", "2", "3", 1, undefined, null, "a", "b"] 答案// 解法1:includes
function removeDuplicate(arr) {
const result = [];
for(const item of arr){
if(!result.includes(item)) result.push(item);
}
return result;
}
// 解法2:Map
function removeDuplicate(arr) {
const map = new Map();
for(const item of arr){
if(!map.has(item)) map.set(item, true);
}
const result = [...map.keys()];
return result;
}
// 解法3:对撞指针
function removeDuplicate(arr) {
const map = new Map();
let i = 0;
let j = arr.length - 1;
while(i<=j){
if(!map.has(arr[i])) map.set(arr[i], true);
if(!map.has(arr[j])) map.set(arr[j], true);
i++;
j--;
}
const result = [...map.keys()];
return result;
}
// 解法4:filter
function removeDuplicate(arr) {
return arr.filter((item, i)=> arr.indexOf(item) === i)
} |
返回 excel 表格列名输入:1 输出:A
输入:2 输出:B
输入:26 输出:Z
输入:27 输出:AA
输入:52 输出:AZ 答案function getExcelColumn(column) {
const obj = {};
let i = 0;
const startCode = "A".charCodeAt();
while (i < 26) {
obj[i + 1] = String.fromCharCode(startCode + i);
i++;
}
if (column <= 26) {
return obj[column]
}
const stack = [];
const left = column % 26;
const floor = Math.floor(column / 26);
if (left) {
stack.unshift(obj[left])
stack.unshift(obj[floor]);
} else {
stack.unshift('Z')
stack.unshift(obj[floor - 1]);
}
const result = stack.join("");
return result;
} 这是一道leetcode 简单难度的题。 |
如何检测一个空对象
答案// 解法1: Object.prototype.toString.call和JSON.stringify
function isObjEmpty(obj){
return Object.prototype.toString.call(obj)==="[object Object]" && JSON.stringify({}) === "{}";
}
// 解法2: Object.keys() Object.values()
function isObjEmpty(obj){
return Object.keys(obj).length === 0 || Object.values(obj).length === 0;
}
// 解法3:for...in
function isObjEmpty(obj){
for(key in obj){
if(key) return false
}
return true;
} |
实现a+a+a打印'abc'console.log(a + a + a); // 打印'abc' 答案/*
console.log(a + a + a); // 打印'abc'
*/
/**
* 解法1: Object.defineProperty() 外部变量
*/
let value = "a";
Object.defineProperty(this, "a", {
get() {
let result = value;
if (value === "a") {
value = "b";
} else if (value === "b") {
value = "c";
}
return result;
},
});
console.log(a + a + a);
/**
* 解法1(优化版):Object.defineProperty() 内部变量
*/
Object.defineProperty(this, "a", {
get() {
this._v = this._v || "a";
if (this._v === "a") {
this._v = "b";
return "a";
} else if (this._v === "b") {
this._v = "c";
return "b";
} else {
return this._v;
}
},
});
console.log(a + a + a);
/**
* 解法2: Object.prototpye.valueOf()
*/
let index = 0;
let a = {
value: "a",
valueOf() {
return ["a", "b", "c"][index++];
},
};
console.log(a + a + a);
/**
* 解法3:charCodeAt,charFromCode
*/
let code = "a".charCodeAt(0);
let count = 0;
Object.defineProperty(this, "a", {
get() {
let char = String.fromCharCode(code + count);
count++;
return char;
},
});
console.log(a + a + a); // 'abc'
/**
* 解法3(优化版一):内部变量this._count和_code
*/
Object.defineProperty(this, "a", {
get() {
let _code = "a".charCodeAt(0);
this._count = this._count || 0;
let char = String.fromCharCode(_code + this._count);
this._count++;
return char;
},
});
console.log(a + a + a); // 'abc'
/**
* 解法3(优化版二):内部变量this._code
*/
Object.defineProperty(this, "a", {
get() {
this._code = this._code || "a".charCodeAt(0);
let char = String.fromCharCode(this._code);
this._code++;
return char;
},
});
console.log(a + a + a); // 'abc'
/*
题目扩展: 打印`a...z`
a+a+a; //'abc'
a+a+a+a; //'abcd'
*/
/**
* charCodeAt,charFromCode
*/
let code = "a".charCodeAt(0);
let count = 0;
Object.defineProperty(this, "a", {
get() {
let char = String.fromCharCode(code + count);
if (count >= 26) {
return "";
}
count++;
return char;
},
});
// 打印‘abc’
console.log(a + a + a); // 'abc'
// 打印‘abcd’
let code = "a".charCodeAt(0);
let count = 0;
// {...定义a...}
console.log(a + a + a); // 'abcd'
// 打印‘abcdefghijklmnopqrstuvwxyz’
let code = "a".charCodeAt(0);
let count = 0;
// {...定义a...}
let str = "";
for (let i = 0; i < 27; i++) {
str += a;
}
console.log(str); // "abcdefghijklmnopqrstuvwxyz"
/*
题目扩展(优化版): 打印`a...z`
a+a+a; //'abc'
a+a+a+a; //'abcd'
*/
Object.defineProperty(this, "a", {
get() {
this._code = this._code || "a".charCodeAt(0);
let char = String.fromCharCode(this._code);
if (this._code >= "a".charCodeAt(0) + 26) {
return "";
}
this._code++;
return char;
},
});
// 打印‘abc’
console.log(a + a + a); // 'abc' |
实现一个Event模块简单实现一个事件订阅机制,具有on、emit、once、off
on(event, func){ ... }
emit(event, ...args){ ... }
once(event, func){ ... }
off(event, func){ ... }
const event = new EventEmitter();
event.on('someEvent', (...args) => {
console.log('some_event triggered', ...args);
});
event.emit('someEvent', 'abc', '123');
event.once('someEvent', (...args) => {
console.log('some_event triggered', ...args);
});
event.off('someEvent', callbackPointer); 答案class EventEmitter {
constructor() {
this.map = new Map()
}
on(event, func) {
const e = { name: event, handler: { type: 'persistent', func } }
const { handlers } = this.map.get(e.name) || {}
this.map.set(e.name, this.map.has(e.name) ? { handlers: [...handlers, e.handler] } : { handlers: [e.handler] })
}
emit(event, ...args) {
const e = { name: event }
const { handlers } = this.map.get(e.name) || {}
if (!handlers) return
for (const handler of handlers) {
handler.func(...args)
}
// 过滤
this.map.set(e.name, { handlers: handlers.filter((handler) => handler.type !== 'once') })
// console.log('emit', this.map)
}
once(event, func) {
const e = { name: event, handler: { func, type: 'once' } }
const { handlers } = this.map.get(e.name) || {}
this.map.set(e.name, this.map.has(e.name) ? { handlers: [...handlers, e.handler] } : { handlers: [e.handler] })
// console.log('once', this.map)
}
off(event, func) {
const e = { name: event, handler: { func } }
const { handlers } = this.map.get(e.name) || {}
if (!handlers) return
const leftHandlers = handlers.filter((handler) => handler.func !== func)
this.map.set(e.name, { handlers: leftHandlers })
// console.log('off', this.map)
}
}
const event = new EventEmitter()
const callbackPointer = (...args) => {
console.log('some_event triggered', ...args)
}
const callbackPointer1 = (...args) => {
console.log('some_event triggered 1', ...args)
}
event.on('someEvent', callbackPointer)
event.on('someEvent', callbackPointer1)
event.emit('someEvent', 'abc', '123')
event.off('someEvent', callbackPointer)
event.emit('someEvent', 'abc', '123')
const callbackPointer2 = (...args) => {
console.log('some_event triggered 2', ...args)
}
const callbackPointer3 = (...args) => {
console.log('some_event triggered 3', ...args)
}
event.once('someEvent2', callbackPointer2)
event.once('someEvent2', callbackPointer3)
event.emit('someEvent2', 'abc', '123')
event.emit('someEvent2', 'abc', '123')
const callbackPointer4 = (...args) => {
console.log('some_event triggered 4', ...args)
}
const callbackPointer5 = (...args) => {
console.log('some_event triggered 5', ...args)
}
event.on('someEvent3', callbackPointer4)
event.once('someEvent3', callbackPointer5)
event.emit('someEvent3', 'abc', '123')
event.emit('someEvent3', 'abc', '123')
|
大整数相加请通过代码实现大整数(可能比Number.MAX_VALUE大)相加运算
var bigint1 = new BigInt('1231230');
var bigint2 = new BigInt('12323123999999999999999999999999999999999999999999999991');
console.log(bigint1.plus(bigint2)) 答案function BigInt(value) {
this.value = value;
}
BigInt.prototype.plus = function (bigint) {
let aArr = this.value.split("");
let bArr = bigint.value.split("");
let stack = [];
let count = 0;
while (aArr.length !== 0 || bArr.length !== 0) {
let aPop = aArr.pop() || 0;
let bPop = bArr.pop() || 0;
let stackBottom = 0;
if (stack.length > count) {
stackBottom = stack.shift();
}
let sum = parseInt(aPop) + parseInt(bPop) + parseInt(stackBottom);
if (sum < 10) {
stack.unshift(sum);
} else if (sum >= 10) {
stack.unshift(sum - 10);
stack.unshift(1);
}
count++;
}
return stack.join("");
}; |
SuperPerson继承Person写一个类Person,拥有属性age和name,拥有方法say(something)
再写一个类Superman,继承Person,拥有自己的属性power,拥有自己的方法fly(height) ES5方式 答案function Person(age, name){
this.age = age;
this.name = name;
}
Person.prototype.say = function(something) {
// ...
}
function Superman(age, name, power){
Person.call(this, age, name, power);
this.power = power;
}
Superman.prototype = Object.create(Person.prototype);
Superman.prototype.constructor = Superman;
Superman.prototype.fly = function(height) {
// ...
}
let superman = new Superman(25, 'GaoKai', 'strong');
// class方式
class Person {
constructor(age, name){
this.age = age;
this.name = name;
}
say(something){
// ...
console.log("say");
}
}
class Superman extends Person{
constructor(age, name, power){
super(age, name)
this.power = power;
}
fly(height){
// ...
console.log("fly");
}
}
let superman = new Superman(25, 'GaoKai', 'strong'); |
字符串隐藏部分内容字符串隐藏部分内容
说明:实现一个方法,接收一个字符串和一个符号,将字符串中间四位按指定符号隐藏
1. 符号无指定时使用星号(*)
2. 接收的字符串小于或等于四位时,返回同样长度的符号串,等同于全隐藏,如 123,隐藏后是 ***
3. 字符串长度是大于四位的奇数时,如 123456789,隐藏后是 12****789,奇数多出来的一位在末尾
示例:
mask('blibaba', '#'); // b####ba
mask('05716666'); // 05****66
mask('hello'); // ****o
mask('abc', '?'); // ???
mask('哔里巴巴集团', '?'); // 哔????团 答案function mask(str, char = "*") {
if(str.length<=4) return char.repeat(str.length);
/* 代码实现 */
let result = "";
let i = Math.floor(str.length / 2) - 1;
let j = Math.floor(str.length / 2);
while(result.length!==str.length){
if(j - i <= 4){
result = char + result;
result += char ;
} else {
result = (str[i] || "") + result;
result += str[j] ;
}
i--;
j++;
}
return result;
} |
实现一个sum(1,2,3)(4)(5)(6,7)(8)()返回结果为这些数字的和:36。 这是一道考察求和+闭包+递归的题目。 答案function sum(){
const result = [...arguments].reduce((acc, cur)=>acc+cur)
return function(){
if(arguments.length === 0)return result
return sum(...[...arguments, result]);
}
} |
实现一个sum(1,2,3)(4)(5)(6,7)(8)()升级版:如何实现加,减,乘,除呢?sum(1,2,3)(4)(5)(6,7)(8)()
minus(1,2,3)(4)(5)(6,7)(8)()
multiple(1,2,3)(4)(5)(6,7)(8)()
divide(1,2,3)(4)(5)(6,7)(8)() 除了考察求和,闭包,递归以外,还考察了柯里化函数。 sum和multiple不用关注顺序。 答案function curry(callback){
return function curried (){
const result = callback(arguments)
return function(){
if(arguments.length === 0)return result
return curried(...[result, ...arguments]);
}
}
}
let sum = (args) =>{
return [...args].reduce((acc, cur)=>acc+cur)
}
let minus = (args) =>{
return [...args].reduce((acc, cur)=>acc-cur)
}
let multiple = (args) =>{
return [...args].reduce((acc, cur)=>acc*cur)
}
let divide = (args) =>{
return [...args].reduce((acc, cur)=>acc / cur)
}
let currySum = curry(sum)
let curryMultiple = curry(multiple)
let curryDivide = curry(divide)
let curryMinus = curry(minus)
console.log(currySum(1,2,3)(4)(5)(6,7)(8)())
console.log(curryMultiple(1,2,3)(4)(5)(6,7)(8)())
console.log(curryDivide(1,2,3)(4)(5)(6,7)(8)())
console.log(curryMinus(1,2,3)(4)(5)(6,7)(8)())
微信公众号: 生活在浏览器里的我们 / excellent_developers
|
最近面试了一些公司,拿了一些offer,不记录概念题目,仅记录coding类题目。
小伙伴们空闲时间可以做这些题目练练手。
The text was updated successfully, but these errors were encountered: