进入CodeWar已经一个多月了,基本的暴力算法只能支撑我走到5级了,今天开始正式学习数据结构与算法,边刷题便学习吧。。

Kyu7test

题目:正整数有很多华丽的特征。其中一些可以表示为两个或多个连续正数的和。
举个例子:10,可以表示为1 + 2 + 3 + 4的和。
任务给定正整数N,如果它可以表示为两个或多个连续正数的和,则返回true,否则返回false。
笔记:保证约束:2≤N≤(2^31)-1。

MyCode

int sum=0;
for(int i=0;i<(n+1)/2;i++) {
sum=i;
for(int j=i+1;j<=(n+1)/2;j++) {
sum+=j;
if(sum == n) return true;
if(sum>n) break;
}
}
return sum==n?true:false;


int small=1;
int big=2;
int sum=small+big;
while(small<(n+1)/2) {
if(sum<n) {
sum+= ++big;
}else {
sum-=small;
small++;
}
if(sum == n) break;
}
return sum==n?true:false;

上面两个算法其实原理一样,CodeWar上因为效率低无法通过(好像7,8级的题都要考虑效率)。

Solutions:

return (n– & n)>0;

return Integer.bitCount(n)>1;

我一开始理解不了这是为什么,直到我看了下一个算法
如下:

while(n%2 == 0){
if(n==2){return false;}
n /= 2;
}
return true;

思路:任意一个大于2的奇数或最小因数不为2的偶数都可以表示为两个或多个连续正数的和,所以只有2的N次方不能这样表示。

所以第一种方法,2的N次方减一,二进制表示为xxxxxxx1,与本身做与运算为0;
第二种方法返回n在二进制表示中所有1的数量,2的N次方自然只有1个1,小于1,返回false。