leetcode每日一题 1601. 最多可达成的换楼请求数目 二进制枚举(状态压缩) 绝对通俗易通哦~

本篇内容:leetcode每日一题 1601. 最多可达成的换楼请求数目 二进制枚举(状态压缩)

文章专栏:leetcode每日一题《打卡日常》

最近更新:2022年2月25日 leetcode每日一题 2016. 增量元素之间的最大差值 简单模拟 一题三解两做~

个人简介:一只二本院校在读的大三程序猿,本着注重基础,打卡算法,分享技术作为个人的经验总结性的博文博主,虽然可能有时会犯懒,但是还是会坚持下去的,如果你很喜欢博文的话,建议看下面一行~(疯狂暗示QwQ)

点赞 收藏 ⭐留言 一键三连 关爱程序猿,从你我做起

本文目录

  • 写在前面
  • 题目
    • 示例
    • 提示
    • 思路
    • ⭐代码实现⭐
    • 运行结果
  • 写在最后

写在前面

新学期,新气象,开学第一天,二月最后一天,果然是困难题呀,不过小付也为了加深思维学习,励志争取看懂每一道力扣的困难题解来加深思维,扩展算法思想,就酱紫吧,冲冲冲,也为以后AC一场周赛做准备。

题目

我们有n栋楼,编号从0 到 n - 1。每栋楼有若干员工。由于现在是换楼的季节,部分员工想要换一栋楼居住。

给你一个数组 requests ,其中requests[i] = [fromi, toi],表示一个员工请求从编号为 fromi 的楼搬到编号为 toi 的楼

一开始 所有楼都是满的,所以从请求列表中选出的若干个请求是可行的需要满足 每栋楼员工净变化为 0 。意思是每栋楼 离开 的员工数目等于该楼 搬入 的员工数数目。比方说 n = 3 且两个员工要离开楼 0 ,一个员工要离开楼 1 ,一个员工要离开楼 2 ,如果该请求列表可行,应该要有两个员工搬入楼 0 ,一个员工搬入楼 1 ,一个员工搬入楼 2 。

请你从原请求列表中选出若干个请求,使得它们是一个可行的请求列表,并返回所有可行列表中最大请求数目。

示例

示例1:
leetcode每日一题 1601. 最多可达成的换楼请求数目 二进制枚举(状态压缩) 绝对通俗易通哦~_第1张图片

输入:n = 5, requests = [[0,1],[1,0],[0,1],[1,2],[2,0],[3,4]]
输出:5
解释:请求列表如下:
从楼 0 离开的员工为 x 和 y ,且他们都想要搬到楼 1 。
从楼 1 离开的员工为 a 和 b ,且他们分别想要搬到楼 2 和 0 。
从楼 2 离开的员工为 z ,且他想要搬到楼 0 。
从楼 3 离开的员工为 c ,且他想要搬到楼 4 。
没有员工从楼 4 离开。
我们可以让 x 和 b 交换他们的楼,以满足他们的请求。
我们可以让 y,a 和 z 三人在三栋楼间交换位置,满足他们的要求。
所以最多可以满足 5 个请求。

示例2:
leetcode每日一题 1601. 最多可达成的换楼请求数目 二进制枚举(状态压缩) 绝对通俗易通哦~_第2张图片

输入:n = 3, requests = [[0,0],[1,2],[2,1]]
输出:3
解释:请求列表如下:
从楼 0 离开的员工为 x ,且他想要回到原来的楼 0 。
从楼 1 离开的员工为 y ,且他想要搬到楼 2 。
从楼 2 离开的员工为 z ,且他想要搬到楼 1 。
我们可以满足所有的请求。

示例3:

输入:n = 4, requests = [[0,3],[3,1],[1,2],[2,0]]
输出:4

提示

1 <= n <= 20
1 <= requests.length <= 16
requests[i].length == 2
0 <= fromi, toi < n

思路

本题考查知识点

  • 思路:根据三叶姐姐的思路:二进制枚举(状压)来进行求解的,这里我们假设共有 m 个人提出请求,m = requests.length我们可以知道对于每个人请求都是有两种状态的接受 / 不接受 更换宿舍的请求 , 接受 / 不接受当前请求对于其他人的请求 也是相互独立开来的 ,换句话说 每个人 有 2 种状态,但是m个人就有 2 ^ m 种状态。 我们默认 当前状态在二进制中表示末位为1时 ,则认为接受了请求, 这样一来呢,我们很清楚的就知道了 对于一个状态而言对应二进制中 1 的个数就代表了我们的当前状态下 接受了请求的个数 。理解了上述,对于这道题就成功了一大半了,剩下就是对思路的实现。

⭐代码实现⭐

二进制模拟(状态压缩)

class Solution {
    public int maximumRequests(int n, int[][] requests) {
        // 获取提出更换请求的员工个数
        int m = requests.length;
        // max 代表的是员工的状态 -----> 员工请求的请求可以被接受 / 不接受 每个员工有两种状态 那么就有 2^m 次种状态结果
        int maxStatus = 1 << m, res = 0;
        // 记录是否成功接受请求的数组
        int[] netChangeArr = new int[n];

        // 枚举所有状态,二进制中 1 的个数为当前状态的请求个数
        for (int i = 0; i < maxStatus; i++) {
            int[] tmp = new int[n];
            int state = i;
            // 用于记录当前的员工请求下标
            int idx = 0;
            // 用于记录当前状态下的接受的请求个数
            int cnt = 0;
            // 用于获取当前状态中二进制数字中1的个数
            while (state > 0) {
                // 判断最后一位是否为1
                int isAccept = state & 1;
                // 如果为 1 则说明了当前状态被接受了 需要记录住房情况
                if (isAccept == 1) {
                    // 获取需要从哪里 搬到 哪里的位置信息
                    int from = requests[idx][0];
                    int to = requests[idx][1];
                    // 记录住房净变化
                    tmp[from]--;
                    tmp[to]++;
                    cnt++;
                }
                // 获取前一个员工的状态请求情况
                state >>= 1;
                idx++;
            }
            // 根据我们上面完成得到记录住房变化 需要满足每栋楼员工净变化为 0
            // 滚动获取最大值
            if (Arrays.equals(tmp, netChangeArr)) {
                res = Math.max(res,cnt);
            }
        }
        return res;
    }
}

运行结果

二进制模拟(状态压缩)
leetcode每日一题 1601. 最多可达成的换楼请求数目 二进制枚举(状态压缩) 绝对通俗易通哦~_第3张图片

写在最后

2022-2-28今天小付打卡了哦~

美好的日出 美好的山河

都因有你存在 而璀璨 耀眼

在这里插入图片描述

你可能感兴趣的:(leetcode,算法,职场和发展)