. ▁▁▁▁ ▁This ▁pre - processing ▁is ▁done ▁in ▁O ( n ) ▁time , ▁where ▁n ▁is ▁the ▁length ▁of ▁S . ▁▁▁▁ ▁""" ▁▁▁▁ ▁if ▁len ( S ) ▁== ▁ 0 : ▁ ▁# ▁Hand les ▁case ▁of ▁empty ▁string ▁▁▁▁▁▁▁▁ ▁return ▁[] ▁▁▁▁ ▁if ▁len ( S ) ▁== ▁ 1 : ▁ ▁# ▁Hand les ▁case ▁of ▁single - character ▁string ▁▁▁▁▁▁▁▁ ▁return ▁[ 1 ] ▁▁▁▁ ▁z ▁= ▁[ 0 ▁for ▁x ▁in ▁S ] ▁▁▁▁ ▁z [ 0 ] ▁= ▁len ( S ) ▁▁▁▁ ▁z [ 1 ] ▁= ▁match _ length ( S , ▁ 0 , ▁ 1 ) ▁▁▁▁ ▁for ▁i ▁in ▁range ( 2 , ▁ 1 + z [ 1 ] ): ▁ ▁# ▁Opt im ization ▁from ▁exercise ▁ 1 - 5 ▁▁▁▁▁▁▁▁ ▁z [ i ] ▁= ▁z [ 1 ] - i + 1 ▁▁▁▁ ▁# ▁Def ines ▁lower ▁and ▁upper ▁limits ▁of ▁z - box ▁▁▁▁ ▁l ▁= ▁ 0 ▁▁▁▁ ▁r ▁= ▁ 0 ▁▁▁▁ ▁for ▁i ▁in ▁range ( 2 + z [ 1 ], ▁len ( S )): ▁▁▁▁▁▁▁▁ ▁if ▁i ▁<= ▁r : ▁ ▁# ▁i ▁falls ▁within ▁existing ▁z - box ▁▁▁▁▁▁▁▁▁▁▁▁ ▁k ▁= ▁i - l ▁▁▁▁▁▁▁▁▁▁▁▁ ▁b ▁= ▁z [ k ] ▁▁▁▁▁▁▁▁▁▁▁▁ ▁a ▁= ▁r - i + 1 ▁▁▁▁▁▁▁▁▁▁▁▁ ▁if ▁b ▁< ▁a : ▁ ▁# ▁b ▁ends ▁within ▁existing ▁z - box ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ ▁z [ i ] ▁= ▁b ▁▁▁▁▁▁▁▁▁▁▁▁ ▁else : ▁ ▁# ▁b ▁ends