数组去重
第一种 new Set
let ary = [1,2,3,4,2,1,3,4,5,6,4,3,5,6,3]
let arr = Array.from(new Set(ary))
第二种
第二种 拿出当前项和后面内容比较
for(let i = 0;i < ary.length - 1; i++){
let item = ary[i]
let arg = ary.slice(i + 1);
if(arg.indexOf(item) > -1){
ary.splice(i,1); // 这个性能不如 新建一个数组好
i--; // 会因为splice造成数组塌陷
}
}
第三种 判断是否包含,包含的话 那最后一项把当前项覆盖
for(let i = 0;i < ary.length - 1; i++){
let item = ary[i]
let arg = ary.slice(i + 1);
if(arg.indexOf(item) > -1){
ary[i] = ary[ary.length - 1];
ary.length--;
i--
}
}
第四种 循环遍历是否包含,不包含push
let arr = []
for(let i = 0;i < ary.length; i++){
if(arr.indexOf(item) === -1){
arr.push(ary[i])
}
}
等等还有很多,比如对象键值对,比如包含置为null 在过滤
数组扁平化
第一种 flat
let arr = [
[1,2,3],
[3,4,5,6],
[6,7,8,9,0,[1],[2,3]],10
]
flat()写 几 就扁平化 几级
Infinity 无限
arr.flat(Infinity)
第二种 reduce
function ab(arr){
return arr.reduce((pre,cur) => {
return pre.concat(Array.isArray(cur) ? ab(cur) : cur)
},[])
}
第三种 toString
arr.toString().split(',').map(itm => parserFloat(itm))
第四种 while + reduce + concat
while(arr.some(itm => Array.isArray(itm))){
arr = [].concat(...arr)
}
第五种 正则
JSON.stringify(arr).replace(/(\[|\])/g,'').split(',').map(itm =>parseFloat(itm))
斐波那契数列
let arr = [1,1,2,3,5,8,13,21]
当前项 = 当前项的 前面两位相加
可以 实现 传入 number 就能计算出对应斐波那契下标的值
第一种: while循环
function fibonacci(n){
if(n<=1) return 1;
let arr = [1,1];
let i = n + 1 -2;
// why?因为传入的n是数组下标,所以要+1 减2的话就是因为一开始就有两个所以只需要创建剩下的位数
while(i > 0){
let a = arr[arr.length - 2];
let b = arr[arr.length - 1];
arr.push(a+b);
i--
}
return arr[arr.length - 1];
}
第二种 递归
count:传进来的number cur:放的最终值 next:每次递归的时候作为下一次 cur 的值,需要每次 cur + next
||
|| 搭配食用
||
fibonacci(count){
function fn(count,cur = 1,next = 1){
if(count == 0){
return cur
}else {
return fn(count - 1,next,cur+next)
}
}
return fn(count)
}
冒泡排序
相邻两元素之间两两比较,比较出大值进行赋值互换,再依次与相邻的元素比较
必须要明白总共比较几回,一回比较几次!!!
let arr = [1,2,3,5,8,0,10]
// 外层控制比较几回
for(let i = 0; i < arr.length - 1; i++){
// 内层控制一回比较几次,并且比较大小
for(let j = 0; j < arr.length -1 -i; j++){
if(arr[j] > arr[j + 1]){
let temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
快速排序
分三步
- 取出数组的中间值
- 遍历数组,大于的放在右数组,小于的放在左边数组
- 递归并且用 concat 连接
let arr = [1,5,2,7,9,10,90,29,25,11,45,34];
function fast(arr){
if(arr.length < 1) return arr;
let num = Math.floor(arr.length / 2)
let idx = arr.splice(num,1)[0];
let left = [];
let right = [];
for(let i = 0; i < arr.length; i++){
if(arr[i] < idx){
left.push(arr[i])
}else {
right.push(arr[i])
}
}
return fast(left).concat(idx,fast(right))
}
插入排序
- 拿出一个值,作为初始数组的值,
- 通过循环想要排序的数组
- 并和新数组的值从后向前比
- 大于就splice到该项后面
function insert(arr){
let handle = []; // 这是最终成型的数组
handle.push(arr[0]); // 先拿一个值
for(let i = 1; i< arr.length; i++){
let news = arr[i];
for(let j = handle.length - 1; j >= 0; j--){ //从后向前比较
if(news > handle[j]){
handle.splice(j+1,0,news);
break;
}
if(j === 0){ // 比到为0的话直接放到数组头部
handle.unshift(news);
}
}
}
return handle
}
单链表反转
看到这的话,要明白它反转后是什么样 { a:4, next:{ a:3, next:{ a:2, next:{ a:1, next: null } } } } 看到这,肯定是有个大概的思路,就是节点替换
let obj = {
a:1,
next:{
a:2,
next: {
a:3,
next:{
a:4,
next:null
}
}
}
}
function reverseObj(obj){
let pre = null; // pre 最终的值(包含每一步)
let cur = obj
while(cur.next !== null){
let context = cur.next; // 首先拿到下一个next的值保存
cur.next = pre === null ? null : pre; // pre是上一项保存的值
pre = cur; // 将 当前项的值赋值给最终的值
cur = context // 拿到下一项next继续重复以商操作
}
}
计算字符串中出现最多的字符和其出现次数
思路,循环字符串每一项,如果有的话 给他+ 1 如果没有的话就给他赋值为 1
var str = 'asdfewrsadfadsfddqwegdsagflkoidfsg';
function strCount (str){
var obj = {};
for(let x = 0; x < str.length; x++){
var itm = str.charAt(x);
if(obj[itm]){
obj[itm]++;
}else {
obj[itm] = 1
}
}
}
会持续更新!!!