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;
    }
}
posted @ 2018-12-30 20:55  shawshawwan  阅读(267)  评论(0编辑  收藏  举报