简体   繁体   中英

Concatenate a string from a sorted Array

Hi I'm practicing for my interview and I would like to know if there is a better solution for this problem:

Given a key String key="apple" and a sorted Array of strings, String[] words ={apple, apples, bananaaple, orangebanana, pearapples}

write a function which return true when you can concatenate to get the key string using words from the word list, false if you can't.

my idea is starting with one letter from the key string, and do a binary search from the world list, if exists, find the rest of the string; if not, increase one more letter, and do the same.

my code:

 public static void main(String[] args){
        String[] words = {"apple", "apples", "bananaaple", "orangebanana", "pearapples"};

        String key = "apple";

        System.out.println(expanding(words,key));
    }


    public static boolean expanding(String[] words, String key){
        if(key.length()<1){
            return false;
        }

        for(int i=1; i<=key.length(); i++){
            String sub = key.substring(0, i);
            boolean found =search(words,sub,0,words.length-1);
            if(found){ //get next piece
                String theSubString =key.substring(i, key.length());
                if(theSubString.compareToIgnoreCase("")==0){
                    return found;
                }
                boolean re = expanding(words,theSubString );
                if(re)
                    return true;
            }
        }
        return false;
    }

    public static boolean search(String[] list, String key, int min, int max){
        if(min>max){
            return false;
        }
            int mid = (min+max)/2;
            if(list[mid].compareToIgnoreCase(key)==0){
                return true;
            }else if(list[mid].compareToIgnoreCase(key)<0){
                return search(list,key,mid+1,max);
            }else{
                return search(list,key,min,mid-1);
            }

    }

In my opinion the best case should be O(log n), but not sure the worst case... maybe O(n^2) when can only match one letter at a time.

can anyone give me more ideas?

Basically the approach that you put forth is a recursive search with backtracking. It should work correctly, but there should exist inputs that can make your algorithm run in exponential time.

Perhaps surprisingly, your problem can be solved in linear time using regular expressions. In your example, we would test whether the regular expression /(apple|apples|bananaaple|orangebanana|pearapples)*/ matches the key.

The problem of matching a string to a regular expression is studied in automata theory, and can be solved using a nondeterministic finite automaton in linear time.

Can we have a Trie where all the words in the word list are inserted?

  • We can take the entire key word, one letter at a time until we reach the LEAF of the trie.
  • On reaching a LEAF, we have found one portion of the key word.
  • Continue TRIE search all remaining letters/sub-words in the key word.
  • If we reach the end of the key word && reach LEAF at the same time in the TRIE, then we have a match using a combination of words in the TRIE.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM