269. Alien Dictionary

来源:互联网 发布:化为简化阶梯型矩阵 编辑:程序博客网 时间:2024/04/26 00:08
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 non-empty words from the dictionary, where words are sorted lexicographically by the rules of this new language. Derive the order of letters in this language.
Example 1:

Given the following words in dictionary,
[
  "wrt",
  "wrf",
  "er",
  "ett",
  "rftt"
]

The correct order is: "wertf".
Example 2:

Given the following words in dictionary,
[
  "z",
  "x"
]

The correct order is: "zx".
Example 3:

Given the following words in dictionary,
[
  "z",
  "x",
  "z"
]

The order is invalid, so return "".
Note:

  1. You may assume all letters are in lowercase.
  2. You may assume that if a is a prefix of b, then a must appear before b in the given dictionary.
  3. If the order is invalid, return an empty string.
  4. There may be multiple valid order of letters, return any one of them is fine.
简单来说 给出的是字典的一部分 按照字典序排序 求字母的排序
比如英文字典中 首先是a开头的字母 然后是b开头的字母 对于同样是a开头的字母 比较后面的字母 哪个字母在在字母表中的位置靠前 那么就在前面
比如 abc在abs之前 前面的ab相同 c在字母表中的位置比s靠前 所以排序是 abc->abs

这是一个排序问题 怎么排序?按照出现的先后排序
比如 
[
  "wrt",
  "wrf",
  "er",
  "ett",
  "rftt"
]
从上到下 w在e之前 e在r之前 所以排序是 w->e->r
然后从左到右 只有两个字母前面的字母相同时才可以比较
比如 wrt和wrf wr之后 t在f之前 所以排序是 t->f

也就是按照当前字母前面出现的字母个数排序 比如w前面有0个字母 e前面有w一个字母 r前面有e一个字母 加上字母e前面有w一个字母
所以 w前面有0个字母 e前面有1个字母 r前面有2个字母 排序是w->e->r

到这里 可以看出本题可以归结为一个拓扑问题 w后面连接了e节点 e后面连接了r节点
首先统计入度 w的入度是0 e的入度是1 r的入度是2
首先统计入度为0的节点 放入结果中 然后取出w后连接的节点 将他们的入度-1 如果有入度为0的节点 再放入结果中
整个过程像是在一个拓扑图中进行广度优先遍历

代码如下

public String alienOrder(String[] words) {    Map<Character, Set<Character>> map=new HashMap<Character, Set<Character>>();    Map<Character, Integer> degree=new HashMap<Character, Integer>();    String result="";    if(words==null || words.length==0) return result;    for(String s: words){        for(char c: s.toCharArray()){            degree.put(c,0);        }    }    for(int i=0; i<words.length-1; i++){        String cur=words[i];        String next=words[i+1];        int length=Math.min(cur.length(), next.length());        for(int j=0; j<length; j++){            char c1=cur.charAt(j);            char c2=next.charAt(j);            if(c1!=c2){                Set<Character> set=new HashSet<Character>();                if(map.containsKey(c1)) set=map.get(c1);                if(!set.contains(c2)){                    set.add(c2);                    map.put(c1, set);                    degree.put(c2, degree.get(c2)+1);                }                break;            }        }    }    Queue<Character> q=new LinkedList<Character>();    for(char c: degree.keySet()){        if(degree.get(c)==0) q.add(c);    }    while(!q.isEmpty()){        char c=q.remove();        result+=c;        if(map.containsKey(c)){            for(char c2: map.get(c)){                degree.put(c2,degree.get(c2)-1);                if(degree.get(c2)==0) q.add(c2);            }        }    }    if(result.length()!=degree.size()) return "";    return result;}


原创粉丝点击