সমস্যা:
লেক্সিকোগ্রাফিকভাবে সর্বনিম্ন সার্কুলার সাবস্ট্রিং এ জাতীয় সমস্ত ঘূর্ণনের সর্বনিম্ন লেকোগ্রাফিকাল ক্রমযুক্ত স্ট্রিংয়ের ঘূর্ণন আবিষ্কার করার সমস্যা finding উদাহরণস্বরূপ, "bbaaccaadd" এর অভিধানের ন্যূনতম ঘূর্ণন "aaccaaddbb" হবে।
সমাধান:
এও (এন) সময়ের অ্যালগরিদম জিন পিয়েরে ডুভাল (1983) দ্বারা প্রস্তাবিত হয়েছিল।
দুটি সূচক দেওয়া হয়েছে i
এবং j
, ডুভালের অ্যালগোরিদম দৈর্ঘ্যের স্ট্রিং সেগমেন্টের সাথে j - i
শুরু হয় i
এবং j
( "ডুয়েল" নামে পরিচিত ) তুলনা করে । যদি index + j - i
স্ট্রিংয়ের দৈর্ঘ্যের চেয়ে বেশি হয় তবে চারপাশে মোড়ানো দ্বারা বিভাগটি গঠিত হয়।
উদাহরণস্বরূপ, s = "বাবাবাবা", i = 5 এবং j = 7. বিবেচনা করুন, যেহেতু j - i = 2, i = 5 থেকে শুরু হওয়া প্রথম বিভাগটি "আব"। জে = 7 এ শুরু হওয়া দ্বিতীয় বিভাগটি চারপাশে মোড়ানো দ্বারা তৈরি করা হয়েছে এবং এটি "আব "ও রয়েছে। যদি উপরের উদাহরণের মতো স্ট্রিংগুলি ডিক্সিকোগ্রাফিকভাবে সমান হয় তবে আমরা বিজয়ী হিসাবে i থেকে শুরু করা একটি বেছে নেব, যা i = 5।
আমাদের একক বিজয়ী না হওয়া পর্যন্ত উপরের প্রক্রিয়াটি পুনরাবৃত্তি হয়েছে। যদি ইনপুট স্ট্রিংটি বিজোড় দৈর্ঘ্যের হয় তবে সর্বশেষ অক্ষরটি প্রথম পুনরাবৃত্তির তুলনা ছাড়াই জয়ী হয়।
সময়ের জটিলতা:
প্রথম পুনরাবৃত্তি প্রতিটি দৈর্ঘ্যের 1 (এন / 2 তুলনা) এর স্ট্রিংগুলির সাথে তুলনা করে, দ্বিতীয় পুনরাবৃত্তির দৈর্ঘ্য 2 (এন / 2 তুলনা) এর n / 2 স্ট্রিংগুলির সাথে তুলনা করতে পারে, এবং অন্যদিকে, i-th পুনরাবৃত্তির 2 টি স্ট্রিংয়ের তুলনা করা হয় দৈর্ঘ্য এন / 2 (এন / 2 তুলনা)। যেহেতু প্রতিবার বিজয়ীর সংখ্যা অর্ধেক হয়ে গেছে, পুনরাবৃত্তি গাছের উচ্চতা লগ (এন) হয়, সুতরাং এটি আমাদের ও (এন লগ (এন)) অ্যালগরিদম দেয়। ছোট এন এর জন্য এটি প্রায় ও (এন)।
স্পেস জটিলতা ও (এন) হ'ল, প্রথম পুনরাবৃত্তির পরে, আমাদের এন / 2 বিজয়ী, দ্বিতীয় পুনরাবৃত্তি এন / 4 বিজয়ী এবং আরও অনেক কিছু সঞ্চয় করতে হবে। (উইকিপিডিয়া দাবি করে যে এই অ্যালগরিদম ধ্রুবক স্থান ব্যবহার করে, আমি বুঝতে পারি না কীভাবে)।
এখানে একটি স্কাল বাস্তবায়ন; আপনার প্রিয় প্রোগ্রামিং ভাষায় রূপান্তর করতে নির্দ্বিধায়
def lexicographicallyMinRotation(s: String): String = {
@tailrec
def duel(winners: Seq[Int]): String = {
if (winners.size == 1) s"${s.slice(winners.head, s.length)}${s.take(winners.head)}"
else {
val newWinners: Seq[Int] = winners
.sliding(2, 2)
.map {
case Seq(x, y) =>
val range = y - x
Seq(x, y)
.map { i =>
val segment = if (s.isDefinedAt(i + range - 1)) s.slice(i, i + range)
else s"${s.slice(i, s.length)}${s.take(s.length - i)}"
(i, segment)
}
.reduce((a, b) => if (a._2 <= b._2) a else b)
._1
case xs => xs.head
}
.toSeq
duel(newWinners)
}
}
duel(s.indices)
}