[leetcode] 805数值的均值分割

在这里插入图片描述

题目意思理解:

将一个数组分成两个数组,要求每个数组的平均值一致—和原数组平均值相等。且数组大小不一定要想等。

刚开始的想法:

因为这个题目它也是0-1问题,所以刚开始是想用动态规划来求解,但是当时确实dp数组和决策方程想不出来用什么好,因为dp数组具有子问题不必多次求解的意思在里面,但是我想不出这里的子问题与原问题之间的联系,而且dp数组里面存放的内容,我觉得好像没有太大用途,所以当时就没有继续该思路想法。
第二个思路是因为0-1还有一个想法就是二进制,所以当时想着取一个数作为固定数组是否取这个数的约定,化作二进制时为1则取,不为1则不取。—此方法名叫二进制枚举。
但是纯二进制枚举会导致数组很大,迭代次数过多,超时,因为最大位数为30位,2的30次方的迭代次数可想而知会超时。

然后最后,就是折半搜索了,就是把原来的数组分为两个数组,分为两个数组去二进制枚举。这样时间复杂度就减少了一个平方次幂。2*2的15次方时间复杂度。

代码

/**
* @param {number[]} nums

* @return {boolean}

*/
var splitArraySameAverage = function(nums) {

    if(nums.length===1) return false
    let len = nums.length
    let b = 1
    let sum = nums.reduce((x,y) => x+y,0)    //利用reduce函数计算和
    nums = nums.map(item =>{        //map函数让原数组和为0
        return item*len - sum
    })
    console.log(nums)
    let tot = []
    /* console.log(sum/len) */
    while(b<2**parseInt(len/2)){
        let as = 0
        let index=0
        let res = []
        while(2**index<=b){
            let n =1 << (index++)

            /* console.log(n)
            console.log(n & b) */
            if((n & b) === n){
                as+=nums[index-1]
                res.push(index-1)
            }
        }
        /* console.log(res,as/res.length) */
        tot.push(as)
        if(as === 0)
            return true
        b+=1
        console.log(b)
    }
    b = 2**parseInt(len/2)

    let s = 0

    for(let i = parseInt(len/2);i<len;i++){
        s+=nums[i]
    }    
    while(b<2**len){
        let as = 0
        let index=0
        let res = []
        while(2**index<=b){
            let n =1 << (index++)
            /* console.log(n)
            console.log(n & b) */
            if((n & b) === n){
                as+=nums[index-1]
                res.push(index-1)
            }
        }
        /* console.log(res,as/res.length) */
        console.log(2**len-1)
        if(as === 0 || ((as!==s) && tot.includes(-as)))
            return true
        b+=2**parseInt(len/2)
        console.log(b)
    }
    return false
};

let nums = [3,1]

console.log(splitArraySameAverage(nums))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值