Codewars刷题思路分享(JS)--------6~10

255 阅读5分钟

保持热爱,奔赴山海

ps. 我第一次学到的 js 方法,或是忘记的,亦或是容易忘记的方法,会记录在拓展里面

6. 开膛破肚的巨魔(Disemvowel Trolls)

描述

巨魔正在攻击您的评论部分! 处理这种情况的常见方法是从巨魔的评论中删除所有元音,从而消除威胁。 你的任务是编写一个函数,该函数接受一个字符串并返回一个删除所有元音的新字符串。

示例

字符串 “This website is for losers LOL!”   将变成   “Ths wbst s fr lsrs LL!”。

思路

首先想到的是字符串的 split() 方法,可以按指定方式将字符串分割成数组,然后再用数组的 join() 方法将数组重新连成字符串,可以将元音字母 “a, e, i, o, u” 存入一个数组,循环使用 split() 方法和 spilt() 方法。

代码

function disemvowel(str) {
    var parameter = ['a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U'];
    for(let i = 0; i < parameter.length; i ++) {
        str = (str.split(parameter[i])).join("");
    }
    return str;
  }

还可以优化

优化思路

使用字符串的 replace() 方法,用 "" 代替 a,e,i,o,u, 注意加全局标志gi,忽略大小写。

优化代码

function disemvowel(str) {
    return str.replace(/[aeiuo]/gi, '');
  }

拓展

  • js 中的 replace() 方法

    是一种正则表达式方法,用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串。

    语法: stringObj.replace(rgExp, replaceText)

    参数 reExp:可以是正则表达式对象(RegExp),也可以是字符串(string);
    参数 replaceText:替代查找到的字符串。

    g为全局标志; gi为全局标志,且忽略大小写

    没有全局标志时,只能匹配一次

7. 元音计数(Vowel Count)

描述

返回给定字符串中元音的数量(计数)。输入字符串将仅由小写字母和/或空格组成。

思路

说来也巧,刚做完前面一道获得删除所有元音的字符串,下一道题就是这个,故只需要获得删除元音后的新字符串,用传入的字符串长度减去新字符串长度,就获得了被删除的元音数,即传入字符串中的元音数。

代码

function getCount(str) {
    var newstr = str.replace(/[aeiou]/g, '');
    return str.length - newstr.length;
    // 可以把两句合在一起  return str.length - (str.replace(//[aeiou]/g, '')).length
    // 但是觉得分开写更容易懂一点hhh
  }

8. 等序词(Isograms)

描述

等序词是一个没有重复字母、连续或非连续字母的单词。实现一个函数,该函数确定仅包含字母的字符串是否为等序词。假设空字符串是等序词。忽略字母大小写。

第一种方法: 时间复杂度为O(n^2)

思路一

先要考虑特殊情况空字符串,所以先判断得到的字符串是否为空,若不是再进行下一步。这里忽略大小写字母,可以用 toUpperCase() 方法或者 toLowerCase() 方法将字符串全部转换为大写或者小写。 然后将字符串用 split() 方法转换成数组,再用两层 for 循环暴力破解就行了。

代码一

function isIsogram (str) { 
        if(str === '') {
            return true;
        }
        let newStr =str.toLowerCase();
        let arr = newStr.split('')
        for(i=0;i<arr.length;i++){
            for(j = i + 1; j < arr.length; j++) {
                if(arr[i] == arr[j]) {
                    return false;
                }
             }
        }
        return true;
    }

第二种方法:时间复杂度为O(nlogn)

思路二

前面的操作还是一样的,得到一个数组,但是后面两层 for 循环可以尝试着改成一层 for 循环,我们可以先用 sort() 方法给数组里面的元素排序,这样只需要比较数组中两个相邻元素是否相等就行了。

代码

function isIsogram(str) {
    if (str === '') {
        return true;
    }
    str = str.toLowerCase();
    arr = str.split("");
    arr.sort();       // ?  看是哪种排序算法   O(n^2)    O(nlogn)
    for(let i = 0; i < arr.length - 1; i ++) {
        if (arr[i] === arr[i + 1]) {
            return false;
        }
    }
    return true;
}

拓展

sort() 方法

可以用于对数组的元素进行排序,返回值是排好序的数组

默认情况是将数组元素转换为字符串,然后 按ASC码进行排序,

sort() 方法如果有参数,则参数必须是一个函数,而且该函数要接收两个参数,如果函数内返 返回值是正数,则第一个参数排在第二个参数前面; 如果函数内返回值是负数, 则第二个参 数排在第一个参数前面;如果返回值为0, 则按ASC码排序。

第三种方法:时间复杂度为O(n)

思路三

前面的操作还是一样的,得到一个数组,但是排序花的时间还是多了,我们可以把排序的方法也给省略,试着用空间换时间,用 hashMap{} 实现。

代码三

function isIsogram(str){
    if (str === '') {
        return true;
    }
    str = str.toLowerCase();
    let arr = str.split('');
    let obj = {}; // 空间的分配 
    for (let i = 0; i < str.length; i++) {
        let char = arr[i];
        if (obj[char] == 1) { // 重复出现               
        // 对象的属性的调用: 一般都是常量,用“对象.属性”, 但如果是变量,就用“对象[属性]”
            return false;
        } else {
            obj[char] = 1  // 第一次出现
        }
    }
    return true;
}

9. 连续重复次数最长的字符(Character with longest consecutive repetition)

描述

对于给定的字符串查找具有最长连续重复的字符,返回该字符和长度 ["s",l], 其中 s 为字符, l 为长度。如果有两个或多个字符相同,则按出现顺序返回第一个。对于空字符串返回:["", 0]

示例

input  "aaaabb"     =>     output   ["a", 4]
input  "bbbaaabaaaa"       =>    output     ["a",4]
input  "cbdeuuu900"      =>      output    ["u",3]
input  ""      =>    output   ["", 0]

思路

先考虑特殊情况,判断若是空字符串,直接返回["", 0],若不是再进行下一步。先将字符串用 split("") 分割成数组 arr,声明一个变量 char 用来存放重复次数最长的字符,char 初始值设置为 arr[0], 再声明一个 max 用来存放最长重复长度, 声明一个 a 来存放每次不相同的字符。用 for 循环遍历数组, 每次判断相邻两项是否相等,如果相等, 声明一个 char1 来存放这个相等的字符,令 a 加一 ,并判断 a 是否大于 max, 如果大于,说明此时有新的重复次数最长的字符出现, 将 a 的值存到 max, 将 char1 的值存到 char,否则不做操作。如果相邻两个元素不相等, 将 a 的值重置为1。

代码

function longestRepetition(s) {
    if (s === "") {
        return ["",0];
    }
    let sarr = s.split("");
    let char = sarr[0];
    let max = 1;
    var a = 1;
    for (let i = 0; i < sarr.length - 1; i ++) {
        if(sarr[i] !== sarr[i+1]) {
            a = 1;
        } else {    // 相等
            var char1 = sarr[i];
            a ++;
            if(a > max) {
                max = a;
                char = char1;
            }
        }
    }
    return [char,max];
  }

10. 字谜检测(Anagram Detection)

描述

字谜是重新排列单词字母以产生新单词的结果。如果给出两个参数是彼此的字谜,函数则返回 true, 否则返回 false

注意:字谜不区分大小写

思路

不区分大小写,故先将接收到的两个字符串用 toUpperCase() 方法或 toLowerCase() 方法转换为大写或小写,再将两个字符串用 split() 方法分割成数组,再用数组的 sort() 方法对两个数组进行排序,最后用 for循环,判断两个排好序的数组的每一项是否相同

代码

var isAnagram = function(test, original) {
    if (test.length !== original.length) {
        return false;
    }
    test = test.toLowerCase();
    original = original.toLowerCase();
    let arr1 = test.split("");
    let arr2 = original.split("");
    arr1 = arr1.sort();
    arr2 = arr2.sort();
    for(let i = 0; i < arr1.length; i ++) {
        if(arr1[i] !== arr2[i]) {
            return false;
        }
    }
    return true;
};