原文地址:一些特地棒的面试题[4]

最近面试了一些公司,拿了一些offer,不记录概念题目,仅记录coding类题目。
小伙伴们闲暇工夫能够做这些题目练练手。

  • 只呈现一次的数字
  • 汇总区间
  • 实现红绿灯成果
  • 数组去重
  • 返回 excel 表格列名
  • 检测空对象
  • 实现a+a+a打印'abc'
  • 实现一个Event模块
  • 大整数相加
  • SuperPerson继承Person
  • 字符串暗藏局部内容

只呈现一次的数字

给定一个非空整数数组,除了某个元素只呈现一次以外,其余每个元素均呈现两次。找出那个只呈现了一次的元素。
示例 1:

输出: [2,2,1]
输入: 1
示例 2:

输出: [4,1,2,1,2]
输入: 4
这是一道leetcode 简略难度的题。
题目:leetcode 136 只呈现一次的数字
题解:136 只呈现一次的数字

/** * @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];};

汇总区间

给定一个乱序整形数组[0,1,7,13,15,16,2,4,5],找出其中间断呈现的数字区间为如下:["0->2", "4->5", "7", "13", "15->16"]
这是一道leetcode 中等难度的题。
题目:leetcode 228 汇总区间
题解:228汇总区间(Summary Ranges)

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]));

实现红绿灯成果,应用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
红 2
红 1
绿 2
绿 1
黄 1
红 3
红 2

数组去重

输出:
['1', '2', '3', 1, '2', undefined, undefined, null, null, 1, 'a','b','b'];
输入:
["1", "2", "3", 1, undefined, null, "a", "b"]

// 解法1:includesfunction removeDuplicate(arr) {    const result = [];    for(const item of arr){       if(!result.includes(item)) result.push(item);    }    return result;}// 解法2:Mapfunction 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:filterfunction removeDuplicate(arr) {    return arr.filter((item, i)=> arr.indexOf(item) === i)}

写一个函数返回 excel 表格列名

输出:1 输入:A
输出:2 输入:B
输出:26 输入:Z
输出:27 输入:AA
输出:52 输入:AZ

这是一道leetcode 简略难度的题。
题目:leetcode 168 Excel表列名称
题解:168 Excel表列名称

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;}

如何检测一个空对象

// 解法1: Object.prototype.toString.call和JSON.stringifyfunction 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...infunction 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办法 * 示例: * 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); // callbackPointer为回调指针,不能是匿名函数 */class EventEmitter {  constructor() {    this.listeners = [];  }  on(event, func) {    const callback = () => (listener) => listener.name === event;    const idx = this.listeners.findIndex(callback);    if (idx === -1) {      this.listeners.push({        name: event,        callbacks: [func],      });    } else {      this.listeners[idx].callbacks.push(func);    }  }  emit(event, ...args) {    if (this.listeners.length === 0) return;    const callback = () => (listener) => listener.name === event;    const idx = this.listeners.findIndex(callback);    this.listeners[idx].callbacks.forEach((cb) => {      cb(...args);    });  }  once(event, func) {    const callback = () => (listener) => listener.name === event;    let idx = this.listeners.findIndex(callback);    if (idx === -1) {      this.listeners.push({        name: event,        callbacks: [func],      });    }  }  off(event, func) {    if (this.listeners.length === 0) return;    const callback = () => (listener) => listener.name === event;    let idx = this.listeners.findIndex(callback);    if (idx !== -1) {      let callbacks = this.listeners[idx].callbacks;      for (let i = 0; i < callbacks.length; i++) {        if (callbacks[i] === func) {          callbacks.splice(i, 1);          break;        }      }    }  }}// let event = new EventEmitter();// let onceCallback = (...args) => {//   console.log("once_event triggered", ...args);// };// let onceCallback1 = (...args) => {//   console.log("once_event 1 triggered", ...args);// };// // once仅监听一次// event.once("onceEvent", onceCallback);// event.once("onceEvent", onceCallback1);// event.emit("onceEvent", "abc", "123");// // off销毁指定回调// let onCallback = (...args) => {//   console.log("on_event triggered", ...args);// };// let onCallback1 = (...args) => {//   console.log("on_event 1 triggered", ...args);// };// event.on("onEvent", onCallback);// event.on("onEvent", onCallback1);// event.emit("onEvent", "abc", "123");// event.off("onEvent", onCallback);// event.emit("onEvent", "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;}

期待和大家交换,共同进步,欢送大家退出我创立的与前端开发密切相关的技术探讨小组:

  • 微信公众号: 生存在浏览器里的咱们 / excellent_developers
  • Github博客: 趁你还年老233的集体博客
  • SegmentFault专栏:趁你还年老,做个优良的前端工程师

致力成为优良前端工程师!