算法
随着互联网发展速度放缓,企业招聘时更挑人,所以越来越多的公司,喜欢在面试中考察算法,特别是在二面的时候,所以算法一定得有所准备。
实现bind
function deepClone(obj){
if (obj === null | typeof obj !== 'object') return obj;
if (obj instanceof Date) return new Date(obj);
if (obj instanceof RegExp) return new Date(RegExp);
const newObj = new obj.constuctor;
for (let key in obj) {
if(obj.hasOwnProperty(key)) {
newObj[key] = deepClone(obj[key]);
}
}
return newObj;
}
实现深拷贝
function deepClone(obj){
if (obj === null | typeof obj !== 'object') return obj;
if (obj instanceof Date) return new Date(obj);
if (obj instanceof RegExp) return new Date(RegExp);
const newObj = new obj.constuctor;
for (let key in obj) {
if(obj.hasOwnProperty(key)) {
newObj[key] = deepClone(obj[key]);
}
}
return newObj;
}
不需要借助第三个临时变量,实现两个变量的交换
function swap(a,b){
b = b - a;
a = a + b;
b = a - b;
return [a,b];
}
确保字符串的每个单词首字母都大写,其余部分小写
function titleCase(str) {
var lstr = str.toLowerCase().split(' ');
for(var i = 0 ; i < lstr.length; i++) {
lstr[i] = lstr[i][0].toUpperCase() + lstr[i].substring(1, lstr[i].length);
}
var res = lstr.join(' ');
return res;
}
titleCase("good night"); // Good Night
清除字符串前后的空格(兼容所有浏览器)
function trim(str) {
if (str & typeof str === "string") {
return str.replace(/(^s*)|(s*)$/g, ''); //去除前后空白符
}
}
去掉一组整型数组中重复的值
let unique = function(arr){
let hash={};
let data=[];
for (let i=0;i < arr.length; i++){
if (!hash[arr[i]]) {
hash[arr[i]] = true;
data.push(arr[i]);
}
}
return data
}
翻转字符串
- split()字符串转成数组;
- reverse()翻转数组;
- join()数组转化成字符串。
function reverseString(str){
return str.split('').reverse().join('');
}
找到提供的句子中最长的单词,并计算它的长度。
- 转化成数组;
- 根据元素长度排序;
- 输出最长元素并返回长度。
function findLongestString(str){
var arr = str.split(' ');
var arrSort = arr.sort(function (a,b) {
return b.length - a.length;
});
return [arrSort[0], arrSort[0].length];
}
截断一个字符串,如果字符串的长度比指定的参数num长,则把多余的部分用...来表示
function truncate(str, num){
var trStr = str.slice(0, num);
if (trStr.length > num) {
return trStr.concat('...');
} else {
return str;
}
}
判断一个字符串中出现次数最多的字符,统计这个次数
funcion findMaxStrCount(str) {
var countObj = {};
var max = '';
for(var i = 0; i < str.length; i++) {
var cur = str[i];
if(!countObj[cur]) {
countObj[cur] = 0;
}
countObj[cur]++;
if(max === '' || countObj[cur] > countObj[max]) { max = cur; }
}
return [max, countObj[max]];
}
快速排序(Quick Sort)
快速排序使用分治法来把一个串(list)分为两个子串(sub-lists)。具体算法描述如下:
var quickSort = function(arr) {
if (arr.length <= 1) { return arr; }
var pivotIndex = Math.floor(arr.length / 2);
var pivot = arr.splice(pivotIndex, 1)[0];
var left = [];
var right = [];
for (var i = 0; i < arr.length; i++){
if (arr[i] < pivot) {
left.push(arr[i]);
} else {
right.push(arr[i]);
}
}
return quickSort(left).concat([pivot], quickSort(right));
};
用递归实现斐波那契数列
function fib(n){
if(typeof n === 'number' && n > 0 && parseInt(n) === n ) {
return n < 3 ? 1 : fib(n-1)+fib(n-2);
} else {
return '输入不合法,请输入正整数!';
}
}
数组中两两之差的最大值?
function maxDiffInArray(arr){
if ( arr instanceof Array) {
if (arr.length) {
let max = arr[0], min = arr[0];
for (let i = 0; i < arr.length; i++) {
if ( typeof arr[i] !== 'number' ) {
return '输入不合法,数组存在非数字类型元素,请输入数字数组';
}
max = Math.max(arr[i], max), min = Math.min(arr[i], min);
}
return max - min;
} else {
return '输入不合法,数组为空,请输入非空数组';
}
} else {
return '输入不合法,请输入非空数组';
}
}
单向链表反转-JS实现
function reverseLinkedList(head) {
if (head === null || head.next === null) {
return head;
}
let newHead = null;
let nextHead = null;
while (head) {
nextHead = head.next; // 先记住当前节点的下一节点
head.next = newHead; // 把当前节点的指针指向上一节点
newHead = head; // 保留上一节点
head = nextHead; // 遍历下一节点
}
return newHead; // 最后head 为null跳出遍历,此时newHead就成了新链表的头结点了
}
变形的链表反转
给定一个单链表的头节点 head,实现一个调整单链表的函数,使得每K个节点之间为一组进行逆序,并且从链表的尾部开始组起,头部剩余节点数量不够一组的不需要逆序。
例如:链表:1->2->3->4->5->6->7->8->null, K = 3。那么 6->7->8,3->4->5,1->2各位一组。调整后:1->2->5->4->3->8->7->6->null。其中 1,2不调整,因为不够一组。
public ListNode reverseKGroup(ListNode head, int k) {
ListNode temp = head;
for (int i = 1; i < k && temp != null; i++) {
temp = temp.next;
}
//判断节点的数量是否能够凑成一组
if(temp == null)
return head;
ListNode t2 = temp.next;
temp.next = null;
//把当前的组进行逆序
ListNode newHead = reverseList(head);
//把之后的节点进行分组逆序
ListNode newTemp = reverseKGroup(t2, k);
// 把两部分连接起来
head.next = newTemp;
return newHead;
}
//逆序单链表
private static ListNode reverseList(ListNode head) {
if(head == null || head.next == null)
return head;
ListNode result = reverseList(head.next);
head.next.next = head;
head.next = null;
return result;
}
public ListNode solve(ListNode head, int k) {
// 调用逆序函数
head = reverse(head);
// 调用每 k 个为一组的逆序函数(从头部开始组起)
head = reverseKGroup(head, k);
// 在逆序一次
head = reverse(head);
return head;
}
小结
这里所列举的一些算法题,应付多数互联网公司应该就可以了,不过若想去字节跳动这个算法驱动的公司,最后还是的去Leecode等刷题网站刷一百题以上的算法。