ARTS
Algorithm:每周至少做一个leetcode的算法题;
Review:阅读并点评至少一篇英文技术文章;
Tip/Tech:学习至少一个技术技巧;
Share:分享一篇有观点和思考的技术文章;
Algorithm
49. 字母异位词分组
https://leetcode-cn.com/problems/group-anagrams/
先来看看这代码写的,其实就是如果一个数组如果遍历过了就放在集合当中,不进行判断了,但是最坏的情况就是没单词都是单独的异位词,这样就导致了时间复杂度非常大。这样的解法是不对的,会导致时间超时。
public List<List<String>> groupAnagrams(String[] strs) {
Set<Integer> set = new HashSet<Integer>();
List<List<String>> res = new LinkedList<>();
for (int i = 0, len = strs.length; i < len; ++i) {
if (set.contains(i)) {
continue;
}
List<String> tempList = new LinkedList<>();
for (int j = i; j < len; ++j) {
if (!set.contains(j)) {
boolean result = hashBetterIsAnagram(strs[i], strs[j]);
if (result) {
set.add(j);
tempList.add(strs[j]);
}
}
}
res.add(tempList);
}
return res;
}
public boolean hashBetterIsAnagram(String s, String t) {
int[] first = new int[26];
for (int i = 0, len = s.length(); i < len; ++i) {
first[s.charAt(i) - 'a'] ++;
}
for (int i = 0, len = t.length(); i < len; ++i) {
first[t.charAt(i) - 'a'] --;
}
for (int i = 0; i < 26; ++i) {
if (first[i] != 0) {
return false;
}
}
return true;
}
一个相对正确的解法
用一个散列表,用排序过后的单词作为key,异位词构成的list直接作为value。这样设计就很好的形成了一一对应的关系了。而且代码也行到底很简洁。非常适合阅读,虽然不是最好的时间复杂度,但是已经做到很好了。
时间复杂度:
时间复杂度:O(NK \log K)O(NKlogK),其中 NN 是 strs 的长度,而 KK 是 strs 中字符串的最大长度。当我们遍历每个字符串时,外部循环具有的复杂度为 O(N)O(N)。然后,我们在 O(K \log K)O(KlogK) 的时间内对每个字符串排序。
public List<List<String>> groupAnagrams(String[] strs) {
// 查找表法
Map<String, List<String>> map = new HashMap<>();
for (String str : strs) {
char[] chars = str.toCharArray();
Arrays.sort(chars);
// 将每个字符串对应字符数组经排序后得到的字符串作为该字符串的分类标志
String flag = String.valueOf(chars);
List<String> list = map.getOrDefault(flag, new ArrayList<>());
list.add(str);
map.put(flag, list);
}
return new ArrayList<>(map.values());
}
public boolean hashBetterIsAnagram(String s, String t) {
int[] first = new int[26];
for (int i = 0, len = s.length(); i < len; ++i) {
first[s.charAt(i) - 'a'] ++;
}
for (int i = 0, len = t.length(); i < len; ++i) {
first[t.charAt(i) - 'a'] --;
}
for (int i = 0; i < 26; ++i) {
if (first[i] != 0) {
return false;
}
}
return true;
}
官方的最佳解答的思想。用计数分类的思想,其实就很想我以前认为的哈希思想。用一个数组在记录每个字母出现的次数
用一个固定的串来作为map的标识,这样全部单词只要遍历一次就够了。Nice
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
if (strs.length == 0) return new ArrayList();
Map<String, List> ans = new HashMap<String, List>();
int[] count = new int[26];
for (String s : strs) {
Arrays.fill(count, 0);
for (char c : s.toCharArray()) count[c - 'a']++;
StringBuilder sb = new StringBuilder("");
for (int i = 0; i < 26; i++) {
sb.append('#');
sb.append(count[i]);
}
String key = sb.toString();
if (!ans.containsKey(key)) ans.put(key, new ArrayList());
ans.get(key).add(s);
}
return new ArrayList(ans.values());
}
}
Review
Let’s code a TCP/IP stack, 4: TCP Data Flow & Socket API
http://www.saminiir.com/lets-code-tcp-ip-stack-4-tcp-data-flow-socket-api/
- Transmission Control Block
- TCP Data Communication
- TCP Connection Termination
- Socket API
- Testing our Socket API
- Conclusion
- Sources
这篇说的和传输的数据流有关,我最近一直在想着是不是要用Java把这几篇的文章给实现一遍。
Tip/Tech
通过看JDK的源码,对几种设计模式加深了思考。
Share
https://onezero.medium.com/ctrl-alt-delete-the-planned-obsolescence-of-old-coders-9c5f440ee68
Ctrl-Alt-Delete: The Planned Obsolescence of Old Coders
Old coders never die, they just become middle managers.
老码农过时计划。
这篇文章说的就是有关于年纪大的程序员和命运相关的话题,总得来说就是很多大公司其实更喜欢年纪小的程序员,因为年轻嘛,可以熬夜,加班,扛得住,可是到了三十几岁的,那就危险了,身体不行了,有了家庭,肯定是不会去花那么多时间熬夜了,毕竟高薪也就意味着竞争压力很大,不可能每个公司都养着这么多的人。