前端编程题:正整数n可以表示为连续的正数序列之和,求最长的一条表达式,例如15 = 1+2+3+4+5。

正整数n可以表示为连续的正数序列之和,求最长的一条表达式,例如15 = 1+2+3+4+5。求大佬解答!

阅读 5.4k
6 个回答
function getNum(n, count) {
        if (typeof n !== "number" && n % 1 !== 0 && n >= 3) return;
        //等差数列
        var disc = Math.pow(count, 2) - 4 * 1 * -2 * n,
            x1,
            x2,
            result;
        if (disc < 0) {
            return;
        } else {
            x1 = (-1 + Math.sqrt(disc)) / 2;
            x2 = (-1 - Math.sqrt(disc)) / 2;
            if (x1 > 0 && x1 % 1 === 0) {
                result = forNum(x1, n, count);
            } else if (x2 > 0 && x2 % 1 === 0) {
                result = forNum(x2, n, count);
            } else {
                result = "该正整数没有满足条件的正数序列!";
            }
        }
        return result;
    }
    function forNum(x, n, count) {
        var total = 0,
            arr = [];
        for (var i = count; i <= x; i++) {
            total += i;
            if (total > n) {
                break;
            } else {
                arr.push(i);
            }
        }
        if (arr.length > 1) {
            var expressionStr = '';
            arr.map(function(item,index){
                expressionStr += item.toString() + '+';
            })
            return expressionStr.slice(0,expressionStr.length - 1);
        } else {
            return "该正整数没有满足条件的正数序列!";
        }
    }

第一个参数是正整数n,第二个参数是最长正数序列的首项值,算法是依据等差数列来实现的。这里你需要知道等差数列,因为公差是d = 1,且当首项值是count时,等差数列求和公式sn = n * count + (n- 1) * n / 2 * 1 = (n ^ 2 + n) / 2为正数序列最长,满足这个条件就可以求得最长序列每一项,然后添加到了一个数组中去,并遍历数组每一项,然后返回一个表达式。

function findLongestConsecutiveSequence(num) {
  let longNums = []

  for (let numCount = 1; numCount <= num / 2 + 1; numCount++) {
    const startNum = ((2 * num) / numCount - numCount + 1) / 2
    if (startNum % 1 !== 0 || startNum === 0 || startNum === num) {
      continue
    }
    if (startNum < 0) {
      break
    }

    longNums = []
    for (let a = 0; a < numCount; a++) {
      longNums.push(startNum + a)
    }
  }

  return longNums
}
console.log(findLongestConsecutiveSequence(15))

详情参考: 一个整数分解为连续正整数之和

我的思路是利用2进制
例如15=> 01111可以看出是1+2+4+8,(看的是1的位置)
然后分解8=>1000 对半分44=> 3+5`,
再例如24=>11000是8+16,对16进行分解7,9再分解下去就没意义了,并且7,8,9刚好连续

主要思路就是利用2进制分解,并判断是否连续,分解下去出现重复就停止,查看上次数组是否连续

function sum (arr){

           let sum = 0;
     arr.forEach(item => {
     sum+=item
        })
   return sum;

}
sum([1,2,3])

如果是那种判断这个数是否能用连续的自然数相加得出,可以如下写(简化什么的就很懒,扶额)

var sum=[];
var result=21;
var i=1;
while(result > 0){
    result = result - i;
    if(result < 0){
        console.log("没有连续表达式");
        sum=[];
        break;
        }
    else{
        sum.push(i);
        i++;
        }
};
console.log(sum);

真的可以吗 2 = 1 + ?

推荐问题