LeetCode 2016. 增量元素之间的最大差值 / 553. 最优除法 / 1601. 最多可达成的换楼请求数目(枚举+回溯)
Posted Zephyr丶J
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 2016. 增量元素之间的最大差值 / 553. 最优除法 / 1601. 最多可达成的换楼请求数目(枚举+回溯)相关的知识,希望对你有一定的参考价值。
2016. 增量元素之间的最大差值
2022.2.26 每日一题
题目描述
给你一个下标从 0 开始的整数数组 nums ,该数组的大小为 n ,请你计算 nums[j] - nums[i] 能求得的 最大差值 ,其中 0 <= i < j < n 且 nums[i] < nums[j] 。
返回 最大差值 。如果不存在满足要求的 i 和 j ,返回 -1 。
示例 1:
输入:nums = [7,1,5,4]
输出:4
解释:
最大差值出现在 i = 1 且 j = 2 时,nums[j] - nums[i] = 5 - 1 = 4 。
注意,尽管 i = 1 且 j = 0 时 ,nums[j] - nums[i] = 7 - 1 = 6 > 4 ,但 i > j 不满足题面要求,所以 6 不是有效的答案。
示例 2:
输入:nums = [9,4,3,2]
输出:-1
解释:
不存在同时满足 i < j 和 nums[i] < nums[j] 这两个条件的 i, j 组合。
示例 3:
输入:nums = [1,5,2,10]
输出:9
解释:
最大差值出现在 i = 0 且 j = 3 时,nums[j] - nums[i] = 10 - 1 = 9 。
提示:
n == nums.length
2 <= n <= 1000
1 <= nums[i] <= 10^9
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/maximum-difference-between-increasing-elements
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
记录当前最小值,然后记录最大的差值
class Solution
public int maximumDifference(int[] nums)
int n = nums.length;
int min = nums[0];
int diff = -1;
for(int i = 1; i < n; i++)
if(nums[i] < min)
min = nums[i];
else if(nums[i] > min)
diff = Math.max(diff, nums[i] - min);
return diff;
553. 最优除法
2022.2.27 每日一题
题目描述
给定一组正整数,相邻的整数之间将会进行浮点除法操作。例如, [2,3,4] -> 2 / 3 / 4 。
但是,你可以在任意位置添加任意数目的括号,来改变算数的优先级。你需要找出怎么添加括号,才能得到最大的结果,并且返回相应的字符串格式的表达式。你的表达式不应该含有冗余的括号。
示例:
输入: [1000,100,10,2]
输出: “1000/(100/10/2)”
解释:
1000/(100/10/2) = 1000/((100/10)/2) = 200
但是,以下加粗的括号 “1000/((100/10)/2)” 是冗余的,
因为他们并不影响操作的优先级,所以你需要返回 “1000/(100/10/2)”。
其他用例:
1000/(100/10)/2 = 50
1000/(100/(10/2)) = 50
1000/100/10/2 = 0.5
1000/100/(10/2) = 2
说明:
输入数组的长度在 [1, 10] 之间。
数组中每个元素的大小都在 [2, 1000] 之间。
每个测试用例只有一个最优除法解。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/optimal-division
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
要使得除数最小,就是一直除就除数最小
class Solution
public String optimalDivision(int[] nums)
//要最大的结果,就是要最小的除数,
//那么怎么才能让后面的除数最小呢,就是一直除就可以了
int n = nums.length;
if(n == 1)
return nums[0] + "";
if(n == 2)
return nums[0] + "/" + nums[1];
String res = nums[0] + "/" + "(";
for(int i = 1; i < n - 1; i++)
res = res + nums[i] + "/";
res = res + nums[n - 1] + ")";
return res;
1601. 最多可达成的换楼请求数目
2022.2.28 每日一题
题目描述
我们有 n 栋楼,编号从 0 到 n - 1 。每栋楼有若干员工。由于现在是换楼的季节,部分员工想要换一栋楼居住。
给你一个数组 requests ,其中 requests[i] = [fromi, toi] ,表示一个员工请求从编号为 fromi 的楼搬到编号为 toi 的楼。
一开始 所有楼都是满的,所以从请求列表中选出的若干个请求是可行的需要满足 每栋楼员工净变化为 0 。意思是每栋楼 离开 的员工数目 等于 该楼 搬入 的员工数数目。比方说 n = 3 且两个员工要离开楼 0 ,一个员工要离开楼 1 ,一个员工要离开楼 2 ,如果该请求列表可行,应该要有两个员工搬入楼 0 ,一个员工搬入楼 1 ,一个员工搬入楼 2 。
请你从原请求列表中选出若干个请求,使得它们是一个可行的请求列表,并返回所有可行列表中最大请求数目。
示例 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:
输入: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
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/maximum-number-of-achievable-transfer-requests
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
枚举所有情况 + 回溯
class Solution
int[] diff; //每个楼人数变化
int count; //处理的请求个数
int zero; //人数变化的楼有几个
int res;
int n;
public int maximumRequests(int n, int[][] requests)
//这个就相当于形成一个环,看哪几个环最大
//那么这个该怎么搞呢,因为一个楼可以和多个形成环
//而所给的n和数组长度也不大,意思是可以暴力做一下
//但是暴力该怎么做呢,就是遍历所有的成环情况吗
//判断成环是用拓扑排序,统计入度出度
//实在有点想不到怎么统计几个环
//然后就看了官解,官解给出的方法是枚举所有的情况,也就是遍历所有的请求,
//如果这个请求被考虑,那么就给响应的房间人数发生变化,如果最后所有房间都没有发生变化,就返回当前统计到的请求数
//如果有楼人数发生了变化,就返回
int l = requests.length;
this.n = n;
diff = new int[n];
zero = n; //刚开始所有楼人数都没有变化
dfs(requests, 0); //处理第几个请求
return res;
public void dfs(int[][] requests, int idx)
//如果遍历到最后一个请求了,同时楼中人数没有发生变化,那么就统计当前变化的请求个数
if(idx == requests.length)
if(zero == n)
res = Math.max(res, count);
return;
//考虑当前请求
int z = zero;
int from = requests[idx][0];
int to = requests[idx][1];
count++;
diff[from]--;
diff[to]++;
if(diff[from] == 0)
zero++;
else if(diff[from] == -1)
zero--;
if(diff[to] == 0)
zero++;
else if(diff[to] == 1)
zero--;
//如果是自环,那么zero不变
if(from == to)
zero = z;
dfs(requests, idx + 1);
//回溯
diff[from]++;
diff[to]--;
count--;
zero = z;
//不考虑当前请求
dfs(requests, idx + 1);
用二进制表示
class Solution
public int maximumRequests(int n, int[][] requests)
//用二进制来枚举,就是用每一个二进制位代表当前requests是否被选择
//如果被选择了,那么更新diff数组,最后查看当前mask下,是否diff数组还是没有变化,
//如果没有变化,就记录当前结果
//比回溯那种更简单高效
int res = 0;
int l = requests.length;
int[] diff = new int[n];
for(int mask = 0; mask < (1 << l); mask++)
int count = Integer.bitCount(mask);
if(count <= res)
continue;
Arrays.fill(diff, 0);
//遍历所有为 1 的请求
for(int i = 0; i < l; i++)
if(((mask >> i) & 1) != 0)
diff[requests[i][0]]--;
diff[requests[i][1]]++;
boolean flag = true;
for(int t : diff)
if(t != 0)
flag = false;
break;
if(!flag)
continue;
res = count;
return res;
以上是关于LeetCode 2016. 增量元素之间的最大差值 / 553. 最优除法 / 1601. 最多可达成的换楼请求数目(枚举+回溯)的主要内容,如果未能解决你的问题,请参考以下文章
Leetcode刷题100天—5881. 增量元素之间的最大差值(数组)—day49
Leetcode刷题100天—5881. 增量元素之间的最大差值(数组)—day49
「 每日一练,快乐水题 」2016. 增量元素之间的最大差值
「 每日一练,快乐水题 」2016. 增量元素之间的最大差值