这个问题本身思考过还是很简单的,但是起初还是让我费了一番脑筋,因此写出来与大家分享,希望对您有所帮助。
已知:
// 给 n
个非负整数,请你求出最大或和,最小或和,最大与和,最小与和这四个数之和。
// 注意事项: 不能不选,至少选一个数
思路:
特性: a|b ≥a 且 a|b≥b 即 a|b ≥a, a&b≤a 且 a&b≤b 即 a&b≤b (我们假设a ≥ b)
解释: 对于a|b 结果中, a原先为1的数字肯定结果还是1(因为1|1 = 1, 1|0 = 1),但0有机会变为1 ( 0|1 = 1),因此结果只会变大,同理可以解释a&b,1可能变0而0只能为0,所以结果只会变小而不会变大。
因此:
最大或和 --- 所有数或起来的值,因为值只会变大
最小或和 --- 选取所有数中最小的数
最大与和 --- 选取所有数中最大的数
最小与和 --- 所有数与起来的值,因为值只会变小
代码如下:
public class Solution {
/**
* @param n:
* @param nums:
* @return: return the sum of maximum OR sum, minimum OR sum, maximum AND sum, minimum AND sum.
*/
public long getSum(int n, int[] nums) {
return miny(n, nums) + maxy(n, nums) + minh(n, nums) + maxh(n, nums);
}
//本质是全部或起来
private int maxh(int n, int[] nums) {
int ret = 0;
for (int i : nums) {
ret = ret | i;
}
return ret;
}
//本质是找最小值
private int minh(int n, int[] nums) {
int ret = nums[0];
for (int i : nums) {
if (ret > i) {
ret = i;
}
}
return ret;
}
//本质是找最大值
private int maxy(int n, int[] nums) {
int ret = nums[0];
for (int i : nums) {
if (ret < i) {
ret = i;
}
}
return ret;
}
//本质是全部与起来
private int miny(int n, int[] nums) {
int ret = nums[0];
for (int i = 1; i < nums.length; i++) {
ret = ret & nums[i];
}
return ret;
}
}