- this seems pretty easy... there was a problem the other day where we had to sort one array based on the sorted values in another array -- I think it was sorting people's names by their heights. The main addition here is finding a way to efficiently apply
mapping
tonums
. - I'll convert
nums
to a string, then loop throughmapping
and replace each digit innums
with its corresponding index. Then I can useast.literal_eval()
to convert the stringified list back to a list, sort it, and return it. - One sneaky potential "gotcha" is that Python doesn't like converting strings with leading zeros to integers. So I'll need to manually remove those from the stringified list before evaluating it. I think the easiest way will be to split the string on
,
to get each item, then.lstrip('0')
from each of those. Also I'll want to remove the leading[
from the stringified list before splitting it so.lstrip('0')
handles the first item correctly. - ah actually, there's one more thing to account for -- items in
nums
can be0
, so I'll need to remove leading 0s IFF they're followed by a non-zero digit. So I think instead of splitting the stringified list and using.lstrip('0')
, I'll use a regular expression withre.sub()
to remove leading zeros. This will involve (1) a positive lookahead assertion to match 0s IFF they're followed by a non-zero digit, and (2) a positive lookbehind assertion to match 0s IFF they're preceded by a space, so I think the pattern will be(?<= )0+(?=[1-9])
. To deal with the first element in the stringified list potentially having leading 0s, I could make the lookbehind assertion(?<= \[)
, but I think it'll be faster to just replace the opening bracket with a space and then undo it after the substitution, rather than give the regex engine additional checks to run.
- I'm realizing there was a silly error in my initial thinking -- if I loop through
mapping
and replace digits one at a time, I'll end up replacing already-replaced digits in later iterations. So I'll want to use a translation table instead to make multiple simultaneous replacements.
from ast import literal_eval
from re import compile
class Solution:
pattern = compile(r'(?<= )0+(?=[1-9])')
def sortJumbled(self, mapping: List[int], nums: List[int]) -> List[int]:
if mapping == list(range(10)):
return sorted(nums)
mapped_nums = str(nums)
trans_table = str.maketrans('0123456789', ''.join(map(str, mapping)))
mapped_nums = mapped_nums.translate(trans_table)
mapped_nums = self.pattern.sub('', mapped_nums.replace('[', ' '))
mapped_nums = literal_eval('[' + mapped_nums[1:])
mapped_ixs = sorted(range(len(mapped_nums)), key=mapped_nums.__getitem__)
return [nums[i] for i in mapped_ixs]
from ast import literal_eval
from re import compile
class Solution:
pattern = compile(r'(?<= )0+(?=[1-9])')
def sortJumbled(self, mapping: List[int], nums: List[int]) -> List[int]:
if mapping == [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]:
yield from sorted(nums)
else:
mapped_nums = literal_eval(
'[' + self.pattern.sub('', str(nums).translate(
str.maketrans('0123456789', ''.join(map(str, mapping)))
).replace('[', ' '))[1:]
)
for i in sorted(range(len(mapped_nums)), key=mapped_nums.__getitem__):
yield nums[i]
Yikes, pretty poor memory usage on this one... probably because of the regular expression. But I'll stick with it for tonight.