Program to find length of smallest sublist that can be deleted to make sum divisible by k in Python

When working with arrays and modular arithmetic, sometimes we need to find the shortest subarray to remove so that the remaining elements' sum is divisible by a given number k. This problem uses prefix sums and hash maps to efficiently find the optimal subarray to delete.

Problem Understanding

Given a list of positive integers and a positive number k, we need to find the length of the shortest subarray that can be deleted to make the remaining sum divisible by k. We cannot delete the entire array.

Example

For nums = [5,8,6,3] and k = 8:

  • Total sum = 22
  • 22 % 8 = 6 (remainder)
  • We need to remove elements with sum ? 6 (mod 8)
  • Removing [6] gives sum = 16, which is divisible by 8

Algorithm Steps

The solution uses prefix sums and modular arithmetic ?

  1. Calculate the remainder when total sum is divided by k
  2. If remainder is 0, no deletion needed
  3. Use prefix sums to find the shortest subarray with the target remainder
  4. Track remainders and their positions using a hash map

Implementation

def solve(nums, k):
    # Calculate remainder of total sum
    rem = sum(nums) % k
    
    # If already divisible, no deletion needed
    if rem == 0:
        return 0
    
    n = len(nums)
    presum = 0
    mp = {0: -1}  # Store remainder positions
    res = n
    
    for i in range(n):
        presum += nums[i]
        m = presum % k
        mp[m] = i
        
        # Look for complementary remainder
        target = (m - rem + k) % k
        if target in mp:
            res = min(res, i - mp[target])
    
    return res if res != n else -1

# Test with example
nums = [5, 8, 6, 3]
k = 8
result = solve(nums, k)
print(f"Shortest subarray length to delete: {result}")
Shortest subarray length to delete: 1

How It Works

The algorithm works by finding prefix sums and their remainders when divided by k. For each position, it checks if there's a previous prefix sum that, when subtracted, gives the target remainder we need to remove.

Step-by-Step Trace

def solve_with_trace(nums, k):
    total_sum = sum(nums)
    rem = total_sum % k
    print(f"Total sum: {total_sum}, remainder: {rem}")
    
    if rem == 0:
        return 0
    
    n = len(nums)
    presum = 0
    mp = {0: -1}
    res = n
    
    print("\nStep-by-step trace:")
    for i in range(n):
        presum += nums[i]
        m = presum % k
        print(f"Index {i}: element={nums[i]}, prefix_sum={presum}, remainder={m}")
        
        mp[m] = i
        target = (m - rem + k) % k
        
        if target in mp:
            length = i - mp[target]
            print(f"  Found matching remainder {target} at position {mp[target]}")
            print(f"  Subarray length: {length}")
            res = min(res, length)
    
    return res if res != n else -1

# Trace the example
nums = [5, 8, 6, 3]
k = 8
result = solve_with_trace(nums, k)
print(f"\nFinal result: {result}")
Total sum: 22, remainder: 6
Step-by-step trace:
Index 0: element=5, prefix_sum=5, remainder=5
Index 1: element=8, prefix_sum=13, remainder=5
Index 2: element=6, prefix_sum=19, remainder=3
  Found matching remainder 5 at position 1
  Subarray length: 1
Index 3: element=3, prefix_sum=22, remainder=6

Final result: 1

Time and Space Complexity

  • Time Complexity: O(n) where n is the length of the array
  • Space Complexity: O(k) for storing remainders in the hash map

Conclusion

This solution efficiently finds the shortest subarray to delete using prefix sums and modular arithmetic. The key insight is tracking remainder positions to quickly identify subarrays with the target sum modulo k.

Updated on: 2026-03-26T17:04:04+05:30

263 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements