JS基础算法

784 阅读2分钟

学习过程中遇到的一些基础算法,总结下来,供自己复习和大家参考。

字符串类

题目1:反转字符串中每个单词的字符顺序,仍保留空格和单词的初始顺序。每个单词由单个空格分隔,并且不会有任何额外的空格。
输入:“Let's take leetCode”,
输出:“s'teL ekat edoCteel”
考查知识点:
String.prototype.split
String.prototype.match
Array.prototype.map
Array.prototype.reverse
Array.prototype.join

实现:

function (str) {
    let arr =str.split(' ');  
    //数组遍历,然后对每个元素反转
    let result = arr.map(item =>{
       return item.split('').reverse().join('');
    })
    return result.join(' ')
}

那么优化优化?? 代码是不是更优雅了?

function (str) {
    //数组遍历,然后对每个元素反转
    return str.split(' ').map(item =>{
       return item.split('').reverse().join('');
    }).join(' ')
}

能用正则吗?

function (str) {
    //数组遍历,然后对每个元素反转
    return str.split(/\s/g).map(item =>{
       return item.split('').reverse().join('');
    }).join(' ')
}
function (str) {
    //数组遍历,然后对每个元素反转
    return str.match(/[\w']+/g).map(item => {
       return item.split('').reverse().join('');
    }).join(' ')
}

题目2: 给定字符串s,计算具有相同数量0和1的非空(连续)子字符串的数量,并且这些子字符串中所有0和1都是组合在一起的。
输入:“00110011”
输出:6
解释:“0011”、 “01”、“1100”、“10”、“0011”和“01”
这道题难了点,怎么做呢?
解题思路:寻找规律并实现,这也是算法的本质<=观察输入与输出,寻找突破点<= 实现是程序+数据结构的结合体
开始: 找规律咯 看图看图看图!

写代码:

export default (str) => {
  // 建立数据结构,堆栈,保存数据
  let r = []
  // 给定任意子输入都返回第一个符合条件的子串
  let match = (str) => {
    let j = str.match(/^(0+|1+)/)[0]
    let o = (j[0] ^ 1).toString().repeat(j.length)
    let reg = new RegExp(`^(${j}${o})`)
    if (reg.test(str)) {
      return RegExp.$1
    } else {
      return ''
    }
  }
  // 通过for循环控制程序运行的流程
  for (let i = 0, len = str.length - 1; i < len; i++) {
    let sub = match(str.slice(i))
    if (sub) {
      r.push(sub)
    }
  }
  return r
}

测试:

import subStr from '../../code/string/lesson2'
test('subStr(00110011)', () => {
  expect(subStr('00110011')).toEqual(['0011', '01', '1100', '10', '0011', '01'])
})
test('subStr(10101)', () => {
  expect(subStr('10101')).toEqual(['10', '01', '10', '01'])
})

知识点:
arrayObject.splice(index,howmany,item1,.....,itemX) index:插入位置 howmany:删除个数
arrayObject.slice(start,end)从数组中返回选定元素。返回一个新数组,包含从 start 到 end (不包括该元素)的 的元素。
stringObject.match(searchvalue) / stringObject.match(regexp)可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配。

数组类

题目3: 电话号码的字母组合: LeetCode上面的题,电话号码数字与字母之间的映射如图


找规律啦 看图看图看图

找到规律了么?现在上代码了,对比一下

function getLetterCom(str) {
    //与电话号码的映射
    let map = ['',1,'abc','def','ghi','jkl','mno','pqrs','tuv','wxyz']
    //输入字符串分隔变成数组,234=>[2,3,4]
    let num =str.split('')
    //输入数字字符串的对应字母数组
    let code=[];
    num.forEach(item=>{
        if (map[item]){
            code.push(map[item])
        }
    })
    let comb = (arr) =>{
        //临时变量,存放中间运算结果
        let tmp=[]
        for(let i=0; i<arr[0].length;i++){
            for(let j=0;j<arr[1].length;j++){
                tmp.push(`${arr[0][i]}${arr[1][j]}`)
            }
        }
        arr.splice(0,2,tmp);
        if(arr.length>1){
            comb(arr);
        }else{
            return tmp;
        }
        return arr[0];
        
    }
    return comb(code);
}
//启动代码测试
getLetterCom('234'); 

题目4: 卡牌分组
给定一副牌,每张牌都有一个整数。此时,你需要选定一个数字X,按规则分成1或多组;规则如下:
·每组都有X张牌,
·组内所有的牌都写相同的整数。
·X>=2,返回true。
示例 输入:[1,2,3,1,2,2,2,3]
输出: true
解释:可行分组:[1,1],[2,2],[2,2],[3,3]
思路:排序并获得最小分组的数值长度,然后分类判断即可。 代码:

//拆分数组,并获取最小数组长度
function cardGroup(arr) {
    //排序
    if (arr.length < 2) {
        return false;
    }
    arr.sort((a, b) => a - b);
    //最小个数
    let min = Number.MAX_SAFE_INTEGER;
    let dst = [];
    let result = true;
    for (let i = 0; i < arr.length; i++) {
        tmp = []
        tmp.push(arr[i]);
        for (let j = i + 1; j < arr.length - 1; j++) {
            if (arr[i] === arr[j]) {
                tmp.push(arr[j])
            } else {
                if (min > tmp.length) {
                    min = tmp.length;
                }
                dst.push([].concat(tmp))
                //清空数组
                tmp.length = 0
                //跳过相同数据
                i = j;
                break;
            }
        }
    }
    //判断,方式:取模
    if (min !== 1) {
        dst.every(item => {
            if (item.length % min !== 0) {
                result = false;
                return false;
            }
        })
        return result;
    }else{
        return false;
    }
}
arr = [1, 2, 2, 3]
cardGroup(arr);  

正则类

题目5: 重复的子字符串
给定一个非空字符串,判断是否可以由其子串重复多次构成,字符串只有小写字母,长度不超过10000.

export default (str) => {
    var reg =/^(\w+)\1+$/
    return reg.test(str)
}