Use this to learn the idea, then write your own version.
123 45class Solution(object):6 def lexSmallest(self, s):7 """8 :type s: str9 :rtype: str10 """11 MOD = 10**9+712 B = 2913 def binary_search(left, right, check):14 while left <= right:15 mid = left+(right-left)216 if check(mid):17 right = mid-118 else:19 left = mid+120 return left21 22 def get_prefix_hash(l, r):23 return (prefix[r+1]-prefix[l]*base[r-l+1])%MOD if l <= r else 024 25 def get_suffix_hash(l, r):26 return (suffix[l]-suffix[r+1]*base[r-l+1])%MOD if l <= r else 027 28 def get_total_hash(k, t, l):29 if not t:30 return get_suffix_hash(k-l, k-1) if l <= k else ((get_suffix_hash(0, k-1))*base[l-k]+get_prefix_hash(k, l-1))%MOD31 nk = len(s)-k32 return get_prefix_hash(0, l-1) if l <= nk else ((get_prefix_hash(0, nk-1))*base[l-nk]+get_suffix_hash(len(s)-(l-nk), len(s)-1))%MOD33 34 def get_char(k, t, idx):35 if not t:36 return s[(k-1)-idx] if idx < k else s[idx]37 return s[idx] if idx < len(s)-k else s[(len(s)-1)-(idx-(len(s)-k))]38 39 def is_less(k, i):40 idx = binary_search(0, len(s)-1, lambda x: get_total_hash(k, i, x+1) != get_total_hash(best_k, best_i, x+1))41 return idx != len(s) and get_char(k, i, idx) < get_char(best_k, best_i, idx)42 43 prefix = [0]*(len(s)+1)44 for i in xrange(len(prefix)-1):45 prefix[i+1] = (prefix[i]*B+ord(s[i]))%MOD46 suffix = [0]*(len(s)+1)47 for i in reversed(xrange(len(suffix)-1)):48 suffix[i] = (suffix[i+1]*B+ord(s[i]))%MOD49 base = [1]*(len(s)+1)50 for i in xrange(len(base)-1):51 base[i+1] = (base[i]*B)%MOD52 best_k, best_i = 1, 053 mn = min(s)54 for k in xrange(1, len(s)+1):55 if s[k-1] != mn:56 continue57 if is_less(k, 0):58 best_k, best_i = k, 059 for k in xrange(1, len(s)+1):60 if not s[-k] >= s[-1]:61 continue62 if is_less(k, 1):63 best_k, best_i = k, 164 return s[:best_k][::-1]+s[best_k:] if not best_i else s[:-best_k]+s[-best_k:][::-1]65 66 67686970class Solution2(object):71 def lexSmallest(self, s):72 """73 :type s: str74 :rtype: str75 """76 result = s77 for k in xrange(2, len(s)+1):78 result = min(result, s[:k][::-1]+s[k:], s[:-k]+s[-k:][::-1])79 return result80 81 82838485class Solution3(object):86 def lexSmallest(self, s):87 """88 :type s: str89 :rtype: str90 """91 return min(min(s[:k][::-1]+s[k:], s[:-k]+s[-k:][::-1]) for k in xrange(1, len(s)+1))92