题目描述:
现有一份 n + m 次投掷单个 六面 骰子的观测数据,骰子的每个面从 1 到 6 编号。观测数据中缺失了 n 份,你手上只拿到剩余 m 次投掷的数据。幸好你有之前计算过的这 n + m 次投掷数据的 平均值 。
给你一个长度为 m 的整数数组 rolls ,其中 rolls[i] 是第 i 次观测的值。同时给你两个整数 mean 和 n 。
返回一个长度为 n 的数组,包含所有缺失的观测数据,且满足这 n + m 次投掷的 平均值 是 mean 。如果存在多组符合要求的答案,只需要返回其中任意一组即可。如果不存在答案,返回一个空数组。
k 个数字的 平均值 为这些数字求和后再除以 k 。
注意 mean 是一个整数,所以 n + m 次投掷的总和需要被 n + m 整除。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/find-missing-observations
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
---------------------------------------------------------------------------------------------------------------------------------
day8:今天是一道中等题,花费半小时左右,执行用时和内存消耗都超过百分之八十几,看题目很容易有思路,但是会有一些小坑,不容易一次正确,今天因为小判断错了两三次,下次一定先测好再提交,太影响正确率了,看看代码:
public int[] missingRolls(int[] rolls, int mean, int n) {
int sum = 0, m = rolls.length, num1 = 0, num2 = 0;
int[] nums = new int[n];
for (int roll : rolls) {
sum += roll;
}
num1 = ( mean * (m + n) - sum ) / n;
num2 = (mean * (m + n) - sum - num1 * n) % n;
if(num1 > 6 || num1 < 1 || ( num1 == 6 && num2 > 0))
return new int[0];
for (int i = 0; i < n ; i++) {
if(i < num2)
nums[i] = num1+1;
else
nums[i] = num1;
}
return nums;
}
思路解析:
sum值用来记录rolls数组的总和,num1表示为总值减去sum值再除以n的结果,也就是缺失那一段数据的平均值(整数值),num2也就是缺失那段数据除开平均值后的余数,把数补满,当因为骰子值为1到6,所以不在这段区间的直接返回[];下面for循环里,因为num2表示余数,所以用num2个值来+1,以把数据充满,最后返回nums;
说点有意思的,当我把nums定义在最上面的时候,速率和内存都超过八十几,但是我把nums定义在for上面,也就是马上填充值时才生成数组,想着这样会提高速率,内存消耗也没变,结果速率果然提高到了100%,但是内存直接掉到10左右,甚至以下,现在没想到为什么,等研究研究再更新解释。
官方思路差不多,速率快内存消耗高:
public int[] missingRolls(int[] rolls, int mean, int n) {
int m = rolls.length;
int sum = mean * (n + m);
int missingSum = sum;
for (int roll : rolls) {
missingSum -= roll;
}
if (missingSum < n || missingSum > 6 * n) {
return new int[0];
}
int quotient = missingSum / n, remainder = missingSum % n;
int[] missing = new int[n];
for (int i = 0; i < n; i++) {
missing[i] = quotient + (i < remainder ? 1 : 0);
}
return missing;
}
思路:
sum值记录总值(缺失和不缺失的总和),missingSum用来记录的是缺失的值总和,判断缺失的值总和比n还少或者比n的6倍还多就直接return,因为骰子值只能为1到6,然后用quotient表示除数值,remainder表示余数值,最后也是前remainder个的值为除数值+1,后面全为除数值。