Greedy Python Solution with Explanation
Observation:\nFor any test case we will have some number of \'a\' in the start one or zero character from \'b\' to \'y\' in the middle and some number of \'z\' 
**Observation:**\nFor any test case we will have some number of \'a\' in the start one or zero character from \'b\' to \'y\' in the middle and some number of \'z\' in the end.\n\n**Intuition:**\nWe want the lexicographically smallest string. If we have a choice to either chose b/w **`az`** and **`by`**, we will chose **`az`** as it is smaller. This suggests that at each step we can make a greedy choice of taking the smallest possible character. However this greedy choice must be made considering that at **i\'th** iteration after taking the smallest character can we still divide the remaining number of k into **n-i-1** ***(remaining number of n)*** number of groups of 26 ***(character \'z\')*** . In simpler terms we want to take the smallest possible character while considering that can the remaining numeric value k be divided into remaining number of \'z\' character. We are counting on the fact that k is divisible by n-i-1.\nk -> Reamining numeric value.\nn - i - 1 -> Remaining number of characters exclusive of the current character in iteration.\nj -> Numeric value of current character.\nSince, `{ (k - j) / (n - i - 1) } <= 26` **(if not it will go beyond character \'z\')**\n=> `26 * (n - i - 1) >= k - j` **(This condition is used in the code)**\n\n**Steps:**\n1. Iterate over range(n).\n2. For each iteration check if taking \'a\' is possible.\n3. If not then find that middle element b/w \'b\' and \'y\' by iterating over 1 to 26 till the remaining number of k can be divided into remaining number of characters(n-i-1).\n4. Till now we found the starting and middle elements. We now need to find the number of \'z\' elements.\n5. If k is still available then check if it is <26. If is is then append that character.\n6. If k is >= 26 then it can be divided into k//26 number of \'z\' characters. So append \'z\' times k//26.\n7. Join the array and return it.\n\n**Code:**\n```\nclass Solution:\n    def getSmallestString(self, n: int, k: int) -> str:\n        offset, arr = 96, []\n        for i in range(n):\n            j = 1\n            # Meaning that if we consider the current char to be \'a\' then the remaining\n            # number of numeric value k cannot be divided into required number of \'z\'\n            if 26*(n-i-1) < k-j:\n                for j in range(1, 27): # Check which middle character to take\n                    if j > k or 26*(n-i-1) >= k-j: # If remaining number of k cannot be divided into n-i-1 groups of \'z\'(26)\n                        break\n            k -= j\n            arr.append(chr(j+offset))\n            # Since latest element is not \'a\', we most probably found the middle character(\'b\' to \'y\')\n            if arr[-1] != \'a\' and k > 0:\n                if k < 26: # If k < 26 then we cannot fill in \'z\'\n                    arr.append(chr(k+offset))\n                else: # If k > 26 then we can fill k//2 number of \'z\'\n                    arr.append(\'z\' * (k // 26))\n                break # All k have been expired by this point. Thus break and return \n        return \'\'.join(arr)\n```
['Greedy', 'Python', 'Python3']