1、無重複字符的最長子串
需求:給定一個字符串(由英文字母、數字、符號和空格組成),請你找出其中不含有重複字符的最長子串的長度。
示例:輸入s = "abcabcbb"
,輸出爲 3
。因爲無重複字符的最長子串是 "abc",所以其長度爲 3。
function maxSubString (s) {
let map = new Map(), max = 0
for(let i = 0, j = 0; j < s.length; j++) {
if(map.has(s[j])) {
i = Math.max(map.get(s[j]) + 1, i)
}
max = Math.max(max, j - i + 1)
map.set(s[j], j)
}
return max
}
// 測試
maxSubString("abcabcbb") // 3
2、求兩個矩形重疊面積的大小。
需求:在二維平面上,求四組座標構成的兩個矩形所重疊的面積大小。
示例:輸入[-3, 0, 3, 4, 0, -1, 9, 2]
,輸出 6
(即重疊的面積大小爲 6),圖解如下。
function overlapArea([x1, y1, x2, y2, x3, y3, x4, y4]) {
let min = Math.min
let max = Math.max
// 記錄矩形的右上角點、左下角點
let [Ax,Bx] = [min(x1,x2), max(x1,x2)]
let [Ay,By] = [min(y1,y2), max(y1,y2)]
let [Cx,Dx] = [min(x3,x4), max(x3,x4)]
let [Cy,Dy] = [min(y3,y4), max(y3,y4)]
console.log(Ax, Ay, Bx, By, Cx, Cy, Dx, Dy)
let w = 0
let h = 0
if(!(Cy>=By || Dy<=Ay || Dx<=Ax || Cx>=Bx)) {
console.log('兩矩形重合')
if(Cx>Ax) w = Bx-Cx
if(Dx<Bx) w = Dx-Ax
if(Ax>Cx && Bx<Dx) w = Bx-Ax
if (Cx>Ax && Dx<Bx) w = Dx-Cx
if(Cy<By) h = By-Cy
if(Dy>Ay) h = Dy-Ay
if(Dy>By && Cy<Ay) h = By-Ay
if(By>Dy && Ay<Cy) h = Dy-Cy
}
return w*h
}
// 測試
overlapArea([-3, -3, 10, -1, 9, 2, 0, -1]) // 0,兩矩形不重合
overlapArea([-3, 0, 3, 4, 0, -1, 9, 2]) // 6,兩矩形重合
3、實現先進先出隊列
需求:最多使用兩個棧,實現先進先出隊列,並支持以下操作:
- void push(int x) 將元素 x 推到隊列的末尾
- int pop() 從隊列的開頭移除並返回這個元素
- int peek() 不改變隊列,只返回隊列開頭的元素
- boolean empty() 如果隊列爲空返回 true ;否則返回 false
var MyQueue = function() {
this.inStack = []
this.outStack = []
}
MyQueue.prototype.push = function(x) {
this.inStack.push(x)
}
MyQueue.prototype.pop = function() {
if (!this.outStack.length) {
this.in2out()
}
return this.outStack.pop()
}
MyQueue.prototype.peek = function() {
if (!this.outStack.length) {
this.in2out()
}
return this.outStack[this.outStack.length - 1]
}
MyQueue.prototype.empty = function() {
return this.outStack.length === 0 && this.inStack.length === 0
}
MyQueue.prototype.in2out = function() {
while (this.inStack.length) {
this.outStack.push(this.inStack.pop())
}
}
// 測試
var queue = new MyQueue()
queue.push(1) // [1]
queue.push(2) // [1,2]
queue.push(3) // [1,2,3]
queue.pop() // [2,3]
queue.peek() // 2
queue.empty() // false
4、封裝洗牌算法。
function shuffle(arr) {
let m = arr.length
while (m){
let index = Math.floor(Math.random() * m--)
let cur = arr[m]
arr[m] = arr[index]
arr[index] = cur
}
return arr
}
// 測試一下
shuffle([1,2,3,4,5,6])
5、理解服務端渲染。
題目:什麼是服務端渲染?SSR、BSR各有什麼優勢和劣勢?有哪些SEO策略?
6、原生封裝 WebSocket。
const socket = new WebSocket('ws://localhost:8080')
socket.addEventListener('open', function (event) {
socket.send('Hello Server!')
})
socket.addEventListener('message', function (event) {
console.log('Message from server ', event.data)
})
7、原生封裝圖片上傳方法。
function upload(option) {
if (typeof XMLHttpRequest === 'undefined') {
return;
}
const xhr = new XMLHttpRequest();
const action = option.action;
if (xhr.upload) {
xhr.upload.onprogress = function progress(e) {
if (e.total > 0) {
e.percent = e.loaded / e.total * 100;
}
option.onProgress(e);
};
}
const formData = new FormData();
if (option.data) {
Object.keys(option.data).forEach(key => {
formData.append(key, option.data[key]);
});
}
formData.append(option.filename, option.file, option.file.name);
xhr.onerror = function error(e) {
option.onError(e);
};
xhr.onload = function onload() {
if (xhr.status < 200 || xhr.status >= 300) {
return option.onError(getError(action, option, xhr));
}
option.onSuccess(getBody(xhr));
};
xhr.open('post', action, true);
if (option.withCredentials && 'withCredentials' in xhr) {
xhr.withCredentials = true;
}
const headers = option.headers || {};
for (let item in headers) {
if (headers.hasOwnProperty(item) && headers[item] !== null) {
xhr.setRequestHeader(item, headers[item]);
}
}
xhr.send(formData);
return xhr;
}
8、求兩個非負數的最大公約數。
function divisor(a,b) {
for(i=a;i>0;i--){
if(a%i==0){
if(b%i==0){
return i
}
}
}
}
// 測試一下
divisor(512,768) // 256
9、封裝方法,判斷兩個元素是否相等。
function isObject(obj) {
return obj !== null && typeof obj === 'object'
}
function looseEqual(a, b) {
if (a === b) { return true }
var isObjectA = isObject(a);
var isObjectB = isObject(b);
if (isObjectA && isObjectB) {
try {
var isArrayA = Array.isArray(a);
var isArrayB = Array.isArray(b);
if (isArrayA && isArrayB) {
return a.length === b.length && a.every(function (e, i) {
return looseEqual(e, b[i])
})
} else if (a instanceof Date && b instanceof Date) {
return a.getTime() === b.getTime()
} else if (!isArrayA && !isArrayB) {
var keysA = Object.keys(a);
var keysB = Object.keys(b);
return keysA.length === keysB.length && keysA.every(function (key) {
return looseEqual(a[key], b[key])
})
} else {
return false
}
} catch (e) {
return false
}
} else if (!isObjectA && !isObjectB) {
return String(a) === String(b)
} else {
return false
}
}
// 測試一下
looseEqual(1,1) // true
looseEqual([1],[1]) // true
looseEqual({a:1},{a:1}) // true
looseEqual({a:1},{a:2}) // false
10、談一談瀏覽器的緩存機制。
本週結束,下週繼續!!!