【问题标题】:understanding solution of Valid Anagram in javascript在javascript中理解Valid Anagram的解决方案
【发布时间】:2020-03-03 06:54:32
【问题描述】:

这是来自 LeetCode - 有效的字谜

给定两个字符串 s 和 t ,编写一个函数来确定 t 是否是 s 的变位词。
示例 1:
输入:s = "anagram", t = "nagaram"
输出:真
示例 2:

您可以假设该字符串仅包含小写字母。

跟进: 如果输入包含 unicode 字符怎么办?您将如何调整您的解决方案以适应这种情况?

下面这些代码我看不懂

  • result1[s.charCodeAt(i) - 97]++; --> ++ 是什么意思?
  • result2.length = 26; --> 26 代表什么?
  • result2.fill(0); --> 为什么用 0 填充?

请指教!

var isAnagram = function(s,t) {
    if (s.length !== t.length)
        result false;
    const result1 = [];
    result1.length = 26;
    result1.fill(0);

    const result2 = [];
    result2.length = 26;
    result2.fill(0);

    for (let i = 0; i < s.length; i++) {
        result1[s.charCodeAt(i) - 97]++;
        result2[t.charCodeAt(i) - 97]++;
    }

    for (let i = 0; i < result1.length; i++) {
        if (result1[i] !== result2[i]) {
            return false;
        }
    }
    return true;
};

【问题讨论】:

  • console.log(s[i], s.charCodeAt(i) - 97)

标签: javascript anagram


【解决方案1】:

这是我的解决方案版本。你甚至可以跳过最后的 join(),因为你仍然可以比较两个数组。

const isAnagram = function(s, t) {
  if (s.length !== t.length ) {
    return false;
    }
  if (s.split('').sort().join('') === t.split('').sort().join('')) {
    return true;
  } else {
    return false;
  }
};

【讨论】:

    【解决方案2】:

    那是写得有点糟糕的代码,让我们稍微改进一下,这样你的问题就会自动消失:

    var isAnagram = function(string1, string2) {
        if (string1.length !== string2.length)
            return false; // here was a typo: result false
    
        const alphabetLength = 26;
        // returns an array of zeros (empty counters), each one per alphabet letter
        const getAlphabetCounters = function() {
            const counters = [];
            counters.length = alphabetLength;
            counters.fill(0);
            return counters;
        }
        const countCharacter = function(c, counters) {
            // zero for a, 25 for z
            const position = c.charCodeAt(0) - 97;
            counters[position]++;
        }
    
        const counters1 = getAlphabetCounters();
        const counters2 = getAlphabetCounters();
    
        for (let i = 0; i < string1.length; i++) {
            countCharacter(string1[i], counters1);
            countCharacter(string2[i], counters2);
        }
    
        for (let i = 0; i < counters1.length; i++) {
            if (counters1[i] !== counters2[i]) {
                return false;
            }
        }
        return true;
    };
    

    但使用这样的“递减”方法可能会更好:

    var isAnagram = function(string1, string2) {
        if (string1.length !== string2.length)
            return false;
    
        let letters1 = string1.split('');
        let letters2 = string2.split('');
        for (let letter of letters1) {
            let position = letters2.indexOf(letter);
            if(position == -1)
                return false;
            letters2.splice(position, 1);
        }
        return true;
    };
    

    或者如果人们关心长字符串的性能,那么对其中的字母进行排序并直接比较将是一种方法。

    【讨论】:

      【解决方案3】:

      ++ 是自增运算符。它可以是前置的 (++i) 或后置的 (i++)。在这种情况下,它是后固定的:result1[s.charCodeAt(i) - 97]++,因此它将增加 result1[s.charCodeAt(i) - 97] 的值。

      26 只是字母表中的字母数(从 a 到 z)。

      代码正在初始化两个数组并fill用 0 对它们进行初始化,以便它可以将数组元素用作计数器。数组中的每个索引代表字母表中的一个字母,并存储该字母在字符串中出现的次数。

      【讨论】:

        【解决方案4】:

        具有最少的数组函数和单个 for 循环

            function anagram(str1, str2){
                var isAnagram = true;
                if(str1.length != str2.length){
                    isAnagram = false;
                }else{
                    for(var i=0; i<str1.length;i++) {       
                        if(!str2.includes(str1[i])){
                            isAnagram = false;
                        }   
                    }
                }
        
                if(isAnagram){
                    console.log('string is anagram');
                }else{
                    console.log('string is not anagram');
                }
            }
        
            anagram('READ', 'DEAR');
        

        【讨论】:

          【解决方案5】:
          var isAnagram = function(s, t) {
            let sArr = s.split('');
            let tArr = t.split('');
          
            sArr.sort();
            let newS = sArr.join('');
          
            tArr.sort();
            let newT = tArr.join('');
          
            return newS === newT; 
          };
          

          【讨论】:

          • 欢迎来到 SO!如果您解释一下您的回答让其他人觉得它更有帮助,那就太好了。
          【解决方案6】:

          只需一行代码即可完成

          const isAnagram = (s,t) => ( [...s].sort().join('') === [...t].sort().join(''))
          
          console.log( isAnagram('anagram', 'nagaram') )  // true
          console.log( isAnagram('anagram', 'xxx') )     // false

          但您的问题还要求管理所有 utf8 字符,我将其解释为必须消除 diacriticfor which there is an answer here

          我做了一点改动,只保留字母(不包括空格和其他标点符号),以便也能够处理几个单词的字谜:

          const letters = str => str.toLowerCase().normalize("NFD").replace(/[^a-z]/g, '')
          

          最终解决方案:

          const letters = str => str.toLowerCase().normalize("NFD").replace(/[^a-z]/g, '')
            ,   isAnagram = (s,t) => ( [...letters(s)].sort().join('') === [...letters(t)].sort().join(''))
            ;
          const anagrams =  // from wikipedia
            [ { s: "evil"
              , t: "vile"                     }
            , { s: "New York Times"
              , t: "monkeys write"            }
            , { s: "William Shakespeare"
              , t: "I am a weakish speller"   }
            , { s: "Le commandant Cousteau"
              , t: "Tout commença dans l'eau" }  // with diacritic ( French )
            , { s: "La crise économique"
              , t: "Le scénario comique"      }
            , { s: "Question sans réponse"
              , t: "Enquêtons sans espoir"    }
            , { s: "Chauve-souris"
              , t: "Souche à virus"           }
            ]
          
          for (let {s,t} of anagrams )
              console.log(`_${s}_, _${t}_ -> `, isAnagram(s,t))
          .as-console-wrapper { max-height: 100% !important; top: 0; }

          【讨论】:

            猜你喜欢
            • 2021-03-20
            • 2016-03-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-03-06
            • 1970-01-01
            • 2012-02-10
            • 1970-01-01
            相关资源
            最近更新 更多