• 数组分成和尽可能相等的子数组


    问题:
    给定n个数据,分成5个数组,所有子数组的和值尽可能相等

    只有正数的情况下可以这样做,但是如果有负数的情况下是方案2
    代码:

    #子数组和类节点,存储和值和子数组编号
    class node:
        def __init__(self,a,b):
            self.num=a
            self.idx=b
    #小顶堆实现函数
    def HeapAdjust(s, a, n):
        temp = s[a]
        i=a*2
        while i <= n:
            if (i < n and s[i].num> s[i + 1].num):
                i+=1
            if (temp.num <= s[i].num):
                break
            s[a] = s[i]
            a = i
            i *= 2
        s[a] = temp
    def HeapSort(s, n):
        i = n // 2
        while i >= 1:
            HeapAdjust(s, i, n)
            i-=1
    #类似哈夫曼树的构成规则的思路,将小的元素放在一起,同大的相当
    def split_array(arr):
        if len(arr)<=5:
            res=[[x] for x in arr]
            for i in range(5-len(res)):
                res.append([])
            return res
        res=[[] for i in range(5)]
        arr.sort(reverse=True)
        nums=[[node(-1,-1)]]#堆排序第一个元素占位
        for idx in range(5):
            res[idx].append(arr[idx])
            nums.append(node(arr[idx],idx))
        HeapSort(nums,len(nums)-1)
        for item in arr[5:]:
            top_id=nums[1].idx
            res[top_id].append(item)
            nums[1].num+=item
            HeapAdjust(nums,1,len(nums)-1)
        return res
    print(split_array([3,4,5,6,7,8,100,101,200,300,400,500]))

     


    测试用例:
    print(split_array([3,4,5,6,7,8,100,101,200,300,400,500]))

    测试结果:
    [[500], [400], [300], [200, 8, 5, 4], [101, 100, 7, 6, 3]]

     

     方案2

    #类似哈夫曼树的构成规则的思路,将小的元素放在一起,同大的相当
    def split_array(arr):
        if len(arr)<=5:
            res=[[x] for x in arr]
            for i in range(5-len(res)):
                res.append([])
            return res
        res=[[] for i in range(5)]
        arr.sort(reverse=True)
        nums=[]#堆排序第一个元素占位
        left=5
        right=len(arr)-1
        for idx in range(5):
            res[idx].append(arr[idx])
            nums.append([arr[idx],idx])
           
        nums=sorted(nums,key=lambda x:x[0],reverse=True)
        while left<=right:
            if abs(arr[left])>abs(arr[right]):
                if arr[left]>0:
                    nums[-1][0]+=arr[left]
                    res[nums[-1][1]].append(arr[left])
                else:
                    nums[0][0]+=arr[left]
                    res[nums[0][1]].append(arr[left])
                left+=1
            else:
                if arr[right]>0:
                    nums[-1][0]+=arr[right]
                    res[nums[-1][1]].append(arr[right])
                else:
                    nums[0][0]+=arr[right]
                    res[nums[0][1]].append(arr[right])
                right-=1
            nums=sorted(nums,key=lambda x:x[0],reverse=True)
        return res
    测试用例:print(split_array([3,4,7,8,100,101,200,-300,400,-500]))
    
    测试结果:
    [[400, -500, 7], [200, -300, 4, 3], [101], [100], [8]]

     

     

     

     

     

     

     

     

     

     

  • 相关阅读:
    WIFI:802.11无线LAN
    如何使你的PPT更高调
    windows的注册表有什么用?
    Steeltoe之Config客户端篇
    初探Spring Cloud Config
    .NET Core开发日志——ADO.NET与SQL Server
    .NET Core开发日志——Linux版本的SQL Server
    .NET Core开发日志——视图与页面
    .NET Core开发日志——Filter
    .NET Core开发日志——Model Binding
  • 原文地址:https://www.cnblogs.com/BetterThanEver_Victor/p/13040299.html
Copyright © 2020-2023  润新知