JS | 教练,我想做习题20

前言

大家好呀,我是毛小悠,可以叫我二毛,在家中排行老二,是一名前端开发工程师。

本系列文章旨在通过练习来提高JavaScript的能力,一起愉快的做题吧。

以下每道题,二毛我都有尝试做一遍。建议限时训练,比如限定为半小时,如果半小时内想不出来,可以结合文章末尾的参考答案来思考。

可以在下方评论区留言或者加我的微信:code_maomao。期待你的到来。

求关注求点赞~~~

题目1:最大子阵列总和II

找到一个或多个具有相应元素之和的最大值的子数组。所需函数:Javascript:findSubarrMaxSum()

find_subarr_maxsum([-2, 1, -3, 4, -1, 2, 1, -5, 4]) == [[4, -1, 2, 1], 6]

如果在解决方案中,我们有两个或多个具有最大和值的数组,则结果将按从左到右的顺序排列数组。

find_subarr_maxsum([4, -1, 2, 1, -40, 1, 2, -1, 4]) == [[[4, -1, 2, 1], [1, 2, -1, 4]], 6]  # From left to right [4, -1, 2, 1] appears in the array before than [1, 2, -1, 4].

如果该数组不包含其条件之和为正的子数组,则该函数将返回[[],0]。

习题代码:

function findSubarrMaxSum(arr){
    var x;
    // your code here
    return [[], x] // or [[[]], x]
}

题目2:简单乐趣#206:因素数字

计算n!中的位数,其中n是给定的。

输入输出

  • [input]整数n

    0≤n≤10 ^ 6。

  • [output] 一个整数

对于n = 1,输出应为1。

1!= 1,一位数字。

对于n = 10,输出应为7

10!= 3628800,七位数。

习题代码:

function factDigits(n) {
  //coding and coding..
  
  
}

题目3:简单乐趣#339:最高产品2

任务

给定一个正整数n(5 <= n <= 100)。您的任务是将n分为一些不同的整数,使这些整数的乘积最大化。

对于n = 5,输出应为6。

5可以分为2和3,2 x 3 = 6

对于n = 8,输出应为15。

8可以分为3和5,3 x 5 = 15

对于n = 10,输出应为30。

10可以分为2、3和5,2 x 3 x 5 = 30

对于n = 15,输出应为144。

15可以分为2、3、4和6,2 x 3 x 4 x 6 = 144

习题代码:

function maximumProduct(n) {
  //coding and coding..
  
}

答案

题目1的答案

参考答案1:

function findSubarrMaxSum(arr){
    let out=[], i=0, m=0, s=0;
    for (let j=0 ; j<=arr.length ; j++){
        let v = j===arr.length ? -Infinity : arr[j];
        if(v<1){
            if(s>m){
                m=s; out=[arr.slice(i,j)];
            }else if(s && s===m){
                out.push(arr.slice(i,j));
            }
        }
        s+=v;
        if(s<1){ s=0; i=j+1; }
    }
    if(out.length==1) out.push(m);
    else out=[out,m];
    return out;
}

参考答案2:

function findSubarrMaxSum(arr) {
  let min = 0, max = 0, maxIdx = [-1], ranges = [[]];
  for (let i = 0, acc = 0; i < arr.length; i++) {
    acc += arr[i];
    if (acc - min > max) {
      max = acc - min, ranges = maxIdx.map(j => [j, i]);
    } else if (acc - min === max) {
      ranges.push(...maxIdx.map(j => [j, i]));
    }
    if (acc < min) {
      min = acc, maxIdx = [i];
    } else if (acc === min) {
      maxIdx.push(i);
    }
  }
  if (ranges[0].length) {
    ranges = ranges.map(([i, j])=> arr.slice(i + 1, j + 1));
    return (ranges.length > 1 ? [ranges] : ranges).concat(max);
  }
  return [[], 0];
}

参考答案3:

function findSubarrMaxSum(arr){
  var min = 0, rangemax = 0, maxidx = [-1], runsum = 0, ranges = [[]];
  for(let i=0; i<arr.length; i++) {
    runsum += arr[i];
    if(runsum-min>rangemax) {rangemax=runsum-min; ranges=maxidx.map(j=>[j,i]);}
    else if(runsum-min===rangemax) ranges.push(...maxidx.map(j=>[j,i]));
    if(runsum<min) {min=runsum; maxidx=[i];}
    else if(runsum===min) maxidx.push(i);
  }
  if(!ranges[0].length) return [[],0];
  ranges = ranges.map(([s,e])=>arr.slice(s+1,e+1));
  return (ranges.length>1?[ranges]:ranges).concat(rangemax);
}

参考答案4:

function findSubarrMaxSum(a){
  var i, j, m=0, r=[], t;
  function sum(a) { return a.reduce((a,b)=>a+b); }
  for (i=0; i<a.length; i++)
    for (j=i+1; j<=a.length; j++) {
      t=a.slice(i,j);
      if (sum(t)>m) {
        r=[t];
        m=sum(t);
      } else if (sum(t)===m)
        r.push(t);
    }
  return [r.length===1?r[0]:r, m];
}

参考答案5:

const findSubarrMaxSum = arr => {
  const a = arr.length? arr.reduce((a, _, i) => a.concat([...Array(arr.length - i)].map((_, j) => arr.slice(j, j + i + 1))), []): [];
  const m = Math.max(...a.map(r => r.reduce((a, b) => a + b)));
  const r = a.filter(s => s.reduce((a, b) => a + b) === m);
  return [!arr.every(n => n < 0)? (r.length > 1? r: r[0]): [], m < 0? 0: m];
}

题目2的答案

参考答案1:

function factDigits(n) {
  if(n==1){
  return 1;  
  }else{
  return Math.floor(((Math.log(2*Math.PI*n)/2+n*(Math.log(n)-Math.log(Math.E)))/Math.log(10))+1);
  }
}

参考答案2:

function factDigits(n) {
  let count = 1, r = 1;
  for(let i=1; i<=n; i++){
    r*=i;
    while(r>10){
      r/=10;
      count++;
    }
  }
  return count;
}

参考答案3:

function factDigits(n) {
  var fact = 1
  var digit = 1
  for(var i = 1; i <= n; i++){
    fact*=i
    while(fact % 10 != fact){
    fact /= 10;
    digit ++;
   }
   }
   return digit
}

参考答案4:

function factDigits(n) {
  return n == 1 ? 1 : Math.floor(n * Math.log10(n / Math.E) + Math.log10(2 * Math.PI * n) / 2) + 1
  
}

参考答案5:

function factDigits(n) {
   let digits = 0;

    while(n > 0){
        digits += Math.log10(n);
        n--;
    }

   return ~~(digits) + 1;
}

题目3的答案

参考答案1:

function maximumProduct(n) {
  function dfs(m, i, a) {
    if (m === 0) return a
    if (m < 0 || i > m) return 0
    return Math.max(dfs(m-i, i+1, a*i), dfs(m, i+1, a))
  }
  return dfs(n, 2, 1)
}

参考答案2:

function maximumProduct(n) {
  var sum=0,arr=[]
  for(var i=2;sum+i<=n;sum+=i++) arr.push(i)
  var rest=n-sum
  for(var i=arr.length*2-1;rest--;i--) arr[i%arr.length]++ 
  //console.log(arr)
  return arr.reduce((a,b)=>a*b,1)
}

参考答案3:

function maximumProduct(n) {
  return [6, 8, 12, 15, 24, 30, 40, 60, 72, 120, 144, 180, 240, 360, 420, 720, 840, 1008, 1260, 1680, 2520, 2880, 5040,
5760, 6720, 8064, 10080, 13440, 20160, 22680, 40320, 45360, 51840, 60480, 72576, 90720, 120960, 181440, 201600, 362880, 403200, 
453600,518400,604800,725760,907200,1209600,1814400,1995840,3628800,3991680,4435200,4989600,5702400,6652800,7983360,9979200,13305600,
19958400,21772800,39916800,43545600,47900160,53222400,59875200,68428800,79833600,95800320,119750400,159667200,239500800,259459200,479001600,
518918400,566092800,622702080,691891200,778377600,889574400,1037836800,1245404160,1556755200,2075673600,3113510400,3353011200,6227020800,
6706022400,7264857600,7925299200,8717829120,9686476800,10897286400,12454041600,14529715200,17435658240,21794572800,29059430400][n-5];
}

// sorry for my laziness on this one

参考答案4:

function maximumProduct(n, m = 2) {
  let r = n >= m ? n : 0;
  for (let i = m; i < n / 2; i++) {
    r = Math.max(r, i * maximumProduct(n - i, i + 1));
  }
  return r;
}

参考答案5:

function maximumProduct(n) {

  function verification(number, offsetA, offsetB) {
    
    if(number == 0)
      return offsetB;
    
    if(offsetA > number)
      return 0;
    
    var split1 = verification(number-offsetA, offsetA + 1, offsetB * offsetA);
    var split2 = verification(number, offsetA + 1, offsetB);
    
    return Math.max(split1, split2);
  }
  
  return verification(n, 2, 1);
}

后序

本系列会定期更新的,题目会由浅到深的逐步提高。

求关注求点赞 ~~

可以关注我的公众号:前端毛小悠。欢迎阅读

你可能感兴趣的:(我要做习题,javascript)