解题思路
易想到的方法就是都数据进行排序,然后先撞击小的,一次一次累计。
排序的时间复杂度为 O(nlogn)。
还有一种线性时间复杂度的方法
将数据分为 , 即在将数字用二进制表示,分别需要 1 位、2 位、3 位、…… 、k + 1 位。
便可发现,在每个区间内,只要小于区间内最小的,他就能摧毁掉这个区间内的所有。
思路:
- 将所有数字分别装入各自的区间,题目已经给出其数值最大值为 ,即最多需要 17 个区间()
- 和每个区间的最小值进行比较,如果小于,就能摧毁掉,否则就不能。
- 能摧毁掉就加上这个区间的和,进入下一区间。
有读者可能会想,可以通过八进制或其他更改进制把数值分进不同的区间,这样占用的空间就会更小。
分成八进制的话,那 当小于最小值就能摧毁整个区间 就不能成立
把数值分成 ,当数值大于等于这个区间的最小值,他加上这个最小值,它就不能保证大于等于整个区间的所有数值。
明显使用二进制是可以做到的。
代码
int getSh(int n) {
int count = 0;
while(n != 1) {
n >>= 1;
count++;
}
return count;
}
bool asteroidsDestroyed(int mass, int* asteroids, int asteroidsSize){
long sum[17] = {0};
int min[17] = {0};
for(int i = 0; i < asteroidsSize; i++) {
int t = getSh(asteroids[i]);
if(asteroids[i] < min[t] || min[t] == 0) min[t] = asteroids[i];
sum[t] += asteroids[i];
}
long long newmas = mass;
for(int i = 0; i < 17; i++) {
if(newmas >= INT_MAX) return true;
if(newmas < min[i]) return false;
newmas += sum[i];
}
return true;
}
结果