Ro'yxatni aylantirish
Massivni aylantirish (rotate) — elementlarni belgilangan miqdorda bir tomonga siljitish. Bu masala turli yo'llar bilan yechilishi mumkin va yechimlar orasidagi farq xotira sarfida keskin bo'ladi. Masala shuningdek "teskari aylantirish" hiylasini o'rgatadi — oddiy amalni uch marta qo'llash orqali murakkab natijaga erishish.
Masala
n uzunlikdagi massiv va k son berilgan. Massivni o'ng tomonga k qadam aylantirish kerak. Ya'ni, har bir element k katak o'ngga siljiydi; oxiridagi elementlar esa boshiga o'tadi.
Kirish: [1, 2, 3, 4, 5, 6, 7], k = 3
Chiqish: [5, 6, 7, 1, 2, 3, 4]
Kirish: [−1, −100, 3, 99], k = 2
Chiqish: [3, 99, −1, −100]
Izoh: k massiv uzunligidan katta bo'lishi mumkin. k = 10, massiv uzunligi 7 bo'lsa, aslida 10 % 7 = 3 qadam aylantiriladi.
Dastlabki g'oya — bitta-bitta aylantirish
Eng sodda yondashuv: massivni k marta, har safar 1 qadam aylantirishni takrorlash.
Bir marta 1 qadam o'ngga aylantirish: - Oxirgi elementni saqla. - Barcha elementlarni bir katak o'ngga sur. - Saqlab qo'yilgan elementni birinchi katakka qo'y.
FUNCTION bir_qadam(array)
oxirgi = array[n - 1]
FOR i = n - 1 DAN 1 GACHA
array[i] = array[i - 1]
array[0] = oxirgi
FUNCTION aylantir_bitta_bitta(array, k)
k = k % array uzunligi
FOR i = 1 DAN k GACHA
bir_qadam(array)
Murakkablik: O(n × k) vaqt, O(1) xotira. k katta bo'lsa, bu juda sekin.
Ikkinchi g'oya — qo'shimcha massiv
Kattaroq, lekin tushunarliroq yondashuv: yangi massiv yaratilib, har bir element to'g'ri joyiga yoziladi.
i-indexdagi element (i + k) % n-indexga ko'chishi kerak:
FUNCTION aylantir_yangi(array, k)
n = array uzunligi
k = k % n
yangi = n o'lchamli bo'sh massiv
FOR i = 0 DAN n - 1 GACHA
yangi[(i + k) % n] = array[i]
FOR i = 0 DAN n - 1 GACHA
array[i] = yangi[i]
[1, 2, 3, 4, 5, 6, 7], k = 3
element 1 (i=0) → yangi[(0+3)%7] = yangi[3]
element 2 (i=1) → yangi[(1+3)%7] = yangi[4]
element 3 (i=2) → yangi[(2+3)%7] = yangi[5]
element 4 (i=3) → yangi[(3+3)%7] = yangi[6]
element 5 (i=4) → yangi[(4+3)%7] = yangi[0]
element 6 (i=5) → yangi[(5+3)%7] = yangi[1]
element 7 (i=6) → yangi[(6+3)%7] = yangi[2]
yangi = [5, 6, 7, 1, 2, 3, 4] ✓
Murakkablik: O(n) vaqt, O(n) xotira. Tez, lekin qo'shimcha massiv kerak.
Optimal yondashuv — uch marta teskari aylantirish
Eng samarali yondashuv: massivni uchta kichik bosqichda teskari aylantirib, natijalari kombinatsiyasidan maqsadga erishish. Bu O(n) vaqt va O(1) xotira beradi.
Mantiq:
Kuzating:
- [5, 6, 7] — aslning oxirgi k = 3 ta elementi;
- [1, 2, 3, 4] — aslning birinchi n - k = 4 ta elementi.
Uch qadam:
- Butun massivni teskari aylantir:
[7, 6, 5, 4, 3, 2, 1] - Birinchi
kta elementni teskari aylantir:[5, 6, 7, 4, 3, 2, 1] - Qolgan
n - kta elementni teskari aylantir:[5, 6, 7, 1, 2, 3, 4]
FUNCTION teskari_oraliq(array, chap, o'ng)
WHILE chap < o'ng
array[chap] VA array[o'ng] JOYINI ALMASHTIR
chap = chap + 1
o'ng = o'ng - 1
FUNCTION aylantir(array, k)
n = array uzunligi
k = k % n
teskari_oraliq(array, 0, n - 1)
teskari_oraliq(array, 0, k - 1)
teskari_oraliq(array, k, n - 1)
Bosqichma-bosqich tahlil
[1, 2, 3, 4, 5, 6, 7], k = 3 uchun:
1-qadam: Butun massivni teskari aylantir:
[1, 2, 3, 4, 5, 6, 7]
↑ ↑
Almashtirish: 1 ↔ 7 → [7, 2, 3, 4, 5, 6, 1]
2 ↔ 6 → [7, 6, 3, 4, 5, 2, 1]
3 ↔ 5 → [7, 6, 5, 4, 3, 2, 1]
Natija: [7, 6, 5, 4, 3, 2, 1]
2-qadam: Birinchi k = 3 ta elementni teskari aylantir (index 0..2):
3-qadam: Qolgan n - k = 4 ta elementni teskari aylantir (index 3..6):
[5, 6, 7, 4, 3, 2, 1]
↑ ↑
4 ↔ 1 → [5, 6, 7, 1, 3, 2, 4]
3 ↔ 2 → [5, 6, 7, 1, 2, 3, 4]
Natija: [5, 6, 7, 1, 2, 3, 4] ✓
Nima uchun bu ishlaydi?
Butun massivni teskari aylantirganingizda, oxirgi k ta element boshiga keladi — lekin teskari tartibda. Ikkinchi qadamda shu k ta elementni teskari aylantirsangiz, ular to'g'ri tartibga keladi. Uchinchi qadamda qolgan qismni teskari aylantirsangiz, ular ham to'g'ri tartibga kiradi.
Bu g'oya algebraga asoslanadi. Teskari aylantirish operatsiyasi — o'z inversiga teng. Ikki marta teskari aylantirish asl holatni qaytaradi.
Murakkablik
| Yondashuv | Vaqt | Xotira |
|---|---|---|
| Bitta-bitta aylantirish | O(n × k) |
O(1) |
| Qo'shimcha massiv | O(n) |
O(n) |
| Uch marta teskari aylantirish | O(n) |
O(1) |
Uch marta teskari aylantirish usulida 3 marta teskari aylantirish bajariladi, har biri O(n). Jami O(3n), ya'ni O(n). Xotira faqat almashtirish uchun bitta o'zgaruvchi — O(1).
Muhim hollar
k = 0: Aylantirish bo'lmaydi. k % n = 0, barcha operatsiyalar bo'sh oraliqda bajariladi. Massiv o'zgarmaydi.
k = n: To'liq bir aylanish. k % n = 0. Massiv o'zgarmaydi.
k > n: k % n orqali haqiqiy qadam soniga keltiriladi.
Bitta element: n = 1, k % 1 = 0. Massiv o'zgarmaydi.
Manfiy aylantirish: Ba'zi masalalar chap tomonga aylantirish ham so'raydi. Chap tomonga k qadam = o'ng tomonga n - k qadam.
Warning
k % n hisoblashni unutmaslik kerak. Aks holda k = 14, n = 7 bo'lsa, ikki marta to'liq aylantirish amalga oshiriladi — bu qimmat va noto'g'ri.
Qaysi texnika ishlatildi?
Bu masalada teskari aylantirish (reverse) texnikasi qo'llanildi. Oddiy amalni — elementlarni almashtirish — uch marta turli oraliqda qo'llash orqali murakkab natijaga erishiladi. Bu "qurilish bloklari" yondashuvi: oddiy operatsiyalardan murakkab transformatsiya yasash.