带O(n)时间和1个额外空间的有效字谜,不是256

时间:2018-08-08 14:12:17

标签: algorithm

我试图找到一种解决方案,用于以O(n)时间(1个空间)验证字谜。 我想出了按位方法。

anagram(s,t)决定两个字符串是否为anagram。

示例

Given s = "abcd", t = "dcab", return true.  
Given s = "ab", t = "ab", return true.  
Given s = "ab", t = "ac", return false.  

时间:n,空格256 我已经有256个空间版本。

    public boolean anagram(String s, String t) {

    if(s == null || t == null){
        return false;
    }
    if(s.length() != t.length()){
        return false;
    }

    int n = s.length();
    int[] count = new int[256];

    for(int i = 0; i < n; i++){
        count[s.charAt(i)]++;
        count[t.charAt(i)]--;
    }

    for(int i : count){
        if(i != 0){
            return false;
        }
    }

    return true;

}

我的按位解决方案的代码

它无法通过此测试用例:

s: "az"  ,  t: "by"  

我知道我的代码是错误的,我想找出O(n)时间和1个空间解,不进行排序,这将花费O(nlgn)时间。

以下代码不正确。

时间:n,空格1

 public boolean anagram(String s, String t) {

    if(s == null || t == null || s.length() != t.length()){
        return false;
    }

    int n = s.length();
    int x = s.charAt(0) ^ t.charAt(0);

    for(int i = 1; i < n; i++){
        x ^= s.charAt(i);
        x ^= t.charAt(i);
    }

    return x == 0;
}

我正在尝试仅增加1个额外空间。 也许没有办法解决。

3 个答案:

答案 0 :(得分:1)

public boolean anagram(String s, String t) {

    if(s == null || t == null || s.length() != t.length()){
        return false;
    }

    int[] hash = new int[256];// all have 0 by default

    for(int i=s.length()-1;i>=0;--i){
        hash[(int)s.charAt(i)]++;
        hash[(int)t.charAt(i)]--;
    }

    for(int i=0;i<256;++i){
        if(hash[i] != 0) return false;
    }

    return true;
}

答案 1 :(得分:0)

s:“ az”,t:“ by”

x = a ^ b = 3;

则x = 3 ^ z = 121; 则y = 121 ^ y = 0;因为y的ascii值为121。

我认为您必须比较用于字谜的单词是不正确的。请重新访问。

我宁愿对所有字符使用带有count的数组。如果您知道字符串输入仅限于字母,则使用大小为26的数组。但是,如果输入可以是任何字符,则使用大小为256的数组。

这样,复杂度将保持O(n)时间和O(1)空间。

答案 2 :(得分:0)

检测字谜的有效方法是对字母进行排序并比较排序后的单词是否相等。

鉴于(大概)单词的短长度和字母的短大小,可能有不同的选择(直接选择排序,直接插入排序,合并排序,计数排序,基数排序,针对小尺寸进行了优化)。

可能的微观优化是并行执行两种排序,并在部分排序的单词之间出现差异时立即得出结论。