前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >LeetCode Weekly Contest 46解题思路

LeetCode Weekly Contest 46解题思路

作者头像
用户1147447
发布2019-05-26 09:41:19
3470
发布2019-05-26 09:41:19
举报
文章被收录于专栏:机器学习入门

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://cloud.tencent.com/developer/article/1434714

LeetCode Weekly Contest 46解题思路

详细代码可以fork下Github上leetcode项目,不定期更新。

赛题

本次周赛主要分为以下4道题:

Leetcode 661. Image Smoother

Problem:

Given a 2D integer matrix M representing the gray scale of an image, you need to design a smoother to make the gray scale of each cell becomes the average gray scale (rounding down) of all the 8 surrounding cells and itself. If a cell has less than 8 surrounding cells, then use as many as you can.

Example 1:

Input: [1,1,1, 1,0,1, 1,1,1] Output: [0, 0, 0, 0, 0, 0, 0, 0, 0] Explanation: For the point (0,0), (0,2), (2,0), (2,2): floor(3/4) = floor(0.75) = 0 For the point (0,1), (1,0), (1,2), (2,1): floor(5/6) = floor(0.83333333) = 0 For the point (1,1): floor(8/9) = floor(0.88888889) = 0

Note:

  • The value in the given matrix is in the range of 0, 255.
  • The length and width of the given matrix are in the range of 1, 150.

直接求解法,很直观。

代码如下:

代码语言:javascript
复制
    int[][] dir = {{1,0},{-1,0},{0,1},{0,-1},{0,0},{1,1},{-1,1},{-1,-1},{1,-1}};
    public int[][] imageSmoother(int[][] M) {
        int n = M.length;
        int m = M[0].length;
        int[][] ans = new int[n][m];
        for (int i = 0; i < n; ++i){
            for (int j = 0; j < m; ++j){
                int sum = 0;
                int cnt = 0;
                for (int[] d : dir){
                    int nx = i + d[0];
                    int ny = j + d[1];
                    if (nx >= 0 && nx < n && ny >= 0 && ny < m){
                        cnt ++;
                        sum += M[nx][ny];
                    }
                }
                ans[i][j] = sum / cnt;
            }
        }
        return ans;
    }

Leetcode 662. Maximum Width of Binary Tree

Problem:

Given a binary tree, write a function to get the maximum width of the given tree. The width of a tree is the maximum width among all levels. The binary tree has the same structure as a full binary tree, but some nodes are null. The width of one level is defined as the length between the end-nodes (the leftmost and right most non-null nodes in the level, where the null nodes between the end-nodes are also counted into the length calculation.

经历了几个版本,其实只需要把每一层的坐标求出来,接着每层更新最小坐标和最大坐标即可,代码如下:

代码语言:javascript
复制
    public int widthOfBinaryTree(TreeNode root) {
        if (root == null) return 0;
        map = new HashMap<>();
        dfs(root, 0, 0);
        int max = 0;
        for (int key : map.keySet()){
            Pair p = map.get(key);
            max = Math.max(max, p.max - p.min + 1);
        }
        return max;
    }

    class Pair{
        int min;
        int max;
        public Pair(){
            this.min = Integer.MAX_VALUE;
            this.max = Integer.MIN_VALUE;
        }
    }

    Map<Integer, Pair> map;
    public void dfs(TreeNode root, int layer, int pos){
        if (root == null) return;
        if (!map.containsKey(layer)) map.put(layer, new Pair());
        Pair p = map.get(layer);
        p.min = Math.min(p.min, pos);
        p.max = Math.max(p.max, pos);
        dfs(root.left, layer + 1, pos * 2);
        dfs(root.right, layer + 1, pos * 2 + 1);
    }

Leetcode 663. Equal Tree Partition

Problem:

Given a binary tree with n nodes, your task is to check if it’s possible to partition the tree to two trees which have the equal sum of values after removing exactly one edge on the original tree.

思路:求出sum,如果为奇数则不可能划分,否则找出sum / 2的子树。切割一条边,可以看作是该边所连结点下的子树和是否等于sum / 2,代码如下:

代码语言:javascript
复制
    public boolean checkEqualTree(TreeNode root) {
        if (root.left == null && root.right == null) return false;
        list = new HashSet<>();
        int sum = find(root);
        if (sum % 2 != 0) return false;
        int key = sum / 2;
        return list.contains(key);
    }

    Set<Integer> list;
    public int find(TreeNode root){
        if (root == null) return 0;
        int left = find(root.left);
        int right = find(root.right);
        list.add(left + right + root.val);
        return left + right + root.val;
    }

官方更新了最新的测试数据,上述代码bug了,具体bug样例为0,-1,1,关键在于sum = 0的情况,需要加个特判,代码如下:

代码语言:javascript
复制
    public boolean checkEqualTree(TreeNode root) {
        list = new HashMap<>();
        int sum = find(root);
        if (sum % 2 != 0) return false;
        int key = sum / 2;
        return (sum != 0 && list.containsKey(key)) || ( sum == 0 && list.get(sum) >= 2);
    }

    Map<Integer, Integer> list;
    public int find(TreeNode root){
        if (root == null) return 0;
        int left = find(root.left);
        int right = find(root.right);
        int sum = left + right + root.val;
        list.put(sum, list.getOrDefault(sum, 0) + 1);
        return sum;
    }

Leetcode 664. Strange Printer

Problem:

here is a strange printer with the following two special requirements:

  • The printer can only print a sequence of the same character each time.
  • At each turn, the printer can print new characters starting from and ending at any places, and will cover the original existing characters.

Given a string consists of lower English letters only, your job is to count the minimum number of turns the printer needed in order to print it.

Example 1:

Input: “aaabbb” Output: 2 Explanation: Print “aaa” first and then print “bbb”.

Example 2:

Input: “aba” Output: 2 Explanation: Print “aaa” first and then print “b” from the second place of the string, which will cover the existing character ‘a’.

思路:

就拿aba来说,最优路径是aaa -> b,所以对于打印机来说,打印单个a和多个a的代价是一样的,在考虑问题时,直接打印多个即可。那么接下来就要找出代价会变小的原因。

代码语言:javascript
复制
aabb
方案1: aaaa -> bb
方案2: aa —> bb
方案1与方案2等价

aaba
方案1: aaaa —> b
方案2: aa -> b -> a
方案1优于方案2 

所以找到了优化准则:
对于被a包裹的子问题b可以用递归求解,那么问题就变成了,如何遍历所有可能的包裹方案。

用dpi表示在某个区间内的最小代价, 现在假设第i个位置的字符为a,那么在i和j的范围内,找寻下一个字符为a,记作下标为m,则可以将问题划分为:dpi + 1 和 dpm,代码如下:

代码语言:javascript
复制
    int[][] dp = new int[101][101];
    public int strangePrinter(String s) {
        for (int i = 0; i < 101; ++i){
            for (int j = 0; j < 101; ++j){
                    dp[i][j] = -1;
            }
        }
        return f(s.toCharArray(), 0, s.length() - 1, dp);
    }

    public int f(char[] cs, int i, int j, int[][] dp){
        if (i > j) return 0;
        if (dp[i][j] > 0) return dp[i][j];
        for (;i + 1 <= j && cs[i] == cs[i + 1]; ++i);
        int res = 1 + f(cs, i + 1, j, dp);
        for (int m = i + 1; m <= j; ++m){
            if (cs[m] == cs[i]){
                res = Math.min(res, f(cs, i + 1, m - 1, dp) + f(cs, m, j, dp));
            }
        }
        return dp[i][j] = res;
    }

迭代方案:

代码语言:javascript
复制
    public int strangePrinter(String s) {
        int[][] dp = new int[101][101];
        int n = s.length();
        if (n == 0) return 0;
        char[] cs = s.toCharArray();
        for (int i = 0; i < n; ++i) dp[i][i] = 1;
        for (int i = n - 1; i >= 0; --i){
            for (int j = i + 1; j < n; ++j){
                dp[i][j] = dp[i + 1][j] + 1;
                char c = cs[i];
                for (int k = i; k < j; ++k){
                    if (cs[k + 1] == c) dp[i][j] = Math.min(dp[i][j], dp[i][k] + dp[k + 1][j] - 1);
                }
            }
        }
        return dp[0][n - 1];
    }
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017年08月21日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • LeetCode Weekly Contest 46解题思路
    • 赛题
      • Leetcode 661. Image Smoother
        • Leetcode 662. Maximum Width of Binary Tree
          • Leetcode 663. Equal Tree Partition
            • Leetcode 664. Strange Printer
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档