Shortest Rotated Distance
def sortedCharLocationMap(word, indices):
"""
:param word: [string] target key mapping
:param indices: List [int] target value mapping
:return: dictionary [char]:[List[int]]
"""
map = collections.defaultdict(list)
for i, char in enumerate(word):
map[char].append(indices[i])
for key, locs in map.items():
map[key] = sorted(locs)
return map
def mapRotatedDistances(word, start):
"""
:param word: [string] rotated word
:param start: [int] relative to
:return: List [int]
"""
distance_ar = [float('inf') for i in range(0, len(word))]
rev_it = 1
for i in range(0, len(word)):
actual = (i + start) % len(word)
distance_ar[actual] = min(distance_ar[actual], i)
for i in reversed(range(0, len(word))):
actual = (i + start) % len(word)
distance_ar[actual] = min(distance_ar[actual], rev_it)
rev_it += 1
return distance_ar
def binarySearchMinDist(dup_chars, left, right, key):
if (left <= right):
mid = int(left + abs(left - right) / 2)
mid_dist = abs(dup_chars[mid] - key)
if mid + 1 < len(dup_chars) and mid - 1 >= 0:
if abs(dup_chars[mid+1] - key) >= mid_dist \
and abs(dup_chars[mid - 1] - key) >= mid_dist:
return dup_chars[mid]
elif mid - 1 >= 0 and mid + 1 >= len(dup_chars):
if abs(dup_chars[mid-1] - key) >= mid_dist:
return dup_chars[mid]
elif mid + 1 < len(dup_chars) and mid - 1 < 0:
if abs(dup_chars[mid+1] - key) >= mid_dist:
return dup_chars[mid]
elif mid + 1 >= len(dup_chars) and mid - 1 < 0:
return dup_chars[mid]
if dup_chars[mid] > key:
return binarySearchMinDist(dup_chars, left, mid-1, key)
else:
return binarySearchMinDist(dup_chars, mid+1, right, key)
else:
return -1
def shortestRotatedDistance(word, start_i, search):
"""
:param word: [string] full word to search
:param start_i: [int] index to start search
:param search: [char] target search
:return: [int] min distance
"""
distance_array = mapRotatedDistances(word, start_i)
char_locs = sortedCharLocationMap(word, distance_array)
dup_chars = char_locs[search]
start_i = distance_array[start_i]
return binarySearchMinDist(dup_chars, 0, len(dup_chars) - 1, start_i)
# find the minimum distance from index i to char c in word
print(shortestRotatedDistance("godding", 0, 'g')) # 0
print(shortestRotatedDistance("godding", 0, 'd')) # 2
print(shortestRotatedDistance("godding", 1, 'n')) # 3
print(shortestRotatedDistance("godding", 5, 'g')) # 1
print("\n")
print(shortestRotatedDistance("dadiedd", 0, 'a')) # 1
print(shortestRotatedDistance("dadiedd", 3, 'd')) # 1
print(shortestRotatedDistance("dadiedd", 2, 'e')) # 2
print("\n")
print(shortestRotatedDistance("ggggggg", 0, 'g')) # 0
print(shortestRotatedDistance("ggggggg", 3, 'g')) # 0
print(shortestRotatedDistance("ggggggg", 2, 'g')) # 0
print("\n")
print(shortestRotatedDistance("ggggggghhhhh", 7, 'g')) # 1
print(shortestRotatedDistance("ggggggghhhhh", 0, 'h')) # 1
print(shortestRotatedDistance("ggggggghhhhh", 1, 'h')) # 2
print("\n")
print(shortestRotatedDistance("ahahahahaha", 0, 'h')) # 1
print(shortestRotatedDistance("ahahahahaha", 1, 'a')) # 1
print(shortestRotatedDistance("ahahahahaha", 5, 'a')) # 1
print("\n")Last updated