LeetCode 117th Weekly Contest 总结
这次比赛前两道题30分钟解决,第三题Vowel Spellchecker暴力超时浪费了时间,最后也没优化出来。事后看了第三题额解答,发现其实挺简单的,但是比赛时就是没想出。
总之周赛成绩有了点进步,但是还得再接再厉。目标是做出3道题。
965. Univalued Binary Tree
题意
A binary tree is univalued if every node in the tree has the same value.
Return true if and only if the given tree is univalued.
思路
easy题,直接递归判断左右子树
代码
class Solution {
public boolean isUnivalTree(TreeNode root) {
return helper(root.left, root.val) && helper(root.right, root.val);
}
private boolean helper(TreeNode node, int prev) {
if (node == null) return true;
if (node.val != prev) return false;
return helper(node.left, node.val) && helper(node.right, node.val);
}
}
967. Numbers With Same Consecutive Differences
题意
Return all non-negative integers of length N such that the absolute difference between every two consecutive digits is K.
Note that every number in the answer must not have leading zeros except for the number 0 itself. For example, 01 has one leading zero and is invalid, but 0 is valid.
思路
- 一看到这题,就知道可以用回溯解决,目标就是一个个拼数字,当长度拼完且每一位都合法的时候,就找到了一个合法解,否则就回溯;于是可以直接用回溯解决
- 最后要注意N=1的corner case,单独加上就可以了
代码
class Solution {
public int[] numsSameConsecDiff(int N, int K) {
Set<String> tmp = new HashSet<>();
StringBuilder sb = new StringBuilder();
for (int i = 1; i <= 9; i++) {
sb.append(i);
helper(0, i, N, K, sb, tmp);
sb.deleteCharAt(sb.length() - 1);
}
if (N == 1) tmp.add("0");
int[] res = new int[tmp.size()];
int i = 0;
for (String s : tmp) res[i++] = Integer.valueOf(s);
return res;
}
private void helper(int index, int prevNum, int N, int diff, StringBuilder sb, Set<String> tmp) {
if (index == N - 1) {
tmp.add(new String(sb.toString()));
return;
}
if (prevNum + diff <= 9) {
sb.append(prevNum + diff);
helper(index + 1, prevNum + diff, N, diff, sb, tmp);
sb.deleteCharAt(sb.length() - 1);
}
if (prevNum - diff >= 0) {
sb.append(prevNum - diff);
helper(index + 1, prevNum - diff, N, diff, sb, tmp);
sb.deleteCharAt(sb.length() - 1);
}
}
}
966. Vowel Spellchecker
题意
这题题目比较冗长,大意就是匹配字符串的意思,详细题意戳:966. Vowel Spellchecker
思路
- 比赛时候用暴力解,明显就知道要超时的,白白浪费了时间;然后看起来像trie的题,但是并没有好的思路
- 比赛结束看大神解法,才知道是用hash map:构建两个hash table分别处理两个匹配规则。小技巧:元音的处理,将元音都用同一个字符代替就行了!
- 这题的技巧就是预处理,用空间换时间,预处理,将一些信息先存储起来,实际算的时候就可以只要hash map get就行了,复杂度大大降低;
代码
class Solution {
List<Character> vowls = new ArrayList<>(Arrays.asList('a', 'e', 'i','o', 'u'));
public String[] spellchecker(String[] wordlist, String[] queries) {
Set<String> set = new HashSet<>();
Map<String, String> map1 = new HashMap<>();
Map<String, String> map2 = new HashMap<>();
String[] res = new String[queries.length];
int i = 0;
for (String s : wordlist) {
set.add(s);
if (!map1.containsKey(s.toLowerCase())) {
map1.put(s.toLowerCase(), s);
}
if (!map2.containsKey(vowlsHelper(s.toLowerCase()))) {
map2.put(vowlsHelper(s.toLowerCase()), s);
}
}
for (String q : queries) {
if (set.contains(q))
res[i++] = q;
else if (map1.containsKey(q.toLowerCase()))
res[i++] = map1.get(q.toLowerCase());
else if (map2.containsKey(vowlsHelper(q.toLowerCase())))
res[i++] = map2.get(vowlsHelper(q.toLowerCase()));
else
res[i++] = "";
}
return res;
}
private String vowlsHelper(String s) {
char[] chars = s.toCharArray();
for (int i = 0; i < s.length(); i++) {
if (vowls.contains(chars[i])) {
chars[i] = '#';
}
}
return new String(chars);
}
}
968. Binary Tree Cameras
题意
Given a binary tree, we install cameras on the nodes of the tree.
Each camera at a node can monitor its parent, itself, and its immediate children.
Calculate the minimum number of cameras needed to monitor all nodes of the tree.
思路
- 求问最少的相机能cover整颗树,要么是动态规划,要么是贪心
- 动态规划可能不太好理解,看了寒神的解答,用贪心会更简单:从叶子节点向上看,在孩子节点上放相机,或者在中间放相机,或者在最上面的父节点放相机,
当然是中间放相机是最优的选择,因为中间放相机能cover更多的节点;
难么每个节点能知道子节点的状态,则能推导出现在自己的状态了
0:表示是叶子节点,且没有被cover
1:表示是叶子节点的父节点,放置了相机,被cover了
2:表示被cover了,但是没有放置相机
代码
class Solution {
int res;
public int minCameraCover(TreeNode root) {
int state = helper(root);
return res + (state < 1 ? 1 : 0);
}
private int helper(TreeNode node) {
int left = node.left == null ? -1 : helper(node.left);
int right = node.right == null ? -1 : helper(node.right);
if (left == 0 || right == 0) {
res++;
return 1;
}
return left == 1 || right == 1 ? 2 : 0;
}
}