关于算法:上岸算法LeetCode-Weekly-Contest-264解题报告

6次阅读

共计 2561 个字符,预计需要花费 7 分钟才能阅读完成。

【NO.1 句子中的无效单词数】

解题思路
签到题。

代码展现

class Solution {
public int countValidWords(String sentence) {

   String[] words = sentence.split(" ");
   int count = 0;
   for (var word : words) {char[] chars = word.trim().toCharArray();
       boolean invalid = false;
       int index = -1;
       for (int i = 0; i < chars.length && !invalid; i++) {char c = chars[i];
           if ('0' <= c && c <= '9') {invalid = true;} else if (c == '-') {if (index == -1) {index = i;} else {invalid = true;}
          } else if (isNotAlpha(c) && i != chars.length - 1) {invalid = true;}
      }
       if (invalid || index == 0 || index == chars.length - 1) {continue;}
       if (index > 0 && (isNotAlpha(chars[index - 1]) || isNotAlpha(chars[index + 1]))) {continue;}
       count++;
  }
   return count;

}

boolean isNotAlpha(char c) {

   return 'a' > c || c > 'z';

}

}

【NO.2 下一个更大的数值均衡数】

解题思路
枚举即可。

代码展现

class Solution {
public int nextBeautifulNumber(int n) {

   for (int i = n + 1; ; i++) {if (balance(i)) {return i;}
  }

}

private boolean balance(int num) {

   int[] cnt = new int[10];
   for (; num > 0; num /= 10) {cnt[num % 10]++;
  }
   for (int i = 0; i < 10; i++) {if (cnt[i] != 0 && cnt[i] != i) {return false;}
  }
   return true;

}
}

【NO.3 统计最高分的节点数目】

解题思路
首先进行一次 DFS 求出每个节点的子树大小,而后进行一次 DFS 求出每个节点的分数。

留神计算分数须要用 Long 类型,防止乘法溢出。

代码展现

class Solution {
Long maxScore;
Map<Long, Integer> count;

public int countHighestScoreNodes(int[] parents) {

   List<List<Integer>> children = new ArrayList<>();
   for (int i = 0; i < parents.length; i++) {children.add(new ArrayList<>());
  }
   for (int i = 1; i < parents.length; i++) {children.get(parents[i]).add(i);
  }
   int[] sum = new int[parents.length];
   calcSum(0, sum, children);
   maxScore = 0L;
   count = new HashMap<>();
   calcMaxScore(0, sum, children);
   return count.get(maxScore);

}

private void calcMaxScore(int cur, int[] sum, List<List<Integer>> children) {

   long score = 1;
   for (var nxt : children.get(cur)) {score *= sum[nxt];
  }
   if (sum[0] - sum[cur] > 0) {score *= sum[0] - sum[cur];
  }
   count.put(score, count.getOrDefault(score, 0) + 1);
   maxScore = Math.max(maxScore, score);
   for (var nxt : children.get(cur)) {calcMaxScore(nxt, sum, children);
  }

}

private void calcSum(int cur, int[] sum, List<List<Integer>> children) {

   sum[cur] = 1;
   for (var nxt : children.get(cur)) {calcSum(nxt, sum, children);
       sum[cur] += sum[nxt];
  }

}
}

【NO.4 并行课程 III】

解题思路
简直是树型 DP 模板题,比较简单。令 finish(i) 示意实现课程 i 的最短时间,则 finish(i) = max(finish(j)) + time[i],其中 j 是 i 的前置课程。

代码展现

class Solution {
public int minimumTime(int n, int[][] relations, int[] time) {

   List<List<Integer>> prev = new ArrayList<>();
   for (int i = 0; i < n; i++) {prev.add(new ArrayList<>());
  }
   for (int[] rel : relations) {prev.get(rel[1] - 1).add(rel[0] - 1);
  }
   int[] mem = new int[n];
   int result = 0;
   for (int i = 0; i < n; i++) {result = Math.max(result, finish(i, prev, time, mem));
  }
   return result;

}

private int finish(int cur, List<List<Integer>> prev, int[] time, int[] mem) {

   if (mem[cur] > 0) {return mem[cur];
  }
   if (prev.get(cur).size() == 0) {return time[cur];
  }
   for (int p : prev.get(cur)) {mem[cur] = Math.max(mem[cur], finish(p, prev, time, mem) + time[cur]);
  }
   return mem[cur];

}
}

正文完
 0