Leetcode 269. Alien Dictionary 已过新test case

原创 2016年10月03日 06:41:30

269. Alien Dictionary

Total Accepted: 13810 Total Submissions: 55329 Difficulty: Hard

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.

Hide Company Tags
 Google Airbnb Facebook Twitter Snapchat Pocket Gems
Hide Tags
 Graph Topological Sort
Hide Similar Problems
 (M) Course Schedule II

思路:

先说明参考这里这里。只是俩文的code面对新test case无法AC,新test case下面会说。

Tag是拓补排序。拓补排序就得知道每个点的入度,而且要知道把一个入度为0的点输出之后哪些点要收到影响。

这个题输入是一个words数组,给了一堆单词。一共需要两步:一,转化为graph。二:对graph使用拓补排序。


Map<Character, Integer> indegree用来保存已有的点的入度。

Map<Character, Set<Character>> map用来保存key输出之后会收到影响的点。

先遍历words中的所有字符c, indegree.put(c, 0)。这是因为有可能有一些点没有入度但是也出现了。 - 注意事项1


接下来遍历words数组,每次取出俩单词。然后判定俩单词的最小长度len,并遍历0~len-1对比char。(char cur, char next)

如果相等,什么都不做;如果不相等,那么就对map和indegree做相应计数。注意的地方是如果map中cur为key取出的set中已经有next,那说明我们已经算过这条边,此时indegree不计数。 - 注意事项2


之后就是拓扑排序。先遍历一遍indegree取出value为0的key,入队。每次队首取一个元素,然后map中取出其set,这些就是将会受到影响的点。在indegree中计数-1,如果为0入队即可。


最后如果结果的长度和indegree.size()不相等(我们把所有的char都放在了indegree即使入度为0),说明有环,返回空字符。


关于新test case:

114 / 115 test cases passed.
Input:
["wrtkj","wrt"]
Output:
"rtwjk"
Expected:
""

本来这个case默认输出不是空字符,直到有人几天前在discussion反应说这不是一个valid input,原贴这里。问题在于lexicographical order的定义是a在b之前,如果a是b的prefix string。所以这个test case应该是invalid的。

原帖中给出了修改意见,就是要判断一下上面的情况:String a出现在String b之前,但是b是a的prefix string。

// j = Math.min(words[i].length(), words[i+1].length());
if(words[i].charAt(j - 1) == words[i + 1].charAt(j - 1) && j < words[i].length())  return "";

如果直接加入我所参考文章的代码中,会报错。因为只check了最后一位。比如abc ac,其实是valid因为ac不是abc的prefix。

解决办法有俩:

1. 使用substring命令,把上面代码的char相等改为s1.equals(s2)。

2. 我代码中的方式。对每一行的循环,设立一个boolean变量,默认值为false。如果在之前对比的过程中发现不相等,代码中会直接break比较过程,这时候把该boolean设置为true。这样比较之后,如果是true说明俩不相等,不需要判断新test case。否则则需要判断。

if(!breaked && cur.charAt(len - 1) == next.charAt(len - 1) && len < cur.length()) return "";

public class Solution { // 9ms
    public String alienOrder(String[] words) {
        if(words == null || words.length == 0) return "";
        
        // map is used to know characters that will be influenced upon removal of cur char
        // indegree isused to know the indegree of cur char
        Map<Character, Set<Character>> map = new HashMap<Character, Set<Character>>(); 
        Map<Character, Integer> indegree = new HashMap<Character, Integer>(); 
        
        for(String word : words){
            for(char c : word.toCharArray()) indegree.put(c, 0);
        }
        
        for(int i = 0; i < words.length - 1; i++){
            String cur = words[i];
            String next = words[i + 1];
            int len = Math.min(cur.length(), next.length());
            boolean breaked = false;
            
            for(int j = 0; j < len; j++){
                char c1 = cur.charAt(j);
                char c2 = next.charAt(j);
                if(c1 != c2){ // cur char should go before next char
                    Set<Character> set;
                    if(map.containsKey(c1)) set = map.get(c1);
                    else{
                        set = new HashSet<Character>();
                        map.put(c1, set);
                    }
                    
                    if(!set.contains(c2)){
                        set.add(c2);
                        indegree.put(c2, indegree.get(c2) + 1);
                    }
                    breaked = true;
                    break;
                }
            }
            if(!breaked && cur.charAt(len - 1) == next.charAt(len - 1) && len < cur.length()) return "";
        }
        
        // now we have the graph, continue with topological sort
        StringBuilder res = new StringBuilder();
        Queue<Character> queue = new LinkedList<Character>();
        for(char c : indegree.keySet()){
            if(indegree.get(c) == 0) queue.add(c);
        }
        
        while(!queue.isEmpty()){
            char c = queue.poll();
            res.append(c);
            if(map.containsKey(c)){ // if this c influences nobody, it will not be in the map
                for(char next : map.get(c)){
                    int value = indegree.get(next);
                    if(value == 1) queue.add(next);
                    indegree.put(next, value - 1);
                }
            }
        }
        
        // check if cycle exists
        if(res.length() == indegree.size()) return res.toString();
        else return "";
    }
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

LeetCode 269. Alien Dictionary(外星人字典)

原题网址:https://leetcode.com/problems/alien-dictionary/ There is a new alien language which uses the ...
  • jmspan
  • jmspan
  • 2016年04月13日 02:23
  • 1116

[leetcode] 269. Alien Dictionary 解题报告

题目链接: https://leetcode.com/problems/alien-dictionary/ There is a new alien language which uses the...
  • qq508618087
  • qq508618087
  • 2016年03月25日 15:58
  • 1780

LeetCode(269) Alien Dictionary (Java)

题目如下: There is a new alien language which uses the latin alphabet. However, the order among letters...
  • feliciafay
  • feliciafay
  • 2015年11月25日 18:58
  • 2056

[LeetCode269]Alien Dictionary

There is a new alien language which uses the latin alphabet. However, the order among letters are un...
  • u012175043
  • u012175043
  • 2015年11月26日 04:06
  • 631

Alien Skin Exposure v6.x 最新通用完整版汉化补丁

完整汉化版说明:     我于2014-06-19上传的“Alien Skin Exposure 6.x 通用汉化补丁”,有些网友反映预设不能显示中文,调查了一下:预设能显示中文的,操作系统基本上是完...
  • xwm0008
  • xwm0008
  • 2014年06月30日 07:42
  • 4524

AlienSkin Snap Art 4.0.366汉化补丁(PS手绘效果插件)

Snap Art 4 允许您通过简单、时尚的用户界面用多个艺术风格进行试验。清新的设计和布局减少了干扰,并提供快速可视化浏览广泛的预设,这样您可以比以往任何时候更快达到完美的效果。Snap Art 可...
  • xwm0008
  • xwm0008
  • 2014年06月03日 13:37
  • 2248

一个使用Dictionary的小实例

在C#中,使用Dictionary类来管理由键值对组成的集合,这类集合称为字典。 字典最大的特点就是能够根据键来快速查找集合中的值。 下面是一个使用字典的小实例,希望通过这个小实例,能让大家对字典...
  • tiana0
  • tiana0
  • 2014年09月14日 17:53
  • 1891

ART登场,Android要和核心虚拟机Dalvik说再见了

Dalvik是Android的核心组成部分之一,Android上的应用程序需要依靠它才可以正常运行。现在Google准备用新的运行环境ART来替代它。在最新的Android4.4上,有两个运行环境供开...
  • LVXIANGAN
  • LVXIANGAN
  • 2014年04月01日 14:52
  • 1777

关于Dictionary元素的遍历

关于Dictionary元素的遍历 以前我面试别人的时候,我经常会问应聘者,如何在C#中遍历Hashtable中的元素,每次遍历时,需要得到Key和Value。 一直以来,也经常有人问这个...
  • cao478208248
  • cao478208248
  • 2014年04月18日 10:07
  • 1472

Alien Skin Eye Candy v7.x(眼睛糖果7)最新通用汉化补丁32/64位

Alien Skin Eye Candy v7.x(眼睛糖果7)主要应用对象包含各种设计任务,字体,标志,网页设计等,通过对自然现象的模拟提供各种现实的精致效果。眼睛糖果 的界面简单直观,轻松提高你使...
  • xwm0008
  • xwm0008
  • 2014年06月09日 11:12
  • 3178
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Leetcode 269. Alien Dictionary 已过新test case
举报原因:
原因补充:

(最多只允许输入30个字)