Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String 谷歌访谈:寻找字符串之间的疯狂距离_String_Algorithm - Fatal编程技术网

String 谷歌访谈:寻找字符串之间的疯狂距离

String 谷歌访谈:寻找字符串之间的疯狂距离,string,algorithm,String,Algorithm,这个问题是在谷歌面试时问我的。我可以做它O(n*n)。。。我能在更好的时间做吗。 字符串只能由1和0组成 定义: X&Y是由0或1组成的字符串 D(X,Y)=从X和Y两个字符串中删除开始时常见的内容。然后从两个字符串中添加剩余长度 例如 D(11111000)=只有第一个字母是常见的。所以剩下的字符串是111&000。因此,结果length(“111”)和length(“000”)=3+3=6 D(1011100)=只有前两个字母是通用的。所以剩下的字符串是01&100。因此,结果length(

这个问题是在谷歌面试时问我的。我可以做它O(n*n)。。。我能在更好的时间做吗。 字符串只能由1和0组成

定义:

X&Y是由0或1组成的字符串

D(X,Y)
=从X和Y两个字符串中删除开始时常见的内容。然后从两个字符串中添加剩余长度

例如

D(11111000)
=只有第一个字母是常见的。所以剩下的字符串是
111
&
000
。因此,结果
length(“111”)
length(“000”)
=3+3=6

D(1011100)
=只有前两个字母是通用的。所以剩下的字符串是
01
&
100
。因此,结果
length(“01”)
length(“100”)
=2+3=5

很明显,我们发现这样一个疯狂的距离是线性的。O(m)

现在的问题是

给定n个输入,比如说like

1111
1000
101
1100
找出可能的最大疯狂距离

n是输入字符串的数目。 m是任何输入字符串的最大长度

O(n2*m)的解非常简单。可以用更好的方法吗?
假设m是固定的。我们能用比O(n^2)更好的方法来做这件事吗

将字符串放入树中,其中0表示向左,1表示向右。比如说

1111
1000
101
1100
结果会变成一棵树

        Root
             1
          0     1
         0 1*  0  1
        0*    0*    1*
其中*表示元素结束于此。构建此树显然需要
O(nm)

现在我们必须找到(两个节点之间的最长路径,与“疯狂距离”相同)。这里提出的优化算法只命中树中的每个节点一次。最多有
min(n m,2^m)
这样的节点

因此,如果
nm<2^m
,则该算法是
O(nm)

如果
nm>2^m
(我们必须重复输入),那么从第一步开始,算法仍然是
O(nm)


这也适用于带有通用字母表的字符串;对于带有
k
字母的字母表,构建一个
k
三元树,在这种情况下,运行时间仍然是O(nm),尽管它占用的内存是
k
的两倍。

我认为,通过创建一个二叉树,字符串中的每一位都对路径(0左,1右)进行编码,在O(nm)时间内就可以做到这一点。然后找到树节点之间的最大距离。

这是我的解决方案,我认为它是有效的:

  • 从所有字符串创建二叉树。树的构造方式如下: 在每一轮中,选择一个字符串并将其添加到树中。因此,对于您的示例,树将是:

                      <root>
              <1>            <empty>
     <1>            <0>
    
    
    

  • 因此,从根到叶的每条路径将表示一个字符串

  • 现在每两片叶子之间的距离就是两条线之间的距离。要找到疯狂的距离,你必须找到这个图的直径,你可以通过dfs或bfs轻松地找到它
  • 该算法的总复杂度为: O(n*m)+O(n*m)=O(n*m)。

    要在O(nm)中得到答案,只需遍历所有字符串的字符(这是一个O(n)操作)。我们将最多比较m个字符,因此这将在O(m)处完成。这给出了总的O(纳米)。这里是一个C++解决方案:

    int max_distance(char** strings, int numstrings, int &distance) {
        distance = 0;
        // loop O(n) for initialization
        for (int i=0; i<numstrings; i++) 
            distance += strlen(strings[i]);
    
        int max_prefix = 0;
        bool done = false;
        // loop max O(m)
        while (!done) {
            int c = -1;
            // loop O(n)
            for (int i=0; i<numstrings; i++) {
                if (strings[i][max_prefix] == 0) {
                    done = true; // it is enough to reach the end of one string to be done
                    break;  
                }
    
                int new_element = strings[i][max_prefix] - '0';
                if (-1 == c)
                    c = new_element;
                else {
                    if (c != new_element) {
                        done = true;    // mismatch
                         break;
                    }
                }
            }
            if (!done) {
                max_prefix++;
                distance -= numstrings;
            }
        }
    
        return max_prefix;
    }
    
    
    void test_misc() {
        char* strings[] = { 
            "10100",
            "10101110",
            "101011",
            "101"
        };
    
        std::cout << std::endl;
        int distance = 0;
        std::cout << "max_prefix = " << max_distance(strings, sizeof(strings)/sizeof(strings[0]), distance) << std::endl;
    }
    
    int max_距离(字符**字符串、int numstrings、int&distance){
    距离=0;
    //用于初始化的循环O(n)
    
    对于(int i=0;i我认为这个问题类似于“查找两个字符串的前缀”,您可以使用trie()来加速搜索

    3天前我有一个谷歌电话面试,但也许我失败了


    祝你好运

    我不知道当迭代给你同样大的O计算复杂度而没有代码复杂度时,为什么要使用树。无论如何,这是我的javascript O(mn)版本

    var len=process.argv.length-2;//在节点中,前两个参数是节点和程序文件
    var输入=过程argv拼接(2);
    无功电流;
    var currentCount=0;
    var currentCharLoc=0;
    var totalCount=0;
    var totalComplete=0;
    var=true;
    while(totalCompletecurrentCharLoc){
    currentCount++;
    如果(相同){
    如果(当前===null){
    电流=输入[loc][currentCharLoc];
    }否则{
    如果(当前!==输入[loc][currentCharLoc]){
    相同=错误;
    }
    }
    }
    }
    }
    如果(!相同){
    totalCount+=当前计数;
    }
    currentCharLoc++;
    }
    console.log(totalCount);
    
    我想我可以对所有的元素进行排序。但即使这样,我也无法在任何地方继续。有谁能指导我解决这个问题的方法吗。@杜克林:谢谢编辑。你能帮我解决这个问题吗?排序也将是算法的一部分。如果列表已排序,那么只需检查连续元素的cra即可zy距离&因此是最大值。然而,我不认为排序是唯一的方法。DoSparKot,你提出的反例:“000”、“001”、“0010”怎么样?按字典顺序对它们进行排序,然后检查连续元素之间的距离,给出D(000001)=len(“0”)+len(“1”)=2,D(0010010010)=len len(”+len(“0”)=1,但D(0000010)=len(“0”)+len(“10”)=3。在这里,我指的是“n”作为字符串的数量。为了找出
    var len = process.argv.length -2; // in node first 2 arguments are node and program file
    var input = process.argv.splice(2);
    var current;
    var currentCount = 0;
    var currentCharLoc = 0;
    var totalCount = 0;
    var totalComplete = 0;
    var same = true;
    while ( totalComplete < len ) {
            current = null;
            currentCount = 0;
            for ( var loc = 0 ; loc < len ; loc++) {
                    if ( input[loc].length === currentCharLoc) {
                            totalComplete++;
                            same = false;
                    } else if (input[loc].length > currentCharLoc) {
                            currentCount++;
                            if (same) {
                                    if ( current === null ) {
                                            current = input[loc][currentCharLoc];
                                    } else {
                                            if (current !== input[loc][currentCharLoc]) {
                                                    same = false;
                                            }
                                    }
                            }
                    }
            }
            if (!same) {
                    totalCount += currentCount;
            }
            currentCharLoc++;
    }
    
    console.log(totalCount);