8.21 - hard - 80

410. Split Array Largest Sum

有两种解法:

  1. 按值二分: 左边界是array里的最大值,右边界是array的sum。按照贪心来做,a. 把array 从左边切割,b.尽量使得两刀之间的值靠近mid,但是小于mid,c. 最后会出现两种情况,一是可以把array切成超过m个subarray,说明mid太小了,否则说明mid太大了。
  2. DP:dp[s][j] 表示把 n[j]...n[L-1] 分成s份能获得的最小和,dp[s+1][i] = min{ max(dp[s][j], n[i]+...+n[j-1]) }, i+1 <= j <= L-s 从i到最后能分成s+1份的最小值就等于,j到最后能分成s份的最小值 和 i到j-1的和这两个值中比较大的值,再取最小,类似minmax,DP的写法可以用memory search感觉写起来要清爽一些。
DP的解法
class Solution(object):
    def splitArray(self, nums, m):
        """
        :type nums: List[int]
        :type m: int
        :rtype: int
        """
        sums = [0]*len(nums)
        sums[len(nums)-1] = nums[len(nums)-1] # sums 表示从某个index到最后一个点的subarray和
        for i in range(len(nums)-2, -1, -1):
            sums[i] = sums[i+1] + nums[i]
        
        memo = [[0]*(m+1) for _ in range(len(nums))]
        
        return self.search(nums, 0, m, sums, memo)
    
    def search(self, nums, start, m, sums, memo):
        if m == 1: #  如果只分成一个部分,从start到最后
            return sums[start]
        if memo[start][m] > 0:
            return memo[start][m]
        min_val = sys.maxint
        total = 0
        
        for i in range(start, len(nums)-m+1):
            total += nums[i]
            # total是从start到i这一段的和,这个与i+1到最后分成m-1份的最小值相比较,取其中的较大的值
            # 然后loop i,取这些值中比较小的值。
            min_val = min(max(total, self.search(nums, i + 1, m - 1, sums, memo)), min_val)
        
        memo[start][m] = min_val
        return min_val
二分法解法
class Solution(object):
    def splitArray(self, nums, m):
        """
        :type nums: List[int]
        :type m: int
        :rtype: int
        """
        max_value = max(nums)
        sum_value = sum(nums)
        if m == 1:
            return sum_value
        # binary search
        l = max_value
        r = sum_value
        while l + 1 < r:
            mid = (l + r)/ 2
            if self.valid(mid, nums, m):
                r = mid
            else:
                l = mid
        if self.valid(l, nums, m):
            return l
        else:
            return r
    
    def valid(self, target, nums, m):
        count = 1;
        total = 0;
        for num in nums:
            total += num
            if total > target:
                total = num
                count += 1
                if count > m:
                    return False
        return True
        
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容