Solving Leetcode Interviews in Seconds with AI: Permutations IV
Introduction
In this blog post, we will explore how to solve the LeetCode problem "3470" using AI. LeetCode is a popular platform for preparing for coding interviews, and with the help of AI tools like Chatmagic, we can generate solutions quickly and efficiently - helping you pass the interviews and get the job offer without having to study for months.
Problem Statement
Given two integers, n and k, an alternating permutation is a permutation of the first n positive integers such that no two adjacent elements are both odd or both even. Return the k-th alternating permutation sorted in lexicographical order. If there are fewer than k valid alternating permutations, return an empty list. Example 1: Input: n = 4, k = 6 Output: [3,4,1,2] Explanation: The lexicographically-sorted alternating permutations of [1, 2, 3, 4] are: [1, 2, 3, 4] [1, 4, 3, 2] [2, 1, 4, 3] [2, 3, 4, 1] [3, 2, 1, 4] [3, 4, 1, 2] ← 6th permutation [4, 1, 2, 3] [4, 3, 2, 1] Since k = 6, we return [3, 4, 1, 2]. Example 2: Input: n = 3, k = 2 Output: [3,2,1] Explanation: The lexicographically-sorted alternating permutations of [1, 2, 3] are: [1, 2, 3] [3, 2, 1] ← 2nd permutation Since k = 2, we return [3, 2, 1]. Example 3: Input: n = 2, k = 3 Output: [] Explanation: The lexicographically-sorted alternating permutations of [1, 2] are: [1, 2] [2, 1] There are only 2 alternating permutations, but k = 3, which is out of range. Thus, we return an empty list []. Constraints: 1 <= n <= 100 1 <= k <= 1015
Explanation
Here's a breakdown of the solution:
Understanding Alternating Permutations: The core idea is to generate alternating permutations efficiently. We can categorize numbers into odd and even sets. A valid alternating permutation must have elements from these sets alternatingly.
Counting Valid Permutations: We need to calculate the total number of possible alternating permutations for a given
n. If the k-th permutation exceeds this count, we return an empty list.Generating the k-th Permutation: The algorithm constructs the permutation digit by digit. At each step, it calculates how many permutations start with a specific number (either odd or even, based on the desired alternating pattern). If
kfalls within that count, the number is added to the result; otherwise,kis adjusted, and the process continues with the next candidate.Runtime Complexity: O(n^2), Storage Complexity: O(n)
Code
def alternating_permutations(n, k):
"""
Calculates the k-th alternating permutation of the first n positive integers.
Args:
n: The number of integers to permute.
k: The index of the desired permutation (1-based).
Returns:
A list representing the k-th alternating permutation, or an empty list if
there are fewer than k valid alternating permutations.
"""
if n == 0:
return []
# Calculate the number of alternating permutations.
if n <= 2:
num_alternating = factorial(n) # Simple case for n = 1 or 2
else:
num_alternating = count_alternating_permutations(n)
if k > num_alternating:
return []
k -= 1 # Convert to 0-based index for calculations.
nums = list(range(1, n + 1))
result = []
# Determine if the permutation should start with an odd or even number.
start_with_odd = (n + 1) // 2 >= (n // 2)
for i in range(n):
# Determine whether we're looking for odd or even for this index
if i % 2 == 0:
eligible_nums = [num for num in nums if (num % 2 != 0) == start_with_odd]
else:
eligible_nums = [num for num in nums if (num % 2 != 0) != start_with_odd]
num_eligible = len(eligible_nums)
for j in range(num_eligible):
num = eligible_nums[j]
# Calculate how many permutations start with num
remaining_nums = nums[:]
remaining_nums.remove(num)
num_permutations_starting_with_num = count_alternating_permutations_starting(n - i, remaining_nums, num, start_with_odd if i%2 == 0 else not start_with_odd)
if k < num_permutations_starting_with_num:
result.append(num)
nums.remove(num)
break
else:
k -= num_permutations_starting_with_num
return result
def count_alternating_permutations(n):
"""
Counts the number of alternating permutations for a given n.
"""
dp = {}
def solve(index, last_parity, remaining):
if index == n:
return 1
key = (index, last_parity, tuple(sorted(remaining)))
if key in dp:
return dp[key]
count = 0
for num in remaining:
parity = num % 2
if index == 0 or parity != last_parity:
new_remaining = remaining[:]
new_remaining.remove(num)
count += solve(index + 1, parity, new_remaining)
dp[key] = count
return count
all_nums = list(range(1, n + 1))
return solve(0, -1, all_nums) # -1 to indicate no previous parity at start.
def count_alternating_permutations_starting(remaining_length, remaining_nums, first_num, start_with_odd):
"""
Calculates the number of alternating permutations of the remaining numbers,
given that the permutation must start with `first_num` and alternate.
"""
if remaining_length <= 1:
return 1
dp = {}
def solve(index, last_parity, remaining):
if index == remaining_length:
return 1
key = (index, last_parity, tuple(sorted(remaining)))
if key in dp:
return dp[key]
count = 0
for num in remaining:
parity = num % 2
if parity != last_parity:
new_remaining = remaining[:]
new_remaining.remove(num)
count += solve(index + 1, parity, new_remaining)
dp[key] = count
return count
initial_parity = first_num % 2
return solve(1, initial_parity, remaining_nums)
def factorial(n):
if n == 0:
return 1
else:
return n * factorial(n-1)