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
-
利用
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; }
-
-
字典树+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]);
}