一、算法之数组去重

方法一:

【简单思路实现】:依次拿出数组的中的每一项,和后面的所有项进行比较,如果有相同的就删除。

  1. var ary=[1,2,3,2,4];
  2. /*
  3. 思路:
  4. 第一次:
  5. 拿出数组的第一项:1
  6. 给[2,3,2,4]进行比较,如果有重复就删除
  7. 拿出数组的第二项:2
  8. ====[3,2,4]进行比较,有重复的删除 [3,4]
  9. 拿出数组的第三项:3
  10. ===4 进行比较,有重复的删除,没有重复
  11. 还用拿最后一项4吗?====不用了
  12. 依次拿出数组中的每一项给剩余的所有项进行比较
  13. */
  14. function unique(ary){
  15. for(var i=0;i<ary.length-1;i++){
  16. var getItem=ary[i];
  17. for(var j=i+1;j<ary.length;j++){
  18. var remainItem=ary[j];
  19. // 如果当前项和后面的项在进行比较的时候,相同就说明重复,要删除掉原数组的那项
  20. if(getItem==remainItem){
  21. ary.splice(j,1);
  22. j--;
  23. }
  24. }
  25. }
  26. return ary;
  27. }
  28. console.log(unique(ary));

【splice造成的数组塌陷问题】

  1. var ary=[1,2,1,3,3,2,3];
  2. for(var i=0;i<ary.length-1;i++){
  3. var current=ary[i];
  4. for(var j=i+1;j<ary.length;j++){
  5. var next=ary[j];
  6. if(current==next){
  7. ary.splice(j,1);
  8. j--;
  9. }
  10. }
  11. }
  12. console.log(ary)

image.png

方法二:

【实现的思路】利用对象属性名不重复的思想,先建立一个空对象,然后依次循环数组中的每一项,把此项作为obj对象的属性名和属性值,在添加的时候,如果这个属性名对应的值已经存在,说明此项重复,删除掉此项

  1. /*
  2. var ary2=[1,2,1,3,3,2,3];
  3. 利用对象属性名不能重复的原理:对象中如果没有一个属性的时候就是undefined
  4. 把数组中的每一项作为一个对象的属性名和属性值
  5. var obj={1:1,2:2,3:3}
  6. 原理:如果对象属性中已经存在这个属性名,我们就把原数组中此项进行删除
  7. */
  8. function unique(ary){
  9. var obj={};
  10. for(var i=0;i<ary.length;i++){
  11. var item=ary[i];
  12. if(typeof (obj[item])!="undefined"){
  13. //如果此时对象的此属性已经有了,我们就应该删除数组中的那一项
  14. ary.splice(i,1);
  15. i--;
  16. continue;
  17. }
  18. obj[item]=item;
  19. }
  20. return ary;
  21. }
  22. var ary2=[1,2,1,3,3,2,3];
  23. var res=unique(ary2);
  24. console.log(res);

【优化方法】:对于数组塌陷,数组中后面所有的数字都要依次改变,这样比较耗性能,怎么优化呢?可以让后面的索引值不变,这样就可以省性能。

  • 把最后一项的值拿过来,占位到塌陷的此项
  • 把最后一项删除
  • 需要注意,此时最后一项也需要比较所以还需要i—;
  1. var ary=[1,2,3,2,3];
  2. var obj={};
  3. for(var i=0;i<ary.length;i++){
  4. var item=ary[i];
  5. if(typeof obj[item]!=="undefined"){
  6. // 把当前重复的项替换成最后一项
  7. ary[i]=ary[ary.length-1];
  8. // 最后一项都已经拿过来了,多余,所以删除掉
  9. ary.length--;
  10. // 此时占位的这一项(最后一项)还没有比较,所以需要i--,再重新比较一次
  11. i--;
  12. continue;
  13. }
  14. obj[item]=item;
  15. }
  16. console.log(ary);

方法三:indexOf

创建一个新数组,遍历原数组,如果新数组中没有那一项的话,就把它push进去

  1. /*
  2. var ary2=[1,2,1,3,3,2,3];
  3. var newAry=[];
  4. 把原数组中的每一项,只要在新数组中没存在过,我们就把它放进去,最后newAry就是咱们最终要的数组
  5. */
  6. function unique(ary){
  7. var newAry=[];
  8. for(var i=0;i<ary.length;i++){
  9. var item=ary[i];
  10. if(newAry.indexOf(item)==-1){
  11. newAry.push(item);
  12. }
  13. }
  14. return newAry;
  15. }
  16. var ary2=[1,2,1,3,3,2,3];
  17. var res=unique(ary2);
  18. console.log(res);

二、算法之冒泡排序

  1. /*
  2. 冒泡排序:
  3. 从小到大排序
  4. var ary=[8,2,1,5]
  5. 原理:依次拿出数组中的每一项给后面的一项做对比,如果当前项比后面的项大就交换位置
  6. 第一轮:[2,1,5,8] 经过一轮比较出现了最大数
  7. 第二轮:[1,5,2,8] 经过二轮比较得出倒数第2个数
  8. 第三轮:[1,5,2,8] 经过二轮比较得出倒数第3个数
  9. .... 总共四项,经过比三轮,已经得到了三个最大数了,最后一个自然就是最小数
  10. 【需要比的总轮数】:ary.length-1;
  11. 【每次需要比的次数】:ary.length-1-已经比较过的轮数
  12. 第一轮:4项两两比较需要比3次:ary.length-1
  13. 第二轮: 正常的ary.length-1-已经比较过的轮数
  14. */
  15. function sort(ary){
  16. // 需要比较的轮数
  17. for(var i=0;i<ary.length-1;i++){
  18. for(var j=0;j<ary.length-1-i;j++){
  19. var current=ary[j];
  20. var next=ary[j+1];
  21. if(ary[j]>ary[j+1]){
  22. // 让 ary[j]=ary[j+1]
  23. var temp=ary[j]
  24. ary[j]=ary[j+1];
  25. ary[j+1]=temp;
  26. }
  27. }
  28. }
  29. return ary;
  30. }
  31. var ary=[8,2,1,5];
  32. var res=sort(ary);

三、递归

自己调自己就是递归;

  1. function fn(num){
  2. fn(num-1)
  3. }
  4. fn(10)

打印1 到10

  1. // 打印1到10
  2. function fn(num){
  3. if(num>10){
  4. return
  5. }
  6. console.log(num);
  7. fn(num+1);
  8. }
  9. fn(1)

[练习题]:求一个1到100的所有数之和

答案一:

  1. /*
  2. 1到100中所有数之和
  3. */
  4. function total(star,end){
  5. var total=null;
  6. for(var i=star;i<=end;i++){
  7. total+=i;
  8. }
  9. return total;
  10. }
  11. var res=total(1,100);
  12. console.log(res);

答案二:递归

  1. function total(num){
  2. if(num>100){
  3. return 0;
  4. }
  5. return num+total(num+1);
  6. }
  7. total(1)

[练习题]:求1到100中同时能被2整除又能被3整除的所有数之和

答案:1

  1. /*
  2. 求1-100所有能被2整除又能被3整除的所有数之和
  3. */
  4. var total=null;
  5. for(var i=1;i<=100;i++){
  6. if(i%2==0&&i%3==0){
  7. total+=i;
  8. }
  9. }
  10. console.log(total);

递归

  1. function total(num){
  2. if(num>100){
  3. return 0;
  4. }
  5. if(num%2==0&&num%3==0){
  6. return num+total(num+1);
  7. }
  8. return total(num+1);
  9. }
  10. var res=total(1);

四、算法之快速排序

image.png

  1. /*
  2. 快速排序
  3. var ary=[12,15,14,13,16,11];
  4. 原理:先拿出中间项,然后把此项从数组中删除掉,让数组中的剩余项一一跟这个中间项做比较,新建两个左右数组,如果大的项就放到右盒子,如果小的项就放到左盒子
  5. [左盒子小]--中间项--[右盒子大]
  6. 依次再继续重复相同的步骤,把左盒子和右盒子都进行排序,直到出现空数组或者一项的时候停止
  7. */
  8. function quickSort(ary){
  9. if(ary.length<=1){
  10. return ary;
  11. }
  12. var centerIndex=Math.floor(ary.length/2);
  13. // 拿到中间项的同时,把中间项从数组中删除掉
  14. var centerValue=ary.splice(centerIndex,1)[0];
  15. // 新建两个数组:leftAry,rightAry;把ary中剩余的项,给中间项做对比,如果大项就放到右数组,小项就放到左数组.
  16. var leftAry=[],rightAry=[];
  17. for(var i=0;i<ary.length;i++){
  18. if(ary[i]<centerValue){
  19. leftAry.push(ary[i]);
  20. }else{
  21. rightAry.push(ary[i]);
  22. }
  23. }
  24. return quickSort(leftAry).concat(centerValue,quickSort(rightAry));
  25. }
  26. var ary=[12,15,14,13,16,11];
  27. var res=quickSort(ary);