Reverse a String
لديك سلسلة نصية s مكوّنة من أحرف إنجليزية وأرقام. أعد سلسلة نصية جديدة تحتوي على الأحرف نفسها بترتيب معكوس، بحيث يأتي الحرف الأخير أولًا والأول أخيرًا. أبقِ كل حرف كما هو تمامًا، بما في ذلك حالة الأحرف.
الدالة
- sstring
- السلسلة المراد عكسها
- تُرجعstring
- أحرف s بترتيب عكسي
القيود
1 ≤ s.length ≤ 104sلا يحتوي إلا على أحرف إنجليزية (aإلىz، وAإلىZ) وأرقام (0إلى9).
أمثلة
- المدخلات
- s = "Coddy2026"
- المخرجات
- "6202yddoC"
- الشرح
- اقرأ
Coddy2026من آخر حرف فيه إلى أوله:6،2،0،2، ثمy،d،d،oوأخيرًا الحرف الكبيرC.
- المدخلات
- s = "noon"
- المخرجات
- "noon"
- الشرح
- كلمة
noonمتناظرة، لذا فإن عكسها هو الكلمة نفسها. يتبادل الحرفانnفي الطرفين موضعيهما، ثم يفعل الحرفانoذلك.
- المدخلات
- s = "Q"
- المخرجات
- "Q"
- الشرح
- السلسلة المكوّنة من حرف واحد ليس فيها شيء لتبدّله به، لذا تعود دون تغيير.
+14 اختبارات مخفية عند الإرسال
سؤال إضافي
كيف يمكنك عكس ترتيب الكلمات في جملة، وتحويل hello big world إلى world big hello، مع الحفاظ على ترتيب حروف كل كلمة؟
تلميحات
افتحها واحدًا تلو الآخر. كل تلميح يكشف أكثر قليلًا.
ينتهي الحرف عند الفهرس
0في النهاية في الإجابة. أين ينتهي الحرف عند الفهرسi؟ينتقل إلى الفهرس
n-1-i. يتبادل الحرف الأول والأخير موضعيهما، ثم الحرف الثاني وما قبل الأخير، وهكذا باتجاه المنتصف.انسخ السلسلة إلى مصفوفة من الأحرف. أبقِ فهرسًا عند البداية وآخر عند النهاية، وبدّل الحرفين، ثم حرّك كلا الفهرسين نحو الداخل حتى يلتقيا. بعد ذلك، ادمج المصفوفة مجددًا في سلسلة.
الحل
لكل حرف موضع ثابت: الحرف عند الفهرس i ينتمي إلى الفهرس n-1-i. يمكنك كتابة الأحرف في سلسلة جديدة بهذا الترتيب، أو تبديلها على شكل أزواج بدءًا من الطرفين. التبديل هو الطريقة التي يطلبها المحاورون في المقابلات، لأن تحريك المؤشرين نفسيهما يعكس مصفوفة في مكانها ويتحقق مما إذا كانت متناظرة.
انسخ الأحرف من الخلف
الفكرة
يبدأ معكوس s بآخر محرف من s، ثم يتابع بالمحرف ما قبل الأخير، وينتهي بالمحرف الأول. لذا مرّر فهرسًا من n-1 نزولًا إلى 0، وأضف كل محرف إلى الإجابة عند الوصول إليه. بالنسبة إلى Coddy2026، تضيف 6، و2، و0، و2، وy، وهكذا، لتكوين 6202yddoC.
تُقرأ كل محرف مرة واحدة وتُكتب مرة واحدة، لذا يكون العمل O(n). الإجابة عبارة عن سلسلة ثانية تتكوّن من n محرفًا، وهذا يتطلب مساحة إضافية O(n).
طريقة الإضافة مهمة. فإضافة محرف واحد إلى سلسلة غير قابلة للتغيير باستخدام + تنسخ السلسلة بأكملها في كل مرة، وبالنسبة إلى n = 10^4 فهذا يعني نحو 5 × 10^7 عملية نسخ للمحارف. اجمع المحارف في قائمة أو في أداة إنشاء السلاسل، ثم ادمجها مرة واحدة في النهاية.
الخوارزمية
- أنشئ قائمة فارغة أو أداةً لبناء سلسلة نصية للإجابة.
- كرّر
iمنn-1تنازليًا حتى0. - أضف
s[i]إلى الإجابة. - ادمج عناصر الإجابة في سلسلة نصية وأعِدها.
def reverseString(s):
result = []
for i in range(len(s) - 1, -1, -1):
result.append(s[i])
return "".join(result)بدّل من الطرفين باستخدام مؤشرين
الفكرة
يعكس الترتيب أزواج الأحرف بدءًا من الخارج إلى الداخل. يتبادل الحرف الأول والأخير موضعيهما، ثم الثاني وما قبل الأخير، وهكذا باتجاه الوسط. ضع مؤشرًا left عند الفهرس 0 ومؤشرًا right عند الفهرس n-1، وبدّل الحرفين، ثم حرّك كلا المؤشرين خطوة واحدة نحو الداخل.
توقّف عندما يلتقي المؤشران أو يتجاوز أحدهما الآخر. في noon يبدأ المؤشران عند 0 و3، ثم ينتقلان إلى 1 و2، وبعد ذلك يتجاوز أحدهما الآخر، وذلك بعد تبديلين. في سلسلة ذات طول فردي مثل xYz، يلتقيان عند الحرف الأوسط، الذي يكون في موضعه النهائي بالفعل، لذا لا يتم لمسه مطلقًا. يضع كل تبديل حرفين في موضعيهما النهائيين، لذا تكفي n / 2 من التبديلات لإنجاز المهمة.
لا تحتاج عمليات التبديل نفسها إلا إلى متغير مؤقت واحد، أي مساحة إضافية O(1). لا تتيح لك معظم اللغات تغيير سلسلة نصية في مكانها، لذا تنسخها أولًا إلى مصفوفة أحرف، وهذا يكلّف O(n). في مقابلة يكون فيها المُدخل مصفوفة أحرف بالفعل، يعكس هذا الأسلوب ترتيبها من دون أي ذاكرة إضافية.
الخوارزمية
- انسخ
sإلى مصفوفة من الأحرف. - عيّن
left = 0وright = n-1. - ما دام
left < right، بدّل الحرفين عندleftوright، ثم أضف 1 إلىleftواطرح 1 منright. - حوّل المصفوفة مرة أخرى إلى سلسلة وأعِدها.
def reverseString(s):
chars = list(s)
left, right = 0, len(chars) - 1
while left < right:
chars[left], chars[right] = chars[right], chars[left]
left += 1
right -= 1
return "".join(chars)
أخطاء شائعة وحالات حدّية
يبدو عكس الترتيب كسطر واحد، لكن الأخطاء تكمن في حدود الحلقة وفي طريقة بناء الإجابة.
- تكرار الحلقة باستخدام
leftحتىn-1. بعد الوصول إلى المنتصف، يُبدَّل كل زوج مرة ثانية، فيعود النص كما كان. توقّف عندleft < right. - بدء الحلقة العكسية من
nبدلًا منn-1، ما يؤدي إلى قراءة موضع واحد بعد النهاية. أمّا في Lua وR، فتبدأ الفهارس من1وتنتهي عندn. - بناء الإجابة باستخدام
result = result + chمع سلسلة نصية غير قابلة للتغيير. تنسخ كل خطوة كل ما بُني حتى تلك اللحظة، ما يحوّل مهمة خطية إلى مهمة تربيعية مع المدخلات الطويلة. - نسيان
'\0'المنهي في C. فالمخزن المؤقت الذي يتسع لـnبايتات ينقصه بايت واحد؛ خصّصn + 1. - التبديل دون استخدام متغير مؤقت: بعد
chars[left] = chars[right]يضيع الحرف القديم الموجود في الموضع الأيسر، إلا إذا كانت لغتك تبدّل القيمتين معًا.
أسئلة شائعة4
ما هو التعقيد الزمني لعكس سلسلة نصية؟
يستغرق العكس زمنًا قدره O(n)، لأن كل حرف يجب أن ينتقل إلى موضع جديد، وتتم معالجة كل حرف مرة واحدة. ويتطلب إنشاء سلسلة جديدة مساحة إضافية قدرها O(n). ولا يحتاج التبديل باستخدام مؤشرين إلا إلى مساحة إضافية قدرها O(1) عندما تكون الأحرف موجودة بالفعل في مصفوفة قابلة للتعديل.
كيف تعكس سلسلة نصية دون استخدام دالة عكس مضمّنة؟
انسخ الأحرف إلى مصفوفة، وضع مؤشرًا عند كل طرف، وبدّل الحرفين، ثم حرّك المؤشرين نحو بعضهما حتى يلتقيا. وبدلًا من ذلك، كرّر من الفهرس الأخير نزولًا إلى الأول، وألحِق كل حرف بمنشئ السلسلة. تنتج كلتا الطريقتين السلسلة المعكوسة في تمريرة واحدة.
هل يمكنك عكس سلسلة نصية في مكانها؟
فقط عندما تكون الأحرف موجودة في مخزن مؤقت قابل للتغيير، مثل مصفوفة char في C أو Java أو C#، أو قائمة في Python، أو std::string في C++. تكون السلاسل النصية في Java وPython وJavaScript والعديد من اللغات الأخرى غير قابلة للتغيير، لذا تنسخها إلى مصفوفة، وتبدّل الأحرف داخلها، ثم تنشئ سلسلة نصية جديدة. وتتم خطوة التبديل نفسها في المكان في كلتا الحالتين.
لماذا تتوقف حلقة المؤشرين عند المنتصف؟
يضع كل تبديل حرفين في موضعيهما النهائيين، لذا بعد n / 2 تبديلات يكون كل حرف في موضعه الصحيح. الاستمرار بعد المنتصف يبدّل الأزواج نفسها مرة أخرى، فيلغي ما تم إنجازه. عندما يكون الطول فرديًا، يكون الحرف الأوسط في فهرس صورته المعكوسة أصلًا، ولا يحتاج إلى تبديل.
مسائل مشابهة
مسائل تعتمد على الأفكار نفسها. حلّ اثنتين أو ثلاث منها يثبّت النمط.
Python
def reverseString(s):
# اكتب الكود هناالحالة 1
الحالة 2
الحالة 3
المدخلات
s = "Coddy2026"
المتوقع
"6202yddoC"