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);
        }
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值