Skip to content
← All posts

Best Team With No Conflicts: Sorting Meets LIS-Style DP

5 min read
leetcodeproblemmediumarraysdynamic-programmingsorting

You are the manager of a basketball team. You have a list of players, each with a score and an age. You want to pick a team that maximizes the total score, but there is a rule: a younger player must not have a strictly higher score than an older player on the same team. If that happens, it creates a conflict.

This is LeetCode 1626: Best Team With No Conflicts. Given two arrays scores and ages, find the highest total score of all possible teams with no conflicts. Players of the same age never conflict with each other.

P0P1P2P3P4age1score15age2score4age3score7age4score10age5score2conflictbest team: 4 + 7 + 10 = 21
Players sorted by age. P0 (age 1, score 15) conflicts with P1 (younger but higher score). The best team is P1, P2, P3 with scores forming a non-decreasing sequence.

Why this problem matters

This problem is a disguised variant of the Longest Increasing Subsequence pattern. Instead of finding the longest subsequence, you are finding the maximum sum subsequence where a certain ordering property holds. The key insight is that sorting transforms the conflict rule into a simple condition you can check with a nested loop.

Once you see the connection to LIS, the entire solution clicks into place. The same "sort, then DP over predecessors" strategy shows up in problems like Russian Doll Envelopes, Longest String Chain, and Number of Longest Increasing Subsequences. Mastering it here gives you a reusable building block for all of them.

The approach

The conflict rule says: if player A is younger than player B, then player A must not have a strictly higher score. Equivalently, if we sort players by age (and break ties by score), a valid team is one where the scores form a non-decreasing subsequence.

That transforms the problem into: sort by (age, score), then find the maximum sum subsequence where scores are non-decreasing. This is exactly the LIS-style DP pattern, but instead of counting length, you sum scores.

Here is the algorithm:

  1. Pair each player as (age, score) and sort by age first, then by score.
  2. Create a dp array where dp[i] is the maximum total score of a valid team ending with player i.
  3. Initialize dp[i] = scores[i] (each player alone is a valid team).
  4. For each player i, scan all previous players j. If scores[j] is not greater than scores[i], you can extend the team ending at j by adding player i.
  5. The answer is max(dp).
def best_team_score(scores, ages):
    players = sorted(zip(ages, scores))
    n = len(players)
    dp = [0] * n

    for i in range(n):
        dp[i] = players[i][1]
        for j in range(i):
            if players[j][1] <= players[i][1]:
                dp[i] = max(dp[i], dp[j] + players[i][1])

    return max(dp)

Step-by-step walkthrough

Let's trace through the example scores = [1, 2, 3, 5], ages = [8, 9, 10, 1]. After sorting by (age, score), the players become: (1,5), (8,1), (9,2), (10,3).

Sort by (age, score): (1,5), (8,1), (9,2), (10,3)

(1,5)dp[0]5(8,1)dp[1]1(9,2)dp[2]2(10,3)dp[3]3

Initialize dp[i] = score[i]. Each player alone is a valid team of one.

i=1 (age 8, score 1): Check j=0. score[0]=5 > score[1]=1, conflict. No update.

(1,5)dp[0]5(8,1)dp[1]1(9,2)dp[2]2(10,3)dp[3]3

Player 0 is younger (age 1) but has a higher score (5). Adding both causes a conflict. dp[1] stays 1.

i=2 (age 9, score 2): j=0 conflict, j=1 valid. dp[2] = dp[1] + 2 = 3.

(1,5)dp[0]5(8,1)dp[1]1(9,2)dp[2]3(10,3)dp[3]3

score[0]=5 > 2 (conflict). score[1]=1 is not greater than 2, so we can extend. dp[2] = 1 + 2 = 3.

i=3 (age 10, score 3): j=0 conflict, j=1 valid, j=2 valid. dp[3] = dp[2] + 3 = 6.

(1,5)dp[0]5(8,1)dp[1]1(9,2)dp[2]3(10,3)dp[3]6

score[1]=1 and score[2]=2 are both not greater than 3. Best predecessor is dp[2]=3. dp[3] = 3 + 3 = 6.

Final answer: max(dp) = max(5, 1, 3, 6) = 6

(1,5)dp[0]5(8,1)dp[1]1(9,2)dp[2]3(10,3)dp[3]6

The best team is players (8,1), (9,2), (10,3) with total score 1 + 2 + 3 = 6.

Player 0 (age 1, score 5) is a strong individual player, but including them with any of the older, lower-scoring players creates a conflict. The best team turns out to be players (8,1), (9,2), (10,3), with scores forming the non-decreasing sequence [1, 2, 3] and a total of 6.

Notice how the DP is identical in structure to LIS. The only differences are: (1) you sort by a secondary key first, and (2) you sum values instead of counting length. The inner loop still scans all predecessors and picks the best compatible one.

Complexity analysis

ApproachTimeSpace
Brute force (check all subsets)O(2^n)O(n)
Sort + DPO(n^2)O(n)

The brute force approach considers every possible team (every subset of players), checks for conflicts, and tracks the maximum score. With n players, that is 2^n subsets.

The sort + DP approach sorts in O(n log n), then runs the nested DP loop in O(n^2). The DP dominates, giving O(n^2) overall. Space is O(n) for the sorted pairs and the dp array.

Edge cases to watch for

  • All players same age: no conflicts are possible since same-age players never conflict. The answer is the sum of all scores.
  • Single player: return that player's score. A team of one is always valid.
  • All scores equal: no conflicts possible regardless of age. The answer is the sum of all scores.
  • Scores strictly decreasing with increasing age: e.g., ages [1,2,3], scores [10,5,1]. Every pair conflicts. The answer is max(scores), since you can only pick one player.
  • Already sorted by both age and score: the entire roster is a valid team. The answer is the sum of all scores.
  • Duplicate (age, score) pairs: same age never conflicts, so identical players can always be on the same team. The sort-and-compare logic handles this naturally since scores[j] will equal scores[i], satisfying the non-decreasing condition.

The building blocks

This problem combines two reusable patterns.

The first is sorting to simplify constraints. The conflict rule involves two dimensions (age and score), and checking it directly across arbitrary pairs is messy. Sorting by age (with score as a tiebreaker) collapses the problem to a single dimension. After sorting, you only need to check whether scores are non-decreasing, and you only need to look at earlier elements in the sorted order. This "sort to reduce dimensions" strategy is the same idea behind the Longest Increasing Subsequence binary search approach and the Russian Doll Envelopes problem.

The second is LIS-style DP with variable lookback. The transition dp[i] = max(dp[j] + score[i]) for all valid j < i is the same scan-back pattern from LIS. Each position looks at every predecessor and picks the best one that satisfies the compatibility condition. In LIS, the condition is "strictly less than." Here, it is "less than or equal to." The shape of the DP is identical. You define dp[i] as the best answer ending at index i, scan all earlier indices, check the condition, and take the max.

Once you recognize "sort, then run LIS-style DP" as a single reusable block, you can apply it to any problem where a multi-dimensional constraint can be reduced to a single-dimension ordering check.

From understanding to recall

You have just walked through the full solution: sort by (age, score), run LIS-style DP summing scores instead of counting length. The logic is clean and the connection to LIS is direct. But reading through a solution and writing it from scratch under pressure are very different skills.

In an interview, you need to independently see that sorting collapses the two-dimensional conflict rule into a one-dimensional check. You need to write the nested DP loop without hesitation and remember that dp[i] stores a sum, not a length. These details slip away without practice.

Spaced repetition is the most effective way to lock in this pattern. You revisit the problem at increasing intervals, write the sort + DP solution from memory, and each time the pattern becomes more automatic. After a few reps, you will recognize the "sort to reduce dimensions, then LIS-style DP" template instantly whenever it appears, whether the problem is about basketball teams, envelopes, or string chains.

Related posts