首先是让你去写算法
你这种叫打表,理论也可以,但是实际违反了练习的本质
而且你需要手动打表出来1-10000的所有内容,所以还是推荐用代码写出来
其次,这个Easy题,稍微思考一下就能秒的垃圾题
FBI WARNING
装逼版秒法,数据范围内低时间复杂度,纯对答案编程,请勿正式场合玩
6= 1 + 2 + 3
28= 1 + 2 + 4 + 7 + 14
很容易想到进制方面,查表可知
然后查一下奇完数
所以可以直接通过进制判断
设检测8128,我们应判断最低有效位以下是否为全0
最低有效位以上是否为全1
获取最低有效位是x-x&(x-1),可以获得最低位为64
获取后续为全1可以通过二进制的下滑特性,将64-1,得到代码
const baseBinary = x - (x & (x - 1)) - 1;
if (num & (baseBinary - 1 !== 0)) {
return 0;
}
然后可以将原数字与baseBinary - 1做或运算,如果符合完数则是满1
接下来可以根据最位末端求log得到位移多少,因为1比0多一位,所以我们可以多位移一次,然后相加低位满1+1来相加判断是否得到原数,完整检查代码
function checkNumber(num) {
const baseBinary = num - (num & (num - 1)) - 1;
if (num & (baseBinary - 1 !== 0)) {
return false;
}
const moveNum = Math.log2(baseBinary + 1);
if ((baseBinary << (moveNum + 1)) + (baseBinary + 1) === num) {
return true;
}
return false;
}
如果符合条件就不断除2,可以得出代码
function getRangeNumber(left, right) {
let text = "";
for (let index = left; index <= right; index++) {
if (checkNumber(index) === true) {
let resultList = [];
let result = Math.ceil(index / 2);
while (result !== 1) {
resultList.push(result);
result = Math.ceil(result / 2);
}
text+=`${index} = 1 + ${resultList.reverse().join(' + ')}\n`
}
}
return text;
}
结果多了一个120和2016
6 = 1 + 2 + 3
28 = 1 + 2 + 4 + 7 + 14
120 = 1 + 2 + 4 + 8 + 15 + 30 + 60
496 = 1 + 2 + 4 + 8 + 16 + 31 + 62 + 124 + 248
2016 = 1 + 2 + 4 + 8 + 16 + 32 + 63 + 126 + 252 + 504 + 1008
8128 = 1 + 2 + 4 + 8 + 16 + 32 + 64 + 127 + 254 + 508 + 1016 + 2032 + 4064
我们可以在利用检查特性秒
得到代码
let charArray = index.toString().split("");
while (charArray.length !== 1) {
charArray = charArray
.reduce((accumulator, currentValue) => {
return accumulator + parseInt(currentValue);
}, 0)
.toString()
.split("");
}
跑一下再看看
6 = 1 + 2 + 3
28 = 1 + 2 + 4 + 7 + 14
496 = 1 + 2 + 4 + 8 + 16 + 31 + 62 + 124 + 248
8128 = 1 + 2 + 4 + 8 + 16 + 32 + 64 + 127 + 254 + 508 + 1016 + 2032 + 4064
完整JS代码
function checkNumber(num) {
const baseBinary = num - (num & (num - 1)) - 1;
if (num & (baseBinary - 1 !== 0)) {
return false;
}
const moveNum = Math.log2(baseBinary + 1);
if ((baseBinary << (moveNum + 1)) + (baseBinary + 1) === num) {
return true;
}
return false;
}
function getRangeNumber(left, right) {
let text = "";
for (let index = left; index <= right; index++) {
if (checkNumber(index) === true) {
let resultList = [];
let result = Math.ceil(index / 2);
let charArray = index.toString().split("");
while (charArray.length !== 1) {
charArray = charArray
.reduce((accumulator, currentValue) => {
return accumulator + parseInt(currentValue);
}, 0)
.toString()
.split("");
}
while (result !== 1) {
resultList.push(result);
result = Math.ceil(result / 2);
}
if (index === 6 || charArray[0] === '1') {
text += `${index} = 1 + ${resultList.reverse().join(" + ")}\n`;
}
}
}
return text;
}
console.log(getRangeNumber(1, 10000));