https://leetcode.com/contest/weekly-contest-145/ranking
1、按照数组排序
public class Leetcode1122 {
public int[] relativeSortArray(int[] arr1, int[] arr2) {
int[] cnt = new int[1001];
for (int x : arr1) cnt[x]++;
int[] r = new int[arr1.length];
int index = 0;
for (int x : arr2) {
for (int j = 0; j < cnt[x]; j++) {
r[index++] = x;
}
cnt[x] = 0;
}
for (int x = 0; x < cnt.length; x++) {
for (int j = 0; j < cnt[x]; j++) {
r[index++] = x;
}
}
return r;
}
}
2、求最大节点它们的公共祖先
解法1:一直求父节点,直到父节点的集合剩下一个就是答案
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
/**
* Created by dezhonger on 2019/7/14
*/
public class Leetcode1123 {
List<Node> nodes = new ArrayList<>();
int maxDepth = -1;
public TreeNode lcaDeepestLeaves(TreeNode root) {
dfs(root, null, 0);
Map<Integer, List<Node>> map =nodes.stream().collect(Collectors.groupingBy(Node::getDepth));
List<Node> nodes = map.get(maxDepth);
while (nodes.size() > 1) {
Set<Node> set = new HashSet<>();
for (Node node : nodes) {
set.add(node.parent);
}
nodes = new ArrayList<>(set);
}
return nodes.get(0).it;
}
private void dfs(TreeNode root, Node parent, int depth) {
if (root == null) return;
maxDepth = Math.max(maxDepth, depth);
Node node = new Node(root, parent, depth);
nodes.add(node);
dfs(root.left, node, depth + 1);
dfs(root.right, node, depth + 1);
}
class Node {
public int getDepth() {
return depth;
}
public Node(TreeNode it, Node parent, int depth) {
this.it = it;
this.parent = parent;
this.depth = depth;
}
TreeNode it;
Node parent;
int depth;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Node node = (Node) o;
return Objects.equals(it, node.it);
}
@Override
public int hashCode() {
return Objects.hash(it);
}
}
}
解法2:前两个先求,拿结果和第三个求,再拿结果和第四个节点求。。
class Solution {
public:
map<TreeNode *, int> depth;
map<TreeNode *, TreeNode *> parent;
int deepest;
void dfs(TreeNode *node, TreeNode *par) {
if (node == nullptr)
return;
parent[node] = par;
depth[node] = par == nullptr ? 0 : depth[par] + 1;
deepest = max(deepest, depth[node]);
dfs(node->left, node);
dfs(node->right, node);
}
TreeNode *lca(TreeNode *a, TreeNode *b) {
while (a != b) {
if (depth[a] < depth[b])
swap(a, b);
a = parent[a];
}
return a;
}
TreeNode* lcaDeepestLeaves(TreeNode* root) {
depth.clear();
parent.clear();
deepest = 0;
dfs(root, nullptr);
vector<TreeNode *> leaves;
for (pair<TreeNode *, int> p : depth)
if (p.second == deepest)
leaves.push_back(p.first);
TreeNode *answer = leaves[0];
for (int i = 1; i < (int) leaves.size(); i++)
answer = lca(answer, leaves[i]);
return answer;
}
};
3、求最长连续的时间,其中大于8的数字个数要严格大于不大于8的数字个数
转化:大于8->1,否则为-1,就是求最大的区间和大于0.
我们维护一个递减的栈,每次在栈里二分答案。
import java.util.ArrayList;
import java.util.List;
/**
* Created by dezhonger on 2019/7/14
*/
public class Leetcode1124 {
public int longestWPI(int[] hours) {
for (int i = 0; i < hours.length; i++) hours[i] = hours[i] > 8 ? 1 : -1;
List<Integer> list = new ArrayList<>();
List<Node> nodes = new ArrayList<>();
list.add(0);
nodes.add(new Node(0, 0));
int ans = 0;
for (int x : hours) {
int val = list.get(list.size() - 1) + x;
list.add(val);
int l = 0;
int r = nodes.size() - 1;
while (l < r) {
int mid = (l + r) / 2;
if (nodes.get(mid).val < val) {
r = mid;
} else {
l = mid + 1;
}
}
if (nodes.get(l).val < val) {
ans = Math.max(ans, list.size() - nodes.get(l).pos - 1);
}
if (val < nodes.get(nodes.size() - 1).val) {
nodes.add(new Node(val, list.size() - 1));
}
}
return ans;
}
class Node {
int val;
int pos;
public Node(int val, int pos) {
this.val = val;
this.pos = pos;
}
}
}
4、给了一个技能列表(<=16),给了一些人(<=60),每个人有其中的一些技能,问选最少的人他们技能的并集为所有的技能
动态规划:技能个数小于16,考虑使用位运算表示一个人的技能
dp[i][bit]表示前i个人中满足技能并集为bit所需要的最少人数,考虑使用刷表法来dp,最后再回溯求出答案
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* Created by dezhonger on 2019/7/15
*/
public class Leetcode1125 {
public int[] smallestSufficientTeam(String[] req_skills, List<List<String>> people) {
int s = req_skills.length;
int n = people.size();
int[] mask = new int[n];
for (int i = 0; i < n; i++) {
for (String skill : people.get(i)) {
int index = -1;
for (int j = 0; j < s; j++) {
if (skill.equals(req_skills[j])) {
index = j;
break;
}
}
if (index >= 0) mask[i] |= 1 << index;
}
}
int[][] dp = new int[n + 1][1 << s];
for (int i = 0; i <= n; i++) Arrays.fill(dp[i], 200000);
dp[0][0] = 0;
for (int i = 0; i < n; i++) {
for (int bit = 0; bit < 1 << s; bit++) {
dp[i + 1][bit] = Math.min(dp[i + 1][bit], dp[i][bit]);
dp[i + 1][bit | mask[i]] = Math.min(dp[i + 1][bit | mask[i]], dp[i][bit] + 1);
}
}
int current = (1 << s) - 1;
List<Integer> res = new ArrayList<>();
for (int i = n - 1; i >= 0; i--) {
int next_bit = -1;
for (int m = 0; m < 1 << s; m++) {
if ((current | m) == current && (m | mask[i]) == current && dp[i][m] + 1 == dp[i + 1][current]) {
next_bit = m;
break;
}
}
if (next_bit >= 0) {
res.add(i);
current = next_bit;
}
}
int[] r = new int[res.size()];
for (int i = 0; i < r.length; i++) r[i] = res.get(r.length - 1 - i);
return r;
}
}