栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

将数组分成两个数组并最小化数组和的差(折半搜索+二分)

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

将数组分成两个数组并最小化数组和的差(折半搜索+二分)

将数组分成两个数组并最小化数组和的差(折半搜索+二分)

2 n ≤ 30 2nle 30 2n≤30,显然是折半搜索。

预处理前一半和后一半的选正的差值。

然后排序去重。

最后扫一遍,枚举正号的个数: i ∈ [ 0 , n ] iin[0,n] i∈[0,n]。

前一半正号选了个 i i i个,那么后一半正号也要选 i i i个,这里两者个数才会相等。

然后二分找到最近的两个数。

class Solution {
    vector s[16],t[16];
    int o[32768];
public:
    int minimumDifference(vector& nums) {
        int n=nums.size()>>1,i,j,k,ans=1000000000;
        for(i=0;i<=n;i++)
        {
            s[i].clear();
            t[i].clear();
        }
        int st=1<>1]+(i&1); //二进制1的个数.
            else o[i]=0;
            for(j=k=0;j>j&1)k+=nums[j];
            else k-=nums[j];
            s[o[i]].push_back(k);
            for(j=k=0;j>j&1)k+=nums[j+n];
            else k-=nums[j+n];
            t[o[i]].push_back(k);
        }
        for(i=0;i<=n;i++)
        {
            sort(t[i].begin(),t[i].end());
            t[i].erase(unique(t[i].begin(),t[i].end()),t[i].end());//去重
        }
        for(i=0;i<=n;i++)for(auto &c:s[i])
        {
            auto it=lower_bound(t[i].begin(),t[i].end(),c);
            if(it!=t[i].end())ans=min(ans,*it-c);
            if(it!=t[i].begin())
            {
                it--;
                ans=min(ans,c-*it);
            }
        }
        return ans;
    }
};
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/312170.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号