🌈【LeetCode.总持续时间可被 60 整除的歌曲】- JavaScript =>模拟+公式

331 阅读3分钟

「这是我参与11月更文挑战的第26天,活动详情查看:2021最后一次更文挑战


说明:文章部分内容及图片出自网络,如有侵权请与我本人联系(主页有公众号:小攻城狮学前端)

作者:小只前端攻城狮、 主页:小只前端攻城狮的主页、 来源:掘金

GitHub:P-J27、 CSDN:PJ想做前端攻城狮

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


题意描述

在歌曲列表中,第 i 首歌曲的持续时间为 time[i] 秒。

返回其总持续时间(以秒为单位)可被 60 整除的歌曲对的数量。形式上,我们希望索引的数字 i 和 j 满足 i < j 且有 (time[i] + time[j]) % 60 == 0。

示例 1:

输入:[30,20,150,100,40] 输出:3 解释:这三对的总持续时间可被 60 整数: (time[0] = 30, time[2] = 150): 总持续时间 180 (time[1] = 20, time[3] = 100): 总持续时间 120 (time[1] = 20, time[4] = 40): 总持续时间 60

示例 2:

输入:[60,60,60] 输出:3 解释:所有三对的总持续时间都是 120,可以被 60 整数。

提示:

  • 1 <= time.length <= 60000
  • 1 <= time[i] <= 500
分析

当我们看到数据集小于等于60000即为1e5左右,所以时间复杂度在你n^2的基本上都不考虑。 那怎么来解决时间的问题呢,我们来分析分析题目。首先保存有限个整数类型时,可以考虑用数组的索引来代表。

  • 但是如果只是用数组存储这些整形的话,想得到某个值时都需要遍历整个数组。很容易造成O(n^2)
  • 但是如果用数组索引来存储的话,通过下标获取的时间是O(1)的。

而我们要求的是余数之和等于**60的pair。**即余数之和等于60意味着他们的和可以被60整除。有一个特殊情况要考虑,那就是我们找到的数已经被60整除了,这种情况我们需要特判一下。

var numPairsDivisibleBy60 = function(time) {
    let yushu=new Array(61).fill(0);
    let res=0,thir=0;
    for(let i in time)
    {
        yushu[time[i]%60]++;
    }
    
    for(let j=0;j<=30;j++)//循环控制重复
    {
      if(j==30||j==0)//和自己排列组合,减去和自身配对结果重复配对,所以再除以2
        thir=thir+(yushu[j]*yushu[j]-yushu[j])/2;
     else//简单排列组合,不担心序号相同
       res=res+yushu[j]*yushu[60-j];
    }
    res=res+thir;
    
    return res;
    
};

还有一种方式,其实我们可以通过数学推算出来一个公式。n * (n - 1) / 2

var numPairsDivisibleBy60 = function(time) {
    let sum = 0;
    let arr = Array(60).fill(0);
    for(let i = 0; i < time.length; i++) {
        arr[time[i]%60] += 1;
    }
    sum += arr[0] * (arr[0] - 1) / 2;
    sum += arr[30] * (arr[30] - 1) / 2;
    let l = 1, r = 59;
    while(l < r){
        sum += arr[l++] * arr[r--];
    }
    return sum;
};

感谢阅读,希望能对你有所帮助,文章若有错误或者侵权,可以在评论区留言或在我的主页添加公众号联系我。

写作不易,如果觉得不错,可以「点赞」+「评论」 谢谢支持❤