原文地址:一些特別棒的面試題[4]
前端
最近面試了一些公司,拿了一些offer,不記錄概念題目,僅記錄coding類題目。
小夥伴們空閒時間能夠作這些題目練練手。git
給定一個非空整數數組,除了某個元素只出現一次之外,其他每一個元素均出現兩次。找出那個只出現了一次的元素。
示例 1:github
輸入: [2,2,1]
輸出: 1
示例 2:面試
輸入: [4,1,2,1,2]
輸出: 4
這是一道leetcode 簡單難度的題。
題目:leetcode 136 只出現一次的數字
題解:136 只出現一次的數字segmentfault
/** * @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]));
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: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) }
輸入: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.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; }
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'
/** * 說明:簡單實現一個事件訂閱機制,具備監聽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(""); };
//寫一個類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專欄:趁你還年輕,作個優秀的前端工程師
努力成爲優秀前端工程師!