Approach
Breadth-first search
For Minimum Partition Score, the implementation explores reachable states in layers, which is the standard shape for unweighted shortest paths and minimum-step transitions.
- Model each valid configuration as a state and each legal move as an edge.
- Seed the queue with the starting state and mark it immediately.
- Expand each state once, recording distance or reachability for unseen neighbours.
Code notes
- 95 lines of Python from the credited upstream file minimum-partition-score.py.
- The implementation visibly relies on sequence storage, work queue, cached states.
- No explicit loop blocks detected.
Complexity
Verify that each state and transition is processed only a bounded number of times; that determines the traversal cost.
Check the problem constraints before deciding whether this complexity will pass.
Use this to learn the idea, then write your own version.
123 4import collections5 6 78class Solution(object):9 def minPartitionScore(self, nums, k):10 """11 :type nums: List[int]12 :type k: int13 :rtype: int14 """15 def binary_search(left, right, check):16 while left <= right:17 mid = left+(right-left)218 if check(mid):19 right = mid-120 else:21 left = mid+122 return left23 24 def check(l1, l2, l3):25 return (l2[1]-l1[1])*(l2[0]-l3[0]) < (l3[1]-l2[1])*(l1[0]-l2[0])26 27 def max_lambda():28 mx, total = 0, prefix[-1]*(prefix[-1]+1)229 for i in xrange(1, len(nums)):30 c1, c2 = prefix[i], prefix[-1]-prefix[i]31 mx = max(mx, total-(c1*(c1+1)2+c2*(c2+1)2))32 return mx33 34 def f(l):35 dp = cnt = 036 hull = collections.deque([(0, 0, 0)])37 for i in xrange(len(nums)):38 x = prefix[i+1]39 while len(hull) >= 2 and hull[0][0]*x+hull[0][1] > hull[1][0]*x+hull[1][1]:40 hull.popleft()41 dp, cnt = (hull[0][0]*x+hull[0][1])+(x*x+x)2+l, hull[0][2]+142 line = (-x, dp+(x*x-x)2, cnt)43 while len(hull) >= 2 and not check(hull[-2], hull[-1], line):44 hull.pop()45 hull.append(line)46 return dp, cnt47 48 prefix = [0]*(len(nums)+1)49 for i in xrange(len(nums)):50 prefix[i+1] = prefix[i]+nums[i]51 mx = max_lambda()52 assert(f(mx)[1] == 1)53 l = binary_search(0, mx, lambda x: f(x)[1] <= k)54 return f(l)[0]-k*l55 56 575859import collections60 61 6263class Solution2(object):64 def minPartitionScore(self, nums, k):65 """66 :type nums: List[int]67 :type k: int68 :rtype: int69 """70 def check(l1, l2, l3):71 return (l2[1]-l1[1])*(l2[0]-l3[0]) < (l3[1]-l2[1])*(l1[0]-l2[0])72 73 INF = float("inf")74 prefix = [0]*(len(nums)+1)75 for i in xrange(len(nums)):76 prefix[i+1] = prefix[i]+nums[i]77 dp = [INF]*(len(nums)+1)78 dp[0] = 079 for j in xrange(k):80 new_dp = [INF]*(len(nums)+1)81 hull = collections.deque()82 for i in xrange(j, len(nums)):83 if dp[i] is not INF:84 x = prefix[i]85 line = (-x, dp[i]+(x*x-x)2)86 while len(hull) >= 2 and not check(hull[-2], hull[-1], line):87 hull.pop()88 hull.append(line)89 x = prefix[i+1]90 while len(hull) >= 2 and hull[0][0]*x+hull[0][1] >= hull[1][0]*x+hull[1][1]:91 hull.popleft()92 new_dp[i+1] = hull[0][0]*x+hull[0][1]+(x*x+x)293 dp = new_dp94 return dp[-1]95