本文已参与「新人创作礼」活动,一起开启掘金创作之路。
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) 链接:leetcode-cn.com/problems/ma… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
记录当前最小值,然后记录最大的差值
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) 链接:leetcode-cn.com/problems/op… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
要使得除数最小,就是一直除就除数最小
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) 链接:leetcode-cn.com/problems/ma… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路
枚举所有情况 + 回溯
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;
}
}