Program to find lexicographically smallest string to move from start to destination in Python

Suppose we are at position (0, 0) in the Cartesian plane and want to reach point (x, y) using only horizontal (H) and vertical (V) moves of single unit. There are multiple possible paths to reach the destination, each comprising H and V moves. We need to find the lexicographically kth smallest path.

For example, to go from (0,0) to (2,2), one possible path is "HVVH". Since 'H' comes before 'V' lexicographically, paths starting with more H's appear earlier in lexicographical order.

Algorithm

The solution uses a greedy approach with combinatorial counting ?

  • Calculate how many paths exist if we choose 'H' first
  • If k is smaller than this count, choose 'H' and move right
  • Otherwise, choose 'V', subtract the count from k, and move up
  • Repeat until we reach the destination

Helper Function

First, we define a function to calculate the number of possible paths from current position to destination ?

from math import factorial

def paths(x, y):
    if min(x, y) < 0:
        return 0
    return factorial(x + y) // factorial(x) // factorial(y)

# Test the function
print("Paths from (0,0) to (2,1):", paths(2, 1))
print("Paths from (0,0) to (3,2):", paths(3, 2))
Paths from (0,0) to (2,1): 3
Paths from (0,0) to (3,2): 10

Complete Solution

Now we implement the main algorithm to find the kth lexicographically smallest path ?

from math import factorial

def paths(x, y):
    if min(x, y) < 0:
        return 0
    return factorial(x + y) // factorial(x) // factorial(y)

def solve(x, y, k):
    result = []
    current_x, current_y = 0, 0
    
    while (current_x, current_y) != (x, y):
        # Calculate paths if we choose 'H' next
        paths_with_h = paths(x - current_x - 1, y - current_y)
        
        # If we can move right and k is within H-paths range
        if current_x + 1 <= x and k <= paths_with_h:
            result.append('H')
            current_x += 1
        else:
            # Choose 'V' and adjust k
            k -= paths_with_h
            result.append('V')
            current_y += 1
    
    return ''.join(result)

# Test with the given example
x, y = 3, 3
k = 3
path = solve(x, y, k)
print(f"The {k}rd lexicographically smallest path to ({x}, {y}): {path}")

# Test with more examples
print(f"1st path to (2, 2): {solve(2, 2, 1)}")
print(f"2nd path to (2, 2): {solve(2, 2, 2)}")
print(f"3rd path to (2, 2): {solve(2, 2, 3)}")
The 3rd lexicographically smallest path to (3, 3): HHVVVH
1st path to (2, 2): HHVV
2nd path to (2, 2): HVHV
3rd path to (2, 2): HVVH

How It Works

The algorithm works by making greedy choices at each step ?

  1. Calculate remaining paths: At each position, calculate how many paths exist if we choose 'H' next
  2. Make decision: If k is within this count, choose 'H'. Otherwise, choose 'V' and reduce k
  3. Update position: Move to the new position and repeat

The paths() function uses the combination formula: C(x+y, x) = (x+y)! / (x! * y!) to count the number of ways to arrange x H's and y V's.

Example Walkthrough

For (3,3) with k=3, the algorithm proceeds as follows ?

Step Position Paths with H k ? paths? Choice New k
1 (0,0) 10 Yes (3 ? 10) H 3
2 (1,0) 5 Yes (3 ? 5) H 3
3 (2,0) 1 No (3 > 1) V 2
4 (2,1) 1 No (2 > 1) V 1
5 (2,2) 0 Yes (1 ? 1) V 1
6 (2,3) - - H -

Result: "HHVVVH"

Conclusion

This algorithm efficiently finds the kth lexicographically smallest path using combinatorial counting and greedy selection. The time complexity is O(x + y) and space complexity is O(x + y) for storing the result path.

Updated on: 2026-03-26T18:22:48+05:30

296 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements