美文网首页算法小屋
卢小七的刷题笔记(js)

卢小七的刷题笔记(js)

作者: 卢小七 | 来源:发表于2017-11-06 21:18 被阅读0次

题目来源: Codewars

题目: Is my friend cheating?

题目难度: 5kyu(不是很难)

  • A friend of mine takes a sequence of numbers from 1 to n (where n > 0).
  • Within that sequence, he chooses two numbers, a and b.
  • He says that the product of a and b should be equal to the sum of all numbers in the sequence, excluding a and b.
  • Given a number n, could you tell me the numbers he excluded from the sequence?

The function takes the parameter: n (don't worry, n is always strictly greater than 0 and small enough so we shouldn't have overflow) and returns an array of the form:

[(a, b), ...] or [[a, b], ...] or {{a, b}, ...} or or [{a, b}, ...]

with all (a, b) which are the possible removed numbers in the sequence 1 to n.

[(a, b), ...] or [[a, b], ...] or {{a, b}, ...} or ...will be sorted in increasing order of the "a".

It happens that there are several possible (a, b). The function returns an empty array if no possible numbers are found which will prove that my friend has not told the truth! (Go: in this case return nil).

#Examples:

removNb(26) should return [(15, 21), (21, 15)]

or

removNb(26) should return { {15, 21}, {21, 15} }

or

removeNb(26) should return [[15, 21], [21, 15]]

or

removNb(26) should return [ {15, 21}, {21, 15} ]

or

in C:
removNb(26) should return  **an array of pairs {{15, 21}{21, 15}}**
tested by way of strings.

个人理解(翻译一下)

1-n的的n个数中找到2个数a,b,使得除去a,b剩下的数之和与a,b之积相等.

解法1 (最粗暴的解法):双重循环遍历

function removeNb(n){
    var res = []
    //等差数列求和
    var sum = ( n + 1 ) * n / 2
    for (var a = 1; a <= n; a++) {
        for(var b = 1; b <= n; b++){
            if (a * b == sum - a - b) {
                res.push([a , b])
            }
        }
    }
    return res
}

结果:几个简单的测试能过,比较大的数字n,超出给定运行时间,报错.

思考1:能不能单循环

需要观察给定的要求,即(sum = (1+n)*n/2):

a*b=sum-a-b

稍微转化一下:

(a+1)*(b+1)=sum+1

思路就有了:

b=(sum+1)/(a+1)-1

改进2:单循环

function removeNb(n){
    var res = []
    //等差数列求和
    var sum = ( n + 1 ) * n / 2
    for (var a = 1; a <= n; a++) {
        var b = ( sum + 1) / ( a + 1 ) - 1
            if ( Number.isInteger(b)&&b<=n) {
                res.push([a , b])
            }
        }
    return res
}

思考二:有无改进空间

单循环的起始位置一定要从1开始么?不.
分析比较小的那个数,不妨认为是a
假设去掉的两个数是n,n-1,则剩下的数之和为:

sumOfRest = sum-2*n-1

此时a应不小于start=[sumOfRest/n]+1,
a的下限为start.并且根据题意,如果[a,b]算一对,[b,a]也算一对.
那么当a>b时,直接将已有的结果加以处理即可.

改进三:利用分析处理循环开始与中间结果

function removeNb(n){
    var res = []
    //等差数列求和
    var sum = ( n + 1 ) * n / 2
    var start = Math.ceil((sum - 2 * n - 1) / n)
    for (var a = start; a <= n; a++) {
        var b = ( sum + 1) / ( a + 1 ) - 1
        if ( Number.isInteger(b) && b <= n && a< b) {
            res.push([a , b])
        }
    }
    var len = res.length
    for (var i = len - 1; i >= 0; i--) {
        var [a, b] = res[i]
        res.push([a, b].reverse())
    }
    return res
}

应该还有改进空间,懒得想了.结束.

再说几句:
提交后也查看了Codewars网站上其他网友的答案,基本都是改进2的做法,其中Number.isInteger(b)用来判断整数,其他做法还有b % 1===0等等,正如题目难度一样,可能并不需要想太多.

相关文章

  • 卢小七的刷题笔记(js)

    题目来源: Codewars 题目: Is my friend cheating? 题目难度: 5kyu(不是很难...

  • 卢小七的刷题笔记(js)

    题目来源: Codewars 题目: Coordinates Validator 题目难度: 4kyu(理论上难,...

  • 刷题笔记-JS相关

    前端JS相关面试题,排名没有先后只记录 1.Promise.then值穿透 你可能会认为结果是"bar", 其实不...

  • 抓住小尾巴

    最近忙着刷题,感觉效率不是很高,白天看录播视频做笔记,晚上刷题。参加了一个集训营,只要每天刷完固定的题量,达到了七...

  • js 刷题

    [不断补充!!!] 1.找出数组中出现最多的元素和次数测试用例: 解决方法:利用对象来统计,区别for...of ...

  • sql刷题笔记(七)

    题目选自leetcode 上的题库 可能不一定都是最优解,答案仅供参考每道题后面都应相应的难度等级,如果没时间做的...

  • 晨间日记

    计算机刷题 看书写笔记 高数刷题 英语刷题 奋斗到天亮,加油奥利给

  • 谷歌工程师为金三银四筹备1000道Leetcode刷题笔记

    对于刷题相关的文章,在之前我也推荐过不少,今天再给大家推荐一份算法刷题笔记,这份笔记与以往的刷题有所区别,作者把 ...

  • LeetCode刷题笔记(七)数论

    七. 数论 7. 整数反转 题目:整数反转 9. 回文数 题目:回文数 69. x 的平方根 题目:x 的平方根 ...

  • 刷题笔记

    算法思想 一、二分查找 1. 算法思想 算法详解 算法细节 一定要看二分查找细节.md 实现时需要注意以下细节: ...

网友评论

    本文标题:卢小七的刷题笔记(js)

    本文链接:https://www.haomeiwen.com/subject/kdtdrxtx.html