LeetCode Weekly Contest 184 解题报告

卖大米 2020-4-12 775


No.1 数组中的字符串匹配

★解题思路

该题目比较简单, 直接枚举即可, 使用 String.contains() 方法来判断一个字符串是否另一个字符串的子串.

有一个小细节, 在判断 sub 是否 word 的子串之前可以先判断长度, 必须严格小于才进一步调用 contains() 方法.

代码展示


class Solution { 
   public List<String> stringMatching(String[] words) { 
       List<String> res = new ArrayList<>(); 
       int n = words.length; 
       for (String sub : words) { 
           // 枚举, 判断 sub 是否某一个字符串的子串 
           for (String word : words) { 
               if (sub.length() < word.length() && word.contains(sub)) { 
                   res.add(sub); 
                   break; 
               } 
           } 
       } 
       return res; 
   } 
}

No.2查询带键的排列

★解题思路

该题目也比较简单, 解释见代码注释.

代码展示


class Solution { 
   public int[] processQueries(int[] queries, int m) { 
       int[] p = new int[m]; 
       for (int i = 0; i < m; i++) { 
           p[i] = i + 1;  
       } 
       int n = queries.length; 
       int[] res = new int[n]; 
       for (int i = 0; i < n; i++) { 
           // 枚举, 查找 queries[i] 在 p 中的位置 
           res[i] = indexOf(p, queries[i]); 
           // 将 p 数组的 [0, res[i]) 的元素向后移动一个位置 
           // 也可以调用 System.arraycopy 完成 
           for (int j = res[i]; j > 0; j--) { 
               p[j] = p[j - 1]; 
           } 
           // 将 queries[i] 放到第一个位置 
           p[0] = queries[i]; 
       } 
       return res; 
   } 

   int indexOf(int[] nums, int val) { 
       for (int i = 0; i < nums.length; i++) { 
           if (nums[i] == val) { 
               return i; 
           } 
       } 
       return -1; 
   } 
}

No.3HTML 实体解析器

★解题思路

只需要做简单的字符串替换即可. 下面的代码的做法是逐个字符处理, 遇到 & 则判断是否题目给定的字符实体之一, 是则进行替换, 否则直接加入到 StringBuilder.

代码展示


class Solution { 
   public String entityParser(String text) { 
       StringBuilder sb = new StringBuilder(); 
       for (int i = 0; i < text.length(); ) { 
           char c = text.charAt(i); 
           if (c != '&') { 
               sb.append(c); 
               i++; 
           } else if (i + 6 <= text.length() &&  
                      """.equals(text.substring(i, i + 6))) { 
               sb.append("\""); 
               i += 6; 
           } else if (i + 6 <= text.length() &&  
                      "'".equals(text.substring(i, i + 6))) { 
               sb.append("'"); 
               i += 6; 
           } else if (i + 5 <= text.length() &&  
                      "&".equals(text.substring(i, i + 5))) { 
               sb.append("&"); 
               i += 5; 
           } else if (i + 4 <= text.length() &&  
                      ">".equals(text.substring(i, i + 4))) { 
               sb.append(">"); 
               i += 4; 
           } else if (i + 4 <= text.length() &&  
                      "<".equals(text.substring(i, i + 4))) { 
               sb.append("<"); 
               i += 4; 
           } else if (i + 7 <= text.length() &&  
                      "⁄".equals(text.substring(i, i + 7))) { 
               sb.append("/"); 
               i += 7; 
           } else { 
               sb.append(c); 
               i++; 
           } 
       } 
       return sb.toString(); 
   } 
}

No.4给 N x 3 网格图涂色的方案数

★解题思路

动态规划问题.

  • 定义状态: dp[i][c1][c2][c3] 表示第 i 列的三个格子颜色为 c1, c2, c3 时, 前 i 列的方案数
  • 状态转移: 枚举上一列所有可能的状态即可, 只要不冲突, 就可以加到当前状态上, 即

dp[i][c1][c2][c3] = sum{ dp[i - 1][d1][d2][d3] } 相邻两列是 c1, c2, c3 和 d1, d2, d3 时颜色不冲突.

  • 初始边界: dp[0][c1][c2][c3] = c1 != c2 && c2 != c3 ? 1 : 0
  • 优化: 可以将 c1, c2, c3 这三维压缩成一维 27, 从而减少循环层数; 还可以使用滚动数组优化空间.

代码展示


class Solution { 
   public int numOfWays(int n) { 
       final int MOD = 1000000007; 
       int[][][][] dp = new int[n][3][3][3]; 
       for (int c1 = 0; c1 < 3; c1++) { 
           for (int c2 = 0; c2 < 3; c2++) { 
               for (int c3 = 0; c3 < 3; c3++) { 
                   dp[0][c1][c2][c3] = c1 != c2 && c2 != c3 ? 1 : 0; 
               } 
           } 
       } 
       for (int i = 1; i < n; i++) { 
           for (int c1 = 0; c1 < 3; c1++) { 
               for (int c2 = 0; c2 < 3; c2++) { 
                   for (int c3 = 0; c3 < 3; c3++) { 
                       for (int d1 = 0; d1 < 3; d1++) { 
                           for (int d2 = 0; d2 < 3; d2++) { 
                               for (int d3 = 0; d3 < 3; d3++) { 
                                   if (c1 == c2 || c2 == c3) continue; 
                                   if (d1 == d2 || d2 == d3) continue; 
                                   if (d1 == c1 || d2 == c2 || d3 == c3) continue; 
                                   dp[i][c1][c2][c3] += dp[i - 1][d1][d2][d3]; 
                                   dp[i][c1][c2][c3] %= MOD; 
                               } 
                           } 
                       } 
                   } 
               } 
           } 
       } 
       int ans = 0; 
       for (int c1 = 0; c1 < 3; c1++) { 
           for (int c2 = 0; c2 < 3; c2++) { 
               for (int c3 = 0; c3 < 3; c3++) { 
                   ans = (ans + dp[n - 1][c1][c2][c3]) % MOD; 
               } 
           } 
       } 
       return ans; 
   } 
}

最新回复 (0)
返回