每个非负整数 N
都有其二进制表示。例如, 5
可以被表示为二进制 "101"
,11
可以用二进制 "1011"
表示,依此类推。注意,除 N = 0
外,任何二进制表示中都不含前导零。
二进制的补码表示是将每个 1
改为 0
且每个 0
变为 1
。例如,二进制数 "101"
的二进制补码为 "010"
。
给定十进制数 N
,返回其二进制表示的补码所对应的十进制整数。
示例 1:
输入:5 输出:2 解释:5 的二进制表示为 "101",其二进制补码为 "010",也就是十进制中的 2 。
示例 2:
输入:7 输出:0 解释:7 的二进制表示为 "111",其二进制补码为 "000",也就是十进制中的 0 。
示例 3:
输入:10 输出:5 解释:10 的二进制表示为 "1010",其二进制补码为 "0101",也就是十进制中的 5 。
提示:
0 <= N < 10^9
对于正数的补码为:符号位不变,每一位求反(0变1,1变0)。最后直接使用Java的parseInt指定二进制转化为对应的十进制.
0的补码是其本身
负数的补码是除符号位以外诸位取反后+1.
public int bitwiseComplement(int N) {
String bin = Integer.toBinaryString(N);
// 求反
StringBuilder sb = new StringBuilder();
boolean first = true;
for (int i = 0; i < bin.length(); i++) {
if (bin.charAt(i) == '0') {
sb.append("1");
first = false;
} else if (!first) {
sb.append("0");
}
}
if (sb.length() == 0) {
sb.append("0");
}
return Integer.parseInt(sb.toString(),2);
}
在歌曲列表中,第 i
首歌曲的持续时间为 time[i]
秒。
返回其总持续时间(以秒为单位)可被 60
整除的歌曲对的数量。形式上,我们希望索引的数字 i < j
且有 (time[i] + time[j]) % 60 == 0
。
示例 1:
输入:[30,20,150,100,40] 输出:3 解释:这三对的总持续时间可被 60 整数: (time[0] = 30, time[2] = 150): 总持续时间 180 (time[1] = 20, time[3] = 100): 总持续时间 120 (time[1] = 20, time[4] = 40): 总持续时间 60
示例 2:
输入:[60,60,60] 输出:3 解释:所有三对的总持续时间都是 120,可以被 60 整数。
提示:
1 <= time.length <= 60000
1 <= time[i] <= 500
暴力题,直接让所有值对60取模。
package menu._1000_1100;
import java.util.Arrays;
public class _1013_numPairsDivisibleBy60 {
public int numPairsDivisibleBy60(int[] time) {
// 所有的数字都%= 60;
for (int i = 0; i < time.length; i++) {
time[i] %= 60;
}
Arrays.sort(time);
int[] count = new int[60];
for (int i = 0; i < time.length; i++) {
count[time[i]]++;
}
int res = 0;
// i== 0时,i == 30 时,个数都是
res += Cby2(count[0]) + Cby2(count[30]);
for (int i = 1; i < 30; i++) {
res += count[i] * count[60 - i];
}
return res;
}
private int Cby2(int up) {
if (up < 2) {
return 0;
}
return (up * (up - 1)) / 2;
}
}
PS:这道题我竟然错了三次才A,被罚时整哭了。
传送带上的包裹必须在 D 天内从一个港口运送到另一个港口。
传送带上的第 i
个包裹的重量为 weights[i]
。每一天,我们都会按给出重量的顺序往传送带上装载包裹。我们装载的重量不会超过船的最大运载重量。
返回能在 D
天内将传送带上的所有包裹送达的船的最低运载能力。
示例 1:
输入:weights = [1,2,3,4,5,6,7,8,9,10], D = 5 输出:15 解释: 船舶最低载重 15 就能够在 5 天内送达所有包裹,如下所示: 第 1 天:1, 2, 3, 4, 5 第 2 天:6, 7 第 3 天:8 第 4 天:9 第 5 天:10 请注意,货物必须按照给定的顺序装运,因此使用载重能力为 14 的船舶并将包装分成 (2, 3, 4, 5), (1, 6, 7), (8), (9), (10) 是不允许的。
示例 2:
输入:weights = [3,2,2,4,1,4], D = 3 输出:6 解释: 船舶最低载重 6 就能够在 3 天内送达所有包裹,如下所示: 第 1 天:3, 2 第 2 天:2, 4 第 3 天:1, 4
示例 3:
输入:weights = [1,2,3,1,1], D = 4 输出:3 解释: 第 1 天:1 第 2 天:2 第 3 天:3 第 4 天:1, 1
提示:
1 <= D <= weights.length <= 50000
1 <= weights[i] <= 500
初始值很好想,就是math.max(max(),avg());,在最大的元素和平均值中取最大即为初始值,之后每次加一个min,这个min是可以使至少一组的容纳个数增加的最小值。
package menu._1000_1100;
public class _1014_shipWithinDays {
public int shipWithinDays(int[] weights, int D) {
// 递归.
// 先找出初始值
int max = 0, sum = 0;
for (int i = 0; i < weights.length; i++) {
if (weights[i] > max) {
max = weights[i];
}
sum += weights[i];
}
int w = Math.max(max, (int) (sum / weights.length + 0.999));
return shipWithinDays(weights, D, w);
}
int min = Integer.MAX_VALUE;
private int shipWithinDays(int[] weights, int d, int w) {
int res = -1;
while (res < 0) {
min = Integer.MAX_VALUE;
res = shipWithinDays2(weights, d, w, 0);
w += min;
}
return res;
}
private int shipWithinDays2(int[] weights, int d, int w, int index) {
if (d >= 0 && index == weights.length) {
return w;
}
if (d == 0 && index < weights.length) {
return -1;
}
int sum = weights[index];
while (index + 1 < weights.length && sum + weights[index + 1] <= w) {
sum += weights[index + 1];
index++;
}
if (index == weights.length - 1) {
return w;
}
min = weights[index + 1] - (w - sum) < min ? weights[index + 1] - (w - sum) : min;
return shipWithinDays2(weights, d - 1, w, index + 1);
}
}