LeetCode 题解(237) : Alien Dictionary

题目:

There is a new alien language which uses the latin alphabet. However, the order among letters are unknown to you. You receive a list of words from the dictionary, where words are sorted lexicographically by the rules of this new language.Derive the order of letters in this language.

For example,
Given the following words in dictionary,

[
  "wrt",
  "wrf",
  "er",
  "ett",
  "rftt"
]

The correct order is: "wertf".

Note:

  1. You may assume all letters are in lowercase.
  2. If the order is invalid, return an empty string.
  3. There may be multiple valid order of letters, return any one of them is fine.
题解:

先转换为char -> list(char) 的哈希。然后就是一个topological sort的问题。 用递归解决。同时要注意存在环的问题。最后把未用过的字母加入排序后的字符串。

C++版:

class Solution {
public:
    string alienOrder(vector& words) {
        if(words.size() == 0)
            return "";
        
        unordered_map> d;
        unordered_map used;
        
        for(auto s : words) {
            for(int i = 0; i < s.length(); i++) {
                if(used.find(s[i]) == used.end())
                    used.insert(pair(s[i], false));
            }
        }
        
        for(int i = 1; i < words.size(); i++) {
            string cur = words[i];
            string pre = words[i - 1];
            int j = 0;
            while(j < min(cur.length(), pre.length())) {
                if(cur[j] != pre[j]) {
                    if(d.find(pre[j]) == d.end()) {
                        vector list;
                        list.push_back(cur[j]);
                        d.insert(pair>(pre[j], list));
                    }
                    else {
                        d[pre[j]].push_back(cur[j]);
                    }
                    break;
                }
                j++;
            }
        }
        
        string result = "";
        for(auto it = d.begin(); it != d.end(); it++) {
            if(!used[it->first]) {
                unordered_set loop;
                bool l = topologicalSort(d, used, result, it->first, loop);
                if(l)
                    return "";
            }
        }
        
        for(auto i = used.begin(); i != used.end(); i++) {
            if(!i->second)
                result = i->first + result;
        }
        
        return result;
    }
    
    bool topologicalSort(unordered_map> d, unordered_map& used, string& result, char cur, unordered_set& loop) {
        used[cur] = true;
        loop.insert(cur);
        for(auto i : d[cur]) {
            if(loop.find(i) != loop.end())
                return true;
            if(!used[i]) {
                bool l = topologicalSort(d, used, result, i, loop);
                if(l)
                    return true;
            }
        }
        result = cur + result;
        return false;
    }
};

Java版:

import java.util.Iterator;

public class Solution {
    public String alienOrder(String[] words) {
        if(words.length == 0)
            return "";

        HashMap> d = new HashMap<>();
        HashMap used = new HashMap<>();

        for(int i = 0; i < words.length; i++) {
            for(int j = 0; j < words[i].length(); j++) {
                if(!used.containsKey(words[i].charAt(j)))
                    used.put(words[i].charAt(j), false);
            }
        }

        for(int i = 1; i < words.length; i++) {
            String pre = words[i - 1];
            String cur = words[i];
            int j = 0;
            while(j < Math.min(pre.length(), cur.length())) {
                if(pre.charAt(j) != cur.charAt(j)) {
                    if(!d.containsKey(pre.charAt(j))) {
                        List l = new ArrayList<>();
                        l.add(cur.charAt(j));
                        d.put(pre.charAt(j), l);
                    } else {
                        d.get(pre.charAt(j)).add(cur.charAt(j));
                    }
                    break;
                }
                j++;
            }
        }

        StringBuffer sb = new StringBuffer();
        Iterator it = d.keySet().iterator();
        while(it.hasNext()) {
            char cur = (char)it.next();
            if(!used.get(cur)) {
                Set loop = new HashSet<>();
                boolean result = topologicalSort(d, used, cur, loop, sb);
                if(result)
                    return "";
            }
        }

        it = used.keySet().iterator();
        while(it.hasNext()) {
            char cur = (char)it.next();
            if(!used.get(cur))
                sb.insert(0, cur);
        }

        return sb.toString();
    }

    boolean topologicalSort(HashMap> d, HashMap used, char cur, Set loop, StringBuffer sb) {
        used.put(cur, true);
        loop.add(cur);
        if(d.containsKey(cur)) {
            for(char i : d.get(cur)) {
                if(loop.contains(i))
                    return true;
                if(!used.get(i)) {
                    boolean result = topologicalSort(d, used, i, loop, sb);
                    if(result)
                        return true;
                }
            }
        }
        sb.insert(0, cur);
        return false;
    }
}

Python版:

class Solution(object):
    def __init__(self):
        self.result = ""

    def alienOrder(self, words):
        """
        :type words: List[str]
        :rtype: str
        """
        d = {}
        visited = {}
        for i in words:
            for j in i:
                if j not in visited:
                    visited[j] = False

        for i in range(1, len(words)):
            j = 0
            last, cur = words[i - 1], words[i]
            while j < min(len(last), len(cur)):
                if last[j] != cur[j]:
                    if last[j] in d:
                        d[last[j]].append(cur[j])
                    else:
                        d[last[j]] = [cur[j]]
                    break
                j += 1


        for i in visited:
            if not visited[i]:
                used = []
                loop = self.topologicalSort(d, visited, i, used)
                if loop:
                    return ""

        self.result = self.result[::-1]

        for i in visited:
            if i not in d:
                self.result += i
        return self.result

    def topologicalSort(self, d, visited, i, used):
        visited[i] = True
        used.append(i)
        if i in d:
            for j in d[i]:
                if j in used:
                    return True
                if not visited[j]:
                    result = self.topologicalSort(d, visited, j, used)
                    if result:
                        return True
            self.result += i
        return False

你可能感兴趣的:(算法)