Leetcode刷题 2021.01.15
Leetcode1029 两地调度
公司计划面试 2N 人。第 i 人飞往 A 市的费用为 costs[i][0],飞往 B 市的费用为 costsi。
返回将每个人都飞到某座城市的最低费用,要求每个城市都有 N 人抵达。
明天要论文预答辩了,感觉都没时间刷题了,难道只坚持一个礼拜就要放弃了每日更新博客了(lll¬ω¬)。
这道题相通了编码还是容易的,既然每个人必须要去A或B里面的一个。就先对每个人去A和B的费用的绝对差进行排序。然后贪心地选择费用小的就行了。
class Solution {
public int twoCitySchedCost(int[][] costs) {
//对费用差贪心地排序
Arrays.sort(costs, (x, y) -> (Math.abs(y[0] - y[1]) - Math.abs(x[0] - x[1])));
int n = costs.length, a = 0, b = 0, index = 0, res = 0;
//遍历数组,选择价值小的加到res
while (a < n / 2 && b < n / 2){
if (costs[index][0] <= costs[index][1]){
a++;
res += costs[index][0];
}else{
b++;
res += costs[index][1];
}
index++;
}
//有一个没加完,就继续加
while (a < n / 2){
res += costs[index][0];
a++;
index++;
}
while (b < n / 2){
res += costs[index][1];
b++;
index++;
}
return res;
}
}
Leetcode1609 奇偶数
如果一棵二叉树满足下述几个条件,则可以称为 奇偶树 :
二叉树根节点所在层下标为 0 ,根的子节点所在层下标为 1 ,根的孙节点所在层下标为 2 ,依此类推。
偶数下标 层上的所有节点的值都是 奇 整数,从左到右按顺序 严格递增
奇数下标 层上的所有节点的值都是 偶 整数,从左到右按顺序 严格递减
给你二叉树的根节点,如果二叉树为 奇偶树 ,则返回 true ,否则返回 false 。
二叉树层序遍历的变形。其实也没怎么变,多加了两个条件而已,比较简单。
class Solution {
public boolean isEvenOddTree(TreeNode root) {
//记录层数
int level = 0;
//队列用来BFS
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()){
int n = queue.size();
//初始化prev
int prev = level % 2 == 0 ? Integer.MIN_VALUE : Integer.MAX_VALUE;
for(int i = 0; i < n; i++){
TreeNode temp = queue.poll();
//判断两个条件
if (level % 2 == 0){
if (temp.val <= prev || temp.val % 2 == 0) return false;
}else{
if (temp.val >= prev || temp.val % 2 != 0) return false;
}
prev = temp.val;
//不为空就加到队列里面
if (temp.left != null) queue.offer(temp.left);
if (temp.right != null) queue.offer(temp.right);
}
level++;
}
return true;
}
}
Leetcode947 移除最多的同行或同列石头
n 块石头放置在二维平面中的一些整数坐标点上。每个坐标点上最多只能有一块石头。
如果一块石头的 同行或者同列 上有其他石头存在,那么就可以移除这块石头。
给你一个长度为 n 的数组 stones ,其中 stones[i] = [xi, yi] 表示第 i 块石头的位置,返回 可以移除的石子 的最大数量。
今天每日一题,又是并查集。稍微变种了一点,其实一开始想不到并查集,以为要贪心。但是后面想了想这个月是图论月,会不会又是并查集,就想出来了。不过有点技巧还不会,代码参考了官方题解。思路就是如果横坐标或者纵坐标相同,就归为一类,然后左边有范围限制,所以可以让x+10000,这样就不会与y重合了。合并的时候就合并每一个节点的两个坐标就行了。
class Solution {
public int removeStones(int[][] stones) {
UnionFind uf = new UnionFind();
//x+10000,就不会余y重合了
for(int[] stone : stones){
uf.union(stone[0] + 10000, stone[1]);
}
int count = 0;
//找一下一共有几个类
for(Integer key : uf.map.keySet()){
if (uf.find(key) == key){
count++;
}
}
//返回n - count即可
return stones.length - count;
}
class UnionFind{
//不知道有几个,用map来代替数组
Map<Integer, Integer> map;
public UnionFind(){
map = new HashMap<>();
}
public int find(int i){
if (!map.containsKey(i)){
map.put(i, i);
}
if (map.get(i) == i){
return i;
}
map.put(i, find(map.get(i)));
return map.get(i);
}
public void union(int i, int j){
int root1 = find(i);
int root2 = find(j);
if (root1 == root2) return;
map.put(root1, root2);
}
}
}