在西安,除了华为和中兴,是不是其他公司的程序员,很难年薪超过 40万?
在西安干程序员,年薪想摸到40万,很多人第一反应还真就是:要么华为,要么中兴,要么你别做梦。
话虽然损,但也不是空穴来风。西安这地方,岗位是有,程序员也不少,可一到薪资就开始拧巴,招聘写得像要造火箭,开价却像让你去修打印机。
我觉得这事最真实的地方就在这儿:不是西安没程序员,也不是西安没活,而是高薪岗位太集中,能打的公司就那几家,剩下大多数岗位都透着一股“够用就行”的抠门气。最后卷来卷去,技术没输,输在公司池子太浅。
面试题:单词规律
pattern = "abba",s = "dog cat cat dog",看着像送分题。真写起来,很多人还是会在映射关系上拧巴一下:只校验 a -> dog,没校验 dog -> a,结果 "abba" 和 "dog dog dog dog" 这种脏数据也能过。
这种题我一般不急着写代码,先盯住一点:映射必须双向唯一。字符不能撞单词,单词也不能撞字符。少验一边,基本就埋雷了。
先看一眼最容易翻车的写法,问题就出在只维护了一张表:
Map<Character, String> map = new HashMap<>();
for (int i = 0; i < pattern.length(); i++) {
char c = pattern.charAt(i);
String word = words[i];
if (map.containsKey(c)) {
if (!map.get(c).equals(word)) {
returnfalse;
}
} else {
map.put(c, word);
}
}
这段代码能挡住一半错误,挡不住另一半。比如 pattern = "ab",s = "dog dog",按题意应该返回 false,因为 a 和 b 不该同时映射到 dog。但上面这段会放行。
我更习惯直接上两张表,判断干净,排查也省事:
classSolution{
publicbooleanwordPattern(String pattern, String s){
String[] words = s.split(" ");
if (words.length != pattern.length()) {
returnfalse;
}
Map<Character, String> c2w = new HashMap<>();
Map<String, Character> w2c = new HashMap<>();
for (int i = 0; i < pattern.length(); i++) {
char ch = pattern.charAt(i);
String word = words[i];
String mappedWord = c2w.get(ch);
Character mappedChar = w2c.get(word);
if (mappedWord == null && mappedChar == null) {
c2w.put(ch, word);
w2c.put(word, ch);
continue;
}
if (!word.equals(mappedWord) || mappedChar == null || mappedChar != ch) {
returnfalse;
}
}
returntrue;
}
}
这题真正该先排的,不是循环怎么写,是两个边界。
一个是数量必须相等。pattern.length() 和单词个数不一致,后面不用看,直接 false。 另一个是字符串切分。题目里单词之间通常是单个空格,这时候 split(" ") 就够了;要是自己在业务里写类似校验,我一般会先 trim(),再考虑连续空格,不然测试数据一脏,结果就开始飘。
再拿几组数据过一下,心里就稳了:
System.out.println(new Solution().wordPattern("abba", "dog cat cat dog")); // true
System.out.println(new Solution().wordPattern("abba", "dog cat cat fish")); // false
System.out.println(new Solution().wordPattern("aaaa", "dog cat cat dog")); // false
System.out.println(new Solution().wordPattern("ab", "dog dog")); // false
时间复杂度就是 O(n),空间复杂度也是 O(n)。这种题不吃算法花活,吃的是你对“唯一映射”这件事是不是想完整了。