LeetCode Weekly Contest 第 251 场周赛解题报告 刷题解法

卖大米 2021-7-26 291


【 NO.1 字符串转化后的各位数字之和】

解题思路

循环 k 次加和即可。

代码展示

class Solution {

    public int getLucky(String s, int k) {

        String s2 = "";

        for (int i = 0; i < s.length(); i++) {

            s2 += String.valueOf((int) (s.charAt(i) - 'a' + 1));

        }

        int result = 0;

        for (int i = 0; i < k; i++) {

            result = 0;

            for (int j = 0; j < s2.length(); j++) {

                result += s2.charAt(j) - '0';

            }

            s2 = String.valueOf(result);

        }

        return result;

    }

}

【 NO.2 子字符串突变后可能得到的最大整数】

解题思路

贪心,这个子串的起点要尽可能得靠左,并且突变后一定要变大。

代码展示

class Solution {

    public String maximumNumber(String num, int[] change) {

        StringBuilder result = new StringBuilder();

        int status = 0;

        for (int i = 0; i < num.length(); i++) {

            char oldChar = num.charAt(i);

            char newChar = (char) (change[oldChar - '0'] + '0');

            if (status == 2) { // status == 2 表示已经结束了突变,直接使用 oldChar

                result.append(oldChar);

            } else if (status == 1) { // status == 1 表示正在突变,进行对比,决定是否结束突变

                if (oldChar <= newChar) {

                    result.append(newChar);

                } else {

                    result.append(oldChar);

                    status = 2;

                }

            } else if (status == 0) { // status == 0 表示还没开始突变,进行对比,决定是否开始突变  

                if (oldChar < newChar) {

                    result.append(newChar);

                    status = 1;

                } else {

                    result.append(oldChar);

                }

            }

        }

        return result.toString();

    }

}

【 NO.3 最大兼容性评分和】

解题思路

回溯,枚举所有的可能性即可。

代码展示

class Solution {

    int max;

    public int maxCompatibilitySum(int[][] students, int[][] mentors) {

        max = 0;

        boolean[] vis = new boolean[mentors.length];

        int[][] compat = new int[students.length][mentors.length];

        for (int i = 0; i < students.length; i++) {

            for (int j = 0; j < mentors.length; j++) {

                for (int k = 0; k < students[0].length; k++) {

                    if (students[i][k] == mentors[j][k]) {

                        compat[i][j]++;

                    }

                }

            }

        }

        dfs(0, 0, compat, students.length, students[0].length, vis);

        return max;

    }

    void dfs(int stu, int sum, int[][] compat, int n, int m, boolean[] vis) {

        max = Math.max(max, sum);

        // 剪枝优化:若后面的学生每对儿都是最大匹配度,也不及当前的最优解,则不必要再继续递归

        if (stu == n || sum + (n - stu) * m <= max) {

            return;

        }

        for (int i = 0; i < n; i++) {

            if (!vis[i]) {

                vis[i] = true;

                dfs(stu + 1, sum + compat[stu][i], compat, n, m, vis);

                vis[i] = false;

            }

        }

    }

}

【 NO.4 删除系统中的重复文件夹】

解题思路

Hash

文件目录系统是树结构,为每棵子树计算哈希值,最后将哈希值相同的子树删掉即可。

计算哈希的方法比较多,最简单的可以直接转换成 JSON 字符串,但是效率略低。可以利用子节点的哈希值计算当前节点的哈希值,效率较高。

代码展示

class Solution {

    static class Node {

        boolean deleted;

        int hash;

        TreeMap<String, Node> children = new TreeMap<>();

    }

    private final Node root;

    private final Map<String, Integer> hash;

    private final Map<Integer, Integer> count;

    public Solution() {

        root = new Node();

        hash = new HashMap<>();

        count = new HashMap<>();

    }

    public void add(List word) {

        Node node = root;

        for (String i : word) {

            if (!node.children.containsKey(i)) {

                Node child = new Node();

                node.children.put(i, child);

            }

            node = node.children.get(i);

        }

    }

    private void calcHash(Node node) {

        if (node.children.size() == 0) {

            node.hash = 0;

            return;

        }

        StringBuilder sb = new StringBuilder();

        for (var child : node.children.navigableKeySet()) {

            Node childNode = node.children.get(child);

            calcHash(childNode);

            if (sb.length() != 0) {

                sb.append("/");

            }

            sb.append(childNode.hash);

            sb.append(getHash(child));

        }

        node.hash = getHash(sb.toString());

        count.put(node.hash, count.getOrDefault(node.hash, 0) + 1);

    }

    private int getHash(String child) {

        if (!hash.containsKey(child)) {

            hash.put(child, hash.size() + 1);

        }

        return hash.get(child);

    }

    private void delete(Node node) {

        for (var child : node.children.entrySet()) {

            delete(child.getValue());

        }

        if (count.getOrDefault(node.hash, 0) > 1) {

            node.deleted = true;

        }

    }

    private List<List> toList(Node node) {

        List<List> result = new LinkedList<>();

        if (node != root) {

            result.add(new LinkedList<>());

        }

        if (node.children.size() == 0) {

            return result;

        }

        for (var child : node.children.entrySet()) {

            if (child.getValue().deleted) {

                continue;

            }

            List<List> childList = toList(child.getValue());

            for (var l : childList) {

                ((LinkedList) l).addFirst(child.getKey());

                result.add(l);

            }

        }

        return result;

    }

    public List<List> deleteDuplicateFolder(List<List> paths) {

        for (var path : paths) {

            add(path);

        }

        calcHash(root);

        delete(root);

        return toList(root);

    }

}

上岸算法网络科技有限公司是一家致力于用高质量,高互动性小班课程来帮助学生更好的在就业市场中定位以及求职的公司。我们以顶级的课程质量,高互动性的教学方式以及独特的小班教学模式来帮助学生更快的跨过求职的鸿沟,用最高效,经济,合理的方式帮助更多学生快速找到梦寐以求的工作。

最新回复 (0)
返回