黑客等级Annagrams

时间:2017-06-01 23:17:33

标签: javascript

我正在尝试使用JavaScript解决此处描述的问题...

https://www.hackerrank.com/challenges/ctci-making-anagrams

我必须输出需要从两个字符串中删除的字母数,以便只有匹配的字母(比较两个字符串以匹配字母和总计不匹配的字母)

例如......

字符串a = cbe string b = abc

两个字符串之间唯一匹配的字母是两个c,所以我将删除4个字母(beab)。

我的代码有效,但它似乎可以保持超时。如果我下载单个测试用例实例,当变量a和b设置为大字符串时,我似乎失败了。如果我单独测试这些,我似乎得到正确的输出,但我仍然得到消息“由于超时终止”。

我认为某人为什么我的代码超时可能是显而易见的。我不确定这是解决问题的最优雅方式,但我很乐意让它发挥作用。任何帮助将不胜感激......

function main() {
    var a = readLine();
    var b = readLine();

    var arraya = a.split('');
    var arrayb = b.split('');

    var arraylengths = arraya.length + arrayb.length;

    //console.log(arraylengths); 

    if (arraya.length <= arrayb.length) {
        var shortestarray = arraya;
        var longestarray = arrayb;
    } else {
        var shortestarray = arrayb;
        var longestarray = arraya;
    }

    var subtract = 0;

    for (x = 0; x < shortestarray.length; x++) {

        var theletter = shortestarray[x];
        var thenumber = x;

        if (longestarray.indexOf(theletter, 0) > -1) {

            var index = longestarray.indexOf(theletter, 0);

            longestarray.splice(index, 1);

            subtract = subtract + 2;

        }
    }


    var total = arraylengths - subtract;

    console.log(total);
}

2 个答案:

答案 0 :(得分:0)

我建议你散列。使字符串键的字符及其出现次数值。对两个字符串执行相同的操作。之后取字符串1并将其每个字符的计数与字符串中相同字符的计数相匹配,然后计算相同字符出现次数的差异并删除该字符,直到差值变为0并计算出您多少次执行删除操作。

算法:

step 1: Let arr1[255]= an integer array for storing the count of string1[i]
        and initialized to zero

        ex: string1[i]='a',  then arr1[97]=1, because ASCII value of a is 97  
        and its count is 1. so we made hash table for arr1 where key is 
        ASCII value of character and value is its no of occurrences.

step 2: Now declare an another array of same type and same size for string 2

step 3: For i=0 to length(string1):
               do arr1[string1[i]]++;
step 4: For i=0 to length(string2):
               do arr2[string2[i]]++;

step 5: Declare an boolean char_status[255] array to check if the 
        character is visited or not during traversing and initialize it to 
        false

step 6: set count=0;

step 7: For i=0 to length(string1):
              if(char_status[string1[i]]==false):
                    count=count+abs(arr1[string1[i]]-arr2[string1[i]])
                    char_status[string1[i]]=true

step 8: For i=0 to length(string2):
             if(char_status[string2[i]]==false):
                     count=count+abs(arr1[string2[i]]-arr2[string2[i]])
                     char_status[string2[i]]=true

step 9: print count

我刚刚应用了这个算法并通过了所有测试用例。如果你有时间,你可以更多地改进这个算法。

答案 1 :(得分:0)

你的算法很好。它直截了当,易于理解。 您可以采取某些措施来提高代码的性能。

  1. 您不必两次计算indexOf操作。你可以减少到一个。

  2. splice操作是最昂贵的操作,因为JS引擎必须从数组中删除元素并重新分配所有元素的索引。 这里要注意的一点是,JS引擎会执行额外的步骤来更正数组的索引,这不是您的目的所必需的。因此,您可以安全地删除longestarray.splice(index, 1);并将其替换为delete longestarray[index]

  3. 这是一个代码片段,可以在不改变逻辑的情况下提高代码性能

    for (var x = 0; x < shortestarray.length; x++) {
        var theletter = shortestarray[x];    
        var thenumber = longestarray.indexOf(theletter, 0);   // <-- check only once 
        if (thenumber > -1) {
            var index = thenumber;
            delete longestarray[index]; // <-- less costlier than splice
            subtract = subtract + 2;
        }
    }
    

    注意:我不建议您对所有情况使用删除。它在这里很有用,因为在删除元素后你不会对数组元素做太多的事情。

    一切顺利。快乐编码