JS常见的算法

1 判断一个单词是否是回文?

回文是指把相同的词汇或句子,在下文中调换位置或颠倒过来,产生首尾回环的情趣,叫做回文,也叫回环。比如 mamam redivider .
很多人拿到这样的题目非常容易想到用for 将字符串颠倒字母顺序然后匹配就行了。其实重要的考察的就是对于reverse的实现。其实我们可以利用现成的函数,将字符串转换成数组,这个思路很重要,我们可以拥有更多的自由度去进行字符串的一些操作。

function checkPalindrom(str) {  
    return str == str.split('').reverse().join('');
}

2 去掉一组整型数组重复的值

比如 输入: [1,13,24,11,11,14,1,2], 输出: [1,13,24,11,14,2] ,需要去掉重复的11 和 1 这两个元素。

主要考察个人对Object的使用,利用key来进行筛选。

let unique = function(arr) {  
  let hashTable = {};
  let data = [];
  for(let i=0,l=arr.length;i
//ES6方法:
function unique(arr) {
  return Array.from(new Set(arr))
}
module.exports = unique;

3 统计一个字符串出现最多的字母

给出一段英文连续的英文字符窜,找出重复出现次数最多的字母
比如: 输入:afjghdfraaaasdenas 输出 : a
前面出现过去重的算法,这里需要是统计重复次数。

function findMaxDuplicateChar(str) {  
  if(str.length == 1) {
    return str;
  }
  let charObj = {};
  for(let i=0;i= maxValue) {
      maxChar = k;
      maxValue = charObj[k];
    }
  }
  return maxChar;
}
module.exports = findMaxDuplicateChar;

    var str = "zhufengpeixunyangfanqihang";
    //把每一个字母出现的次数进行统计
    var obj = {};
    str.replace(/[a-z]/gi, function () {
        var a = arguments[0];
        if (obj[a] >= 1) {
            obj[a] = obj[a] + 1;
        } else {
            obj[a] = 1;
        }
    });
    //用假设法,获取最多出现的次数
    var max = 0;
    for (var key in obj) {
        var cur = obj[key];
        max = cur > max ? cur : max;
    }
    //把最多出现次数的字母放到数组中
    var ary = [];
    for (var key in obj) {
        if (obj[key] === max) {
            ary.push(key);
        }
    }
    console.log(ary);
    console.log(max);

4 排序算法

如果说到算法题目的话,应该大多都是比较开放的题目,不限定算法的实现,但是一定要求掌握其中的几种,所以冒泡排序,这种较为基础并且便于理解记忆的算法一定需要熟记于心。冒泡排序算法就是依次比较大小,小的的大的进行位置上的交换。

function bubbleSort(arr) {  
    for(let i = 0,l=arr.length;iarr[j]) {
                let tem = arr[i];
                arr[i] = arr[j];
                arr[j] = tem;
            }
        }
    }
    return arr;
}
module.exports = bubbleSort;

除了冒泡排序外,其实还有很多诸如 (插入排序、快速排序、希尔排序)等。每一种排序算法都有各自的特点。全部掌握也不需要,但是心底一定要熟悉几种算法。 比如快速排序,其效率很高,而其基本原理如图(来自wiki):

算法参考某个元素值,将小于它的值,放到左数组中,大于它的值的元素就放到右数组中,然后递归进行上一次左右数组的操作,返回合并的数组就是已经排好顺序的数组了。

//快速排序
function quickSort(arr) {
    if(arr.length<=1) {
        return arr;
    }
    let leftArr = [];
    let rightArr = [];
    let q = arr[0];
    for(let i = 1,l=arr.length; iq) {
            rightArr.push(arr[i]);
        }else{
            leftArr.push(arr[i]);
        }
    }
    return [].concat(quickSort(leftArr),[q],quickSort(rightArr));
}
module.exports = quickSort;
//插入排序
 function insertSort(arr) {
        var len =arr.length;
        for (var i=1;i=0 && arr[j]>temp) {  //在已排序好的队列中从后向前扫描
                    arr[j+1]=arr[j]; //已排序的元素大于新元素,将该元素移到一下个位置
                    j--;
                }
            arr[j+1]=temp;
        }
        return arr
}
module.exports = insertSort;
//希尔排序
function shellSort(arr) {
  for(let gap = Math.floor(arr.length/2); gap > 0; gap = Math.floor(gap/2)) {
    // 内层循环与插入排序的写法基本一致,只是每次移动的步长变为 gap
    for(let i = gap; i < arr.length; i++) {
      let j = i;
      let temp = arr[j];
      for(; j> 0; j -= gap) {
        if(temp >= arr[j-gap]) {
          break;
        }
        arr[j] = arr[j-gap];
      }
      arr[j] = temp;
    }
  }
  return arr;
}
module.exports = shellSort;

几种排序算法以及性能比较

5 不借助临时变量,进行两个整数的交换

举例:输入 a = 2, b = 4 输出 a = 4, b =2
这种问题非常巧妙,需要大家跳出惯有的思维,利用 a , b进行置换。
主要是利用 + - 去进行运算,类似 a = a + ( b - a) 实际上等同于最后 的 a = b;

function swap(a , b) {  
  b = b - a;
  a = a + b;
  b = a - b;
  return [a,b];
}
module.exports = swap;

7 找出下列正数组的最大差值

比如: 输入 [10,5,11,7,8,9] 输出 6
这是通过一道题目去测试对于基本的数组的最大值的查找,很明显我们知道,最大差值肯定是一个数组中最大值与最小值的差。

function getMaxProfit(arr) {
    var minPrice = arr[0];
    var maxProfit = 0;
    for (var i = 0; i < arr.length; i++) {
        var currentPrice = arr[i];
        minPrice = Math.min(minPrice, currentPrice);
        var potentialProfit = currentPrice - minPrice;
        maxProfit = Math.max(maxProfit, potentialProfit);
    }
    return maxProfit;
}
function getMaxProfit(arr){
  var min = arr[0],
      max = arr[0];
  for(var i = 0; i < arr.length; i++){
    if(arr[i] < min) min = arr[i];
    if(arr[i] > max) max = arr[i];
  }
  return max - min;
}

8 随机生成指定长度的字符串

实现一个算法,随机生成指制定长度的字符窜。
比如:给定 长度 8 输出 4ldkfg9j

function randomString(n) {  
  let str = 'abcdefghijklmnopqrstuvwxyz9876543210';
  let tmp = '',
      i = 0,
      l = str.length;
  for (i = 0; i < n; i++) {
    tmp += str.charAt(Math.floor(Math.random() * l));
  }
  return tmp;
}
module.exports = randomString;

9 如何将浮点数左边的数每三位添加逗号

//var num='1200000.11';
function numberFormat(num){
    return num && num.toString().replace(/(\d)(?=(\d{3})+\.)/g,function($1,$2){
        return $2 + ',';
    })
}
module.exports = numberFormat;

10 编写一个函数fn(Number n),将数字转为大写输出,如输入123,输出一百二十三

function fn(n) {
    if (!/^([1-9]\d*)/.test(n)) {
        return '非法数据';
    }
    var unit = '千百十亿千百十万千百十个';
    if (n.length > unit.length) {
        return '数据过长';
    }
    var newStr = '';
    var nlength = n.length;
    unit = unit.substr(unit.length - nlength);
    for (var i = 0; i < nlength; i++) {
        newStr += '零一二三四五六七八九'.charAt(n[i]) + unit.charAt(i);
    }
    newStr = newStr.substr(0, newStr.length - 1);
    newStr = newStr.replace(/零(千|百|十)/g, '零').replace(/(零)+/g, '零').replace(/零(亿|万)/g, '$1');
    return newStr;
}
console.log(fn('205402002103'));

11 不确定数量的数组遍历组合算法

好吧,解释下这题。这题在现实中确实会用到。尤其是做商城网站时,sku的算法真的经常会遇到。
这题的意思就是说。相当于说[1,2,3],[4,5]。。。。的不确定个数的数组进行遍历组合,组成[[1,4],[1,5],[2,4],[2,5],[3,4],[3,5]]这样。然后数组越多,组出来就肯定越多。
那怎么做的,我上网查了一些相关算法都没找到好的,然后我就自己写。可能还是会有点毛病,大家将就看。
有写的更好的欢迎评论教我一下。

function group(arr, re) {
    if (arr.length <= 0) {
        return re;
    }
    if (!re) {
        var arr = arr.slice();
        var re = arr.shift();
        return group(arr, re);
    } else {
        var now = arr.shift();
        var newre = [];
        for (var j = 0; j < now.length; j++) {
            for (var k = 0; k < re.length; k++) {
                var temp = [];
                if (re[k] instanceof Array) {
                    temp = re[k];
                } else {
                    temp.push(re[k]);
                }
                newre.push(temp.concat(now[j]));
            }
        }
        return group(arr, newre);
    }
}
var arr = [['a', 'b', 'c'], ['e', 'd', 'f'], ['h', 'i'], ['j', 'k', 'l', 'm']];
// var arr = [['a','b','c'],['e','d','f'],['h','i']];
// console.log(arr);
var result = group(arr);
console.log(result);

12 翻转字符串

思路一:反向遍历字符串

function reverseString(str){
  var tmp = '';
  for(var i=str.length-1; i>=0; i--)
    tmp += str[i];
  return tmp
}

思路二:转化成array操作

function reverseString(str){
  var arr = str.split("");
  var i = 0,j = arr.length-1;
  while(i

13 猴子第一天摘下若干个桃子,当即吃掉一半,不过瘾,又多吃了一个,第二天早上又将剩下的桃子吃掉一半,又多吃了一个,以后每天早上都吃掉剩下桃子的一半零一个,到第十天早上的时候,发现只剩下一个桃子了,问猴子第一天摘下多少个桃子?

function peach(day){
     var sum=1;
    for(var i=0;i

14 输入一个字符串,打印该字符串中字符的所有排列(这里的思路是递归)

//这里重复的也列出来了有兴趣的可以再写下去重
 var perm = function(s) {
    var result = [];
    if (s.length <= 1) {
      return [s];
    } else {
      for (var i = 0; i < s.length; i++) {
        var c = s[i];
        var newStr = s.slice(0, i) + s.slice(i + 1, s.length);
        var l = perm(newStr);
           
        for (var j = 0; j < l.length; j++) {
          var tmp = c + l[j];
          result.push(tmp);
        }
      }
    }
    return result;
  };
console.log(perm('121'));

15 二分法查找 js 算法

二分法查找算法:
采用二分法查找时,数据需是排好序的。
主要思想是:(设查找的数组区间为array[s, e])
(1)确定该区间的中间位置m
(2)将查找的值T与array[m]比较,若相等,查找成功返回此位置;否则确定新的查找区域,继续二分查找。
区域确定如下:
这里设array从小到大排列,
array[m]>T由数组的有序性可知array[m,……,e]>T;
故新的区间为array[s,……,m-1],
类似上面查找区间array[s,……,m-1]。
每一次查找与中间值比较,判断是否查找成功,不成功当前查找区间缩小一半,循环查找,即可。
时间复杂度:O(log2n)。

let arr = [0, 1, 2, 4, 5, 6, 7, 8];
let arr2 = [88, 77, 66, 55, 44, 33, 22, 11];
BinarySearch(arr2, 77);
BinarySearch(arr, 2);
function BinarySearch(arr, target) {
    let s = 0;
    let e = arr.length - 1;
    let m = Math.floor((s + e) / 2);
    let sortTag = arr[s] <= arr[e];//确定排序顺序

    while (s < e && arr[m] !== target) {
        if (arr[m] > target) {
            sortTag && (e = m - 1);
            !sortTag && (s = m + 1);
        } else {
            !sortTag && (e = m - 1);
            sortTag && (s = m + 1);
        }
        m = Math.floor((s + e) / 2);
    }

    if (arr[m] == target) {
        console.log('找到了,位置%s', m);
        return m;
    } else {
        console.log('没找到');
        return -1;
    }
}

16、斐波那契数列

斐波那契数列的排列是:1,1,2,3,5,8,13,21,34,55,89,144……

function getFib(n){
   let fibarr =[];
   let  i=0;
   while(i

17、找到提供的句子中最长的单词,并计算它的长度。

注意:函数的返回值应该是一个数字。

function findLongestWord(str) {
//转化成数组
  var astr=str.split( " " ); 
//对数组中每个元素的字符串长度进行比较,按照字符串长度由大至小排列数组顺序。
  var bstr=astr.sort(function(a,b){
    return b.length-a.length;
  });
//取出数组中第一个元素(也就是最大长度的字符串)
  var lenMax= bstr[0].length;
//返回长度值
  return lenMax;
}

findLongestWord("The quick brown fox jumped over the lazy dog");
//结果:6

18、确保字符串的每个单词首字母都大写,其余部分小写。

function titleCase(str) {
  var astr=str.toLowerCase().split(" ");
  for(var i=0 ; i

19、如果给定的字符串是回文,返回true,反之,返回false。

// 如果一个字符串忽略标点符号、大小写和空格,正着读和反着读一模一样,那么这个字符串就是palindrome(回文)。
// 注意需要去掉字符串多余的标点符号和空格,然后把字符串转化成小写来验证此字符串是否为回文。

//方式一:
function palindrome(str) {
  astr=str.replace(/[^0-9A-Za-z]/g,'').toLowerCase();
  bstr=astr.split("").reverse().join("");
  if(astr===bstr){
    return true;
  }else{
    return false;
  }
}
var is_true=palindrome("eye");
console.log(is_true);

//方式二:
//正则表达式还可以是:
var str="eye";
astr=str.replace(/[\ |\~|\`|\!|\@|\#|\$|\%|\^|\&|\*|\(|\)|\-|\_|\+|\=|\||\\|\[|\]|\{|\}|\;|\:|\"|\'|\,|\<|\.|\>|\/|\?]/g,"").toLowerCase();
console.log(astr);

20、右边大数组中包含了4个小数组,分别找到每个小数组中的最大值,然后把它们串联起来,形成一个新数组。

function largestOfFour(arr) {
  var newArr=[];
  for(i=0;i

21、检查一个字符串(str)是否以指定的字符串(target)结尾。

如果是,返回true;如果不是,返回false。

function confirmEnding(str, target) {
  var len=target.length;
  var astr=str.substr(-len);
  if(astr===target){
    return true;
  }else{
    return false;
  }
}
confirmEnding("Bastian", "n");

//语法:substr()方法返回字符串中从指定位置开始到指定长度的子字符串
  str.slice(beginSlice[,endSlice]);

22、截断一个字符串!

如果字符串的长度比指定的参数num长,则把多余的部分用...来表示。

切记,插入到字符串尾部的三个点号也会计入字符串的长度。

但是,如果指定的参数num小于或等于3,则添加的三个点号不会计入字符串的长度。
function truncate(str, num) {
  var len=str.length;
  var astr=str.slice(0,num-3);
  var bstr=str.slice(0,num);
  if(len>num){
    if(num<=3){
      return bstr+'...';
    }else{
      return astr+'...';
    }
  }else{
    return str;
  }
}

truncate("A-tisket a-tasket A green and yellow basket", 11);
//结果:A-tisket...
//运用的语法:
slice()
提取字符串的一部分,并返回这个新的字符串;
  str.slice(beginSlice[,endSlice]);


23、把一个数组arr按照指定的数组大小size分割成若干个数组块。

例如:chunk([1,2,3,4],2)=[[1,2],[3,4]];
chunk([1,2,3,4,5],2)=[[1,2],[3,4],[5]];

function chunk(arr, size) {
  var newarr=[];
  for(var i=0;i

24、如果数组第一个字符串元素包含了第二个字符串元素的所有字符,函数返回true。

举例,["hello", "Hello"]应该返回true,因为在忽略大小写的情况下,第二个字符串的所有字符都可以在第一个字符串找到。
function mutation(arr) {
  var astr=arr[0].toLowerCase();
  var bstr=arr[1].toLowerCase();
  for(var i=0;i

参数
searchValue:一个字符串表示被查找的值。
fromIndex:可选 表示调用该方法的字符串中开始查找的位置。可以是任意整数。默认值为 0。如果 fromIndex < 0 则查找整个字符串(如同传进了 0)。如果 fromIndex >= str.length,则该方法返回 -1,除非被查找的字符串是一个空字符串,此时返回 str.length。
区分大小写 indexOf 方法区分大小写。例如,下面的表达式返回 -1:
"Blue Whale".indexOf("blue") // returns -1
检测是否存在某字符串 当检测某个字符串是否存在于另一个字符串中时,可使用下面的方法:
"Blue Whale".indexOf("Blue") !== -1; // true
"Blue Whale".indexOf("Bloe") !== -1; // false

25、删除数组中的所有假值。

function bouncer(arr) {
  function isBigEnough(element) {
    if(element!==false || element!==null || element!==0 || element!=="" || element!==undefined || element!==NaN){
      return element;
    }
  }
  var filtered =arr.filter(isBigEnough);
  return filtered;
}

bouncer([7, "ate", "", false, 9]);

filter()
方法使用指定的函数测试所有元素,并创建一个包含所有通过测试的元素的新数组
var new_arrary = arr.filter(callback[, thisArg])

26、找到你的另一半

都说优秀的程序员擅长面向对象编程,但却经常找不到另一半,这是为什么呢?因为你总是把自己局限成为一个程序员,没有打开自己的思维。

这是一个社群的时代啊,在这里你应该找到与你有相同价值观但又互补的另一半。

譬如:你编程能力强,估值11分,如果以20分为最佳情侣来计算,你应该找一个设计能力强,估值为9分的女生。

那么当你遇到一个设计能力为9分的女生,千万别犹豫,大胆去表白。千万别以为后面的瓜比前面的甜哦。

举个例子:有一个能力数组[7,9,11,13,15],按照最佳组合值为20来计算,只有7+13和9+11两种组合。而7在数组的索引为0,13在数组的索引为3,9在数组的索引为1,11在数组的索引为2。

所以我们说函数:pairwise([7,9,11,13,15],20) 的返回值应该是0+3+1+2的和,即6。

pairwise([1, 4, 2, 3, 0, 5], 7) 应该返回 11.
pairwise([1, 3, 2, 4], 4) 应该返回 1.
pairwise([1, 1, 1], 2) 应该返回 1.
pairwise([0, 0, 0, 0, 1, 1], 1) 应该返回 10.
pairwise([], 100) 应该返回 0.

function pairwise(arr, arg) {
  var sum=0;
  for(var i=0;i

你可能感兴趣的:(JS常见的算法)