LeetCode #3695 — HARD

Maximize Alternating Sum Using Swaps

Break down a hard problem into reliable checkpoints, edge-case handling, and complexity trade-offs.

Solve on LeetCode
The Problem

Problem Statement

You are given an integer array nums.

You want to maximize the alternating sum of nums, which is defined as the value obtained by adding elements at even indices and subtracting elements at odd indices. That is, nums[0] - nums[1] + nums[2] - nums[3]...

You are also given a 2D integer array swaps where swaps[i] = [pi, qi]. For each pair [pi, qi] in swaps, you are allowed to swap the elements at indices pi and qi. These swaps can be performed any number of times and in any order.

Return the maximum possible alternating sum of nums.

Example 1:

Input: nums = [1,2,3], swaps = [[0,2],[1,2]]

Output: 4

Explanation:

The maximum alternating sum is achieved when nums is [2, 1, 3] or [3, 1, 2]. As an example, you can obtain nums = [2, 1, 3] as follows.

  • Swap nums[0] and nums[2]. nums is now [3, 2, 1].
  • Swap nums[1] and nums[2]. nums is now [3, 1, 2].
  • Swap nums[0] and nums[2]. nums is now [2, 1, 3].

Example 2:

Input: nums = [1,2,3], swaps = [[1,2]]

Output: 2

Explanation:

The maximum alternating sum is achieved by not performing any swaps.

Example 3:

Input: nums = [1,1000000000,1,1000000000,1,1000000000], swaps = []

Output: -2999999997

Explanation:

Since we cannot perform any swaps, the maximum alternating sum is achieved by not performing any swaps.

Constraints:

  • 2 <= nums.length <= 105
  • 1 <= nums[i] <= 109
  • 0 <= swaps.length <= 105
  • swaps[i] = [pi, qi]
  • 0 <= pi < qi <= nums.length - 1
  • [pi, qi] != [pj, qj]
Patterns Used

Roadmap

  1. Brute Force Baseline
  2. Core Insight
  3. Algorithm Walkthrough
  4. Edge Cases
  5. Full Annotated Code
  6. Interactive Study Demo
  7. Complexity Analysis
Step 01

Brute Force Baseline

Problem summary: You are given an integer array nums. You want to maximize the alternating sum of nums, which is defined as the value obtained by adding elements at even indices and subtracting elements at odd indices. That is, nums[0] - nums[1] + nums[2] - nums[3]... You are also given a 2D integer array swaps where swaps[i] = [pi, qi]. For each pair [pi, qi] in swaps, you are allowed to swap the elements at indices pi and qi. These swaps can be performed any number of times and in any order. Return the maximum possible alternating sum of nums.

Baseline thinking

Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.

Pattern signal: Array · Greedy · Union-Find

Example 1

[1,2,3]
[[0,2],[1,2]]

Example 2

[1,2,3]
[[1,2]]

Example 3

[1,1000000000,1,1000000000,1,1000000000]
[]
Step 02

Core Insight

What unlocks the optimal approach

  • Build connected components using a DSU (disjoint-set union).
  • Let <code>E</code> be the count of even indices inside that component. In each component, place the largest <code>E</code> values on the component's even indices.
  • The component's contribution to the alternating sum is <code>2 * sumTopE - sumAll</code>, where <code>sumTopE</code> is the sum of the largest <code>E</code> values and <code>sumAll</code> is the sum of all values in the component.
Interview move: turn each hint into an invariant you can check after every iteration/recursion step.
Step 03

Algorithm Walkthrough

Iteration Checklist

  1. Define state (indices, window, stack, map, DP cell, or recursion frame).
  2. Apply one transition step and update the invariant.
  3. Record answer candidate when condition is met.
  4. Continue until all input is consumed.
Use the first example testcase as your mental trace to verify each transition.
Step 04

Edge Cases

Minimum Input
Single element / shortest valid input
Validate boundary behavior before entering the main loop or recursion.
Duplicates & Repeats
Repeated values / repeated states
Decide whether duplicates should be merged, skipped, or counted explicitly.
Extreme Constraints
Largest constraint values
Re-check complexity target against constraints to avoid time-limit issues.
Invalid / Corner Shape
Empty collections, zeros, or disconnected structures
Handle special-case structure before the core algorithm path.
Step 05

Full Annotated Code

Source-backed implementations are provided below for direct study and interview prep.

// Accepted solution for LeetCode #3695: Maximize Alternating Sum Using Swaps
// Auto-generated Java example from go.
class Solution {
    public void exampleSolution() {
    }
}
// Reference (go):
// // Accepted solution for LeetCode #3695: Maximize Alternating Sum Using Swaps
// package main
// 
// import "slices"
// 
// // https://space.bilibili.com/206214
// 
// // 模板来源 https://leetcode.cn/circle/discuss/mOr1u6/
// type unionFind struct {
// 	fa  []int // 代表元
// 	odd []int // 集合中的奇数个数
// }
// 
// func newUnionFind(n int) unionFind {
// 	fa := make([]int, n)
// 	odd := make([]int, n)
// 	// 一开始有 n 个集合 {0}, {1}, ..., {n-1}
// 	// 集合 i 的代表元是自己
// 	for i := range fa {
// 		fa[i] = i
// 		odd[i] = i % 2
// 	}
// 	return unionFind{fa, odd}
// }
// 
// // 返回 x 所在集合的代表元
// // 同时做路径压缩,也就是把 x 所在集合中的所有元素的 fa 都改成代表元
// func (u unionFind) find(x int) int {
// 	// 如果 fa[x] == x,则表示 x 是代表元
// 	if u.fa[x] != x {
// 		u.fa[x] = u.find(u.fa[x]) // fa 改成代表元
// 	}
// 	return u.fa[x]
// }
// 
// // 把 from 所在集合合并到 to 所在集合中
// func (u *unionFind) merge(from, to int) {
// 	x, y := u.find(from), u.find(to)
// 	if x == y { // from 和 to 在同一个集合,不做合并
// 		return
// 	}
// 	u.fa[x] = y          // 合并集合
// 	u.odd[y] += u.odd[x] // 更新集合中的奇数个数
// }
// 
// func maxAlternatingSum(nums []int, swaps [][]int) (ans int64) {
// 	n := len(nums)
// 	uf := newUnionFind(n)
// 	for _, p := range swaps {
// 		uf.merge(p[0], p[1])
// 	}
// 
// 	g := make([][]int, n)
// 	for i, x := range nums {
// 		f := uf.find(i)
// 		g[f] = append(g[f], x) // 相同集合的元素分到同一组
// 	}
// 
// 	for i, a := range g {
// 		if a == nil {
// 			continue
// 		}
// 		slices.Sort(a)
// 		odd := uf.odd[i]
// 		// 小的取负号,大的取正号
// 		for j, x := range a {
// 			if j < odd {
// 				ans -= int64(x)
// 			} else {
// 				ans += int64(x)
// 			}
// 		}
// 	}
// 	return
// }
Step 06

Interactive Study Demo

Use this to step through a reusable interview workflow for this problem.

Press Step or Run All to begin.
Step 07

Complexity Analysis

Time
O(n log n)
Space
O(1)

Approach Breakdown

EXHAUSTIVE
O(2ⁿ) time
O(n) space

Try every possible combination of choices. With n items each having two states (include/exclude), the search space is 2ⁿ. Evaluating each combination takes O(n), giving O(n × 2ⁿ). The recursion stack or subset storage uses O(n) space.

GREEDY
O(n log n) time
O(1) space

Greedy algorithms typically sort the input (O(n log n)) then make a single pass (O(n)). The sort dominates. If the input is already sorted or the greedy choice can be computed without sorting, time drops to O(n). Proving greedy correctness (exchange argument) is harder than the implementation.

Shortcut: Sort + single pass → O(n log n). If no sort needed → O(n). The hard part is proving it works.
Coach Notes

Common Mistakes

Review these before coding to avoid predictable interview regressions.

Off-by-one on range boundaries

Wrong move: Loop endpoints miss first/last candidate.

Usually fails on: Fails on minimal arrays and exact-boundary answers.

Fix: Re-derive loops from inclusive/exclusive ranges before coding.

Using greedy without proof

Wrong move: Locally optimal choices may fail globally.

Usually fails on: Counterexamples appear on crafted input orderings.

Fix: Verify with exchange argument or monotonic objective before committing.