LeetCode第164场竞赛题解

deadline压得人喘不过气

上周竞赛没有参加,555我好菜

题目链接

概述

总的来说,这周竞赛是我做过的最简单的一次,前三道都是阅读理解,倒数第二道题也可以用字典树+BFS,最后一道题可以用dp,考虑到大数问题后完美解决。

5271. 访问所有点的最小时间

这个题属于找规律,我们容易发现:从一个点到另一个点的最小距离即使两个点坐标差的最小值

通过点去求面,用到了贪心的思想

public int minTimeToVisitAllPoints(int[][] points) {
    int tx, ty;
    int count = 0;
    for(int i = 1; i < points.length; i ++) {
        tx = Math.abs(points[i][0] - points[i-1][0]);
        ty = Math.abs(points[i][1] - points[i-1][1]);
        count += ty > tx ? ty : tx;
    }
    return count;
}

5272. 统计参与通信的服务器

这个也是传说中的阅读理解题,根据我们最直观的理解:

先横着遍历,如果有超过2台服务器,则把其个数加到返回值中,再纵向遍历,如果有超过两台服务器,且没有被统计上,则把其个数加到返回值中

public int countServers(int[][] grid) {
    int count = 0;
    int roLen = grid.length;
    int coLen = grid[0].length;
    int[] flag = new int[roLen];
    // 横向遍历
    for(int i = 0; i < roLen; i ++) {
        int num = 0;
        for(int j = 0; j < coLen; j ++) {
            if(grid[i][j] == 1) num ++;
        }
        if(num > 1) {
            count += num;
            // 标记已经遍历过的行
            flag[i] = 1;
        }
    }
    // 纵向遍历
    for(int i = 0; i < coLen; i ++) {
        int num = 0;
        int nflag = 0;
        for(int j = 0; j < roLen; j ++) {
            if(grid[j][i] == 1) {
                num ++;
                // 如果该服务器所在的那一行被遍历过,即该服务器被遍历过
                if(flag[j] == 1) nflag ++;
            }
        }
        if(num > 1) {
            count += num - nflag;
        }
    }
    return count;
}

5273. 搜索推荐系统

这个题可以取巧,用Java自带的Arrays.sort(),来进行字典序的排序。

有两种方法,第一种是非常经典的字典树+DFS,第二种是阅读理解。当然我可能阅读理解比较好,通过Java自带的API直接AC了hhhh

  1. 利用sort()方法,阅读理解做题

    • 遍历products的每个商品,并找出首字符和searchWord匹配的单词,这里我取了个巧:

      for(int i = 0; i < searchLen; i ++) {
          // 取巧点
          int point = 0;
          List<String> sugPro = new ArrayList<>(3);
          for(int j = 0; j < productLen; j ++) {
              if(i < products[j].length() && searchWord.charAt(i) == products[j].charAt(i)) {
                  products[point ++] = products[j];
              }
          }
      }
      
    • 之后,我们再对我们找到的新的products进行排序,排完序之后就是可以加入List中了

      Arrays.sort(products, 0, point);
      for(int j = 0; j < point && j < 3; j ++) {
          sugPro.add(products[j]);
      }
      
    • 然后,在新的products的基础上重新开始循环,来找与searchWord匹配的第二个字符的单词

    public List<List<String>> suggestedProducts(String[] products, String searchWord) {
        int searchLen = searchWord.length();
        int productLen = products.length;
        List<List<String>> sugPros = new ArrayList<>(searchLen);
        for(int i = 0; i < searchLen; i ++) {
            int point = 0;
            List<String> sugPro = new ArrayList<>(3);
            for(int j = 0; j < productLen; j ++) {
                if(i < products[j].length() && searchWord.charAt(i) == products[j].charAt(i)) {
                    products[point ++] = products[j];
                }
            }
            Arrays.sort(products, 0, point);
            for(int j = 0; j < point && j < 3; j ++) {
                sugPro.add(products[j]);
            }
            productLen = point;
            sugPros.add(sugPro);
        }
        return sugPros;
    }
    
  2. 字典树+DFS

    什么是字典树

    public class SearchSuggestionsSystem {
        private class TrieNode{
            boolean end = false;
            String str = null;
            int count = 0;
            TrieNode[] children = new TrieNode[26];
        }
    
        private class Trie{
            TrieNode root = new TrieNode();
            public void insert(String[] products){
                for(String str : products){
                    insertWord(str);
                }
            }
            private void insertWord(String products){
                TrieNode node = root;
                for(char c : products.toCharArray()){
                    if(node.children[c - 'a'] == null){
                        node.children[c - 'a'] = new TrieNode();
                    }
                    node = node.children[c - 'a'];
                }
                if(node.end != true){
                    node.end = true;
                    node.str = products;
                }
                node.count++;
            }
            public List<List<String>> searchWord(String word){
                List<List<String>> result = new ArrayList<>();
                for(int i = 1; i <= word.length(); i++){
                    result.add(search(word.substring(0, i)));
                }
                return result;
            }
            private List<String> search(String pattern){
                List<String> result = new ArrayList<>();
                TrieNode node = root;
                for(char c : pattern.toCharArray()){
                    if(node.children[c - 'a'] == null){
                        return result;
                    }
                    node = node.children[c - 'a'];
                }
                Solution(node, result);
                return result;
            }
            private void Solution(TrieNode root, List<String> result){
                if(root.end){
                    for(int i = 0; i < root.count; i++){
                        result.add(root.str);
                        if(result.size() == 3){
                            return;
                        }
                    }
                }
                for(TrieNode node : root.children){
                    if(node != null){
                        Solution(node, result);
                    }
                    if(result.size() == 3){
                        return;
                    }
                }
            }
        }
    
        public List<List<String>> suggestedProducts(String[] products, String searchWord) {
            Trie trie = new Trie();
            trie.insert(products);
            return trie.searchWord(searchWord);
        }
    }
    

5274. 停在原地的方案数

这个题第一眼我觉得是可以用dfs,但是看看好像也可以用dp,所以就试了试dp。把x作为步数,把y作为数组长度。我们要考虑一个问题就是大数问题,起初我为了省事,最后才mod,结果总是不对,还是要算出一个就mod稳当

public int numWays(int steps, int arrLen) {
    int mod = 1_000_000_007;
    if(steps < arrLen) arrLen = steps;
    long[][] dp = new long[steps + 1][arrLen];
    dp[0][0] = 1;
    for(int i = 1; i <= steps; i ++) {
        for(int j = 0; j < arrLen; j ++) {
            if(j == arrLen - 1 && j == 0) dp[i][j] = dp[i - 1][j] % mod;
            else if(j == arrLen - 1) dp[i][j]  = (dp[i - 1][j - 1] + dp[i - 1][j]) % mod;
            else if(j == 0) dp[i][j] = (dp[i - 1][j + 1] + dp[i - 1][j])% mod;
            else dp[i][j] = (dp[i - 1][j - 1] + dp[i - 1][j + 1] + dp[i - 1][j]) % mod;
        }
    }
    return (int) (dp[steps][0]);
}
发布了100 篇原创文章 · 获赞 142 · 访问量 17万+

猜你喜欢

转载自blog.csdn.net/coder_what/article/details/103226704