11-dars: Stek
2-darajaKumush — usullar9–16 darslar
Bu darsdan keyin siz
- stekni Python ro’yxati bilan yozasiz va uning ikki amalini bilasiz
- qavslar to’g’riligini tekshirasiz
- «keyingi katta element» masalasini
O(n)da yechasiz
Avval qo’lda
“Avval qo’lda” bo'limiga havolaAvval qo‘lda
Kitoblarni birma-bir ustma-ust qo’ying va har qo’yganda nomini ayting. Endi sinfdoshingiz «uchinchi qo’ygan kitobingni ber» desin.
Nechta kitobni olib qo’yishga to’g’ri keldi? Endi «oxirgi qo’yganingni ber» desin — necha harakat kerak bo’ldi?
Nimani sezishingiz kerak
Oxirgisi bepul, o’rtadagisi qimmat. Stek aynan shuni ta’minlaydi: bitta uchi tez ishlaydi va shu cheklov uni sodda va ishonchli qiladi.
Kompyuter yopiq. Bu mashq tugamaguncha kod ochilmaydi.
Stek nima
“Stek nima” bo'limiga havolastekstack
Elementlar faqat bir uchidan qo’shiladigan va o’sha uchidan olinadigan tuzilma. «Oxirgi kelgan birinchi ketadi» qoidasi bilan ishlaydi.
Python’da alohida tur kerak emas: oddiy ro’yxatning append() va pop()
amallari aynan stek amallari va ikkalasi ham o’zgarmas vaqtda ishlaydi.
Siz stek bilan allaqachon tanishsiz.
Python Basic 14-darsidagi chaqiruv steki —
o’sha narsa: funksiya chaqirilganda stekka qo’shiladi, tugaganda
olinadi. RecursionError esa stek to’lganini bildiradi.
Birinchi misol: qavslar
“Birinchi misol: qavslar” bo'limiga havolaAvval o'ylang: bu kod nima chiqaradi? Ishga tushirishdan oldin yozing.
def togrimi(s): stek = [] juft = {")": "(", "]": "[", "}": "{"} for b in s: if b in "([{": stek.append(b) elif not stek or stek.pop() != juft[b]: return False return not stekprint(togrimi("([]{})"), togrimi("(]"), togrimi("(("))Haqiqiy natija:
True False False
Uchta holat: to'g'ri, mos kelmagan juftlik va yopilmagan qavs. Oxirgi return not stek aynan uchinchi holatni ushlaydi — stekda qolgan qavs ochiq qolgan degani.
Javobni ko'rish
True False False
Uchta holat: to'g'ri, mos kelmagan juftlik va yopilmagan qavs. Oxirgi return not stek aynan uchinchi holatni ushlaydi — stekda qolgan qavs ochiq qolgan degani.
Nega stek: yopuvchi qavs har doim eng oxirgi ochilgan qavsga tegishli. Bu esa stekning ta’rifi bilan bir xil gap.
Sekin yechim
“Sekin yechim” bo'limiga havolaEndi asosiy masala. Qatorda o’quvchilar turibdi; har biri uchun o’ngdagi birinchi baland kishini toping. To’liq izlash har o’quvchidan o’ngga yuguradi.
boy = [3, 1, 4, 1, 5, 9]javob = []for i in range(len(boy)): topilgan = -1 for j in range(i + 1, len(boy)): if boy[j] > boy[i]: topilgan = boy[j] break javob.append(topilgan)print(javob)Avval o'ylang: bu kod nima chiqaradi? Ishga tushirishdan oldin yozing.
boy = [3, 1, 4, 1, 5, 9]javob = []for i in range(len(boy)): topilgan = -1 for j in range(i + 1, len(boy)): if boy[j] > boy[i]: topilgan = boy[j] break javob.append(topilgan)print(javob)Haqiqiy natija:
[4, 4, 5, 5, 9, -1]
Oxirgi o'quvchidan baland hech kim yo'q, shuning uchun -1. Kamayuvchi tartibda turgan qatorda esa har o'quvchi oxirigacha yugurishga majbur bo'ladi.
Javobni ko'rish
[4, 4, 5, 5, 9, -1]
Oxirgi o'quvchidan baland hech kim yo'q, shuning uchun -1. Kamayuvchi tartibda turgan qatorda esa har o'quvchi oxirigacha yugurishga majbur bo'ladi.
Nega sekin
“Nega sekin” bo'limiga havolaEng yomon holat — qator kamayuvchi tartibda tursa. Unda har o’quvchi oxirigacha yuguradi va hech narsa topmaydi.
Sig‘adimi?
Bir soniyada taxminan 10⁸ oddiy amal bajariladi.
| Yechim | n = 1 000 | n = 5 000 | n = 200 000 |
|---|---|---|---|
Har birdan o‘ngga yugurishn^2 | 10⁶sig‘adi | 10⁷sig‘adi | 10¹⁰sig‘maydi |
Stek bilan bir yurishn | 1 000sig‘adi | 5 000sig‘adi | 200 000sig‘adi |
Yashil — yechim o‘tadi. Sariq — chegarada, konstanta va til muhim bo‘lib qoladi. Qizil — bu yechim bilan bormaydi, boshqasini qidiring.
Tez yechim
“Tez yechim” bo'limiga havolaO’ngdan chapga yuramiz va stekda faqat hali kerak bo’lishi mumkin bo’lganlarni saqlaymiz. Yangi o’quvchi kelganda undan past bo’lganlar stekdan chiqariladi: ular endi hech kimga «birinchi baland» bo’la olmaydi, chunki yangi kelgan ham balandroq, ham yaqinroq.
boy = [3, 1, 4, 1, 5, 9]javob = [-1] * len(boy)stek = []for i in range(len(boy) - 1, -1, -1): while stek and stek[-1] <= boy[i]: stek.pop() if stek: javob[i] = stek[-1] stek.append(boy[i])print(javob)Avval o'ylang: bu kod nima chiqaradi? Ishga tushirishdan oldin yozing.
boy = [3, 1, 4, 1, 5, 9]javob = [-1] * len(boy)stek = []for i in range(len(boy) - 1, -1, -1): while stek and stek[-1] <= boy[i]: stek.pop() if stek: javob[i] = stek[-1] stek.append(boy[i])print(javob)Haqiqiy natija:
[4, 4, 5, 5, 9, -1]
Javob avvalgisi bilan bir xil. Farqi — bu yechim har elementni bir marta ko'radi.
Javobni ko'rish
[4, 4, 5, 5, 9, -1]
Javob avvalgisi bilan bir xil. Farqi — bu yechim har elementni bir marta ko'radi.
Sinab ko’r
“Sinab ko’r” bo'limiga havolaVizualda stekdan nima chiqib ketayotganini kuzating. Chiqqan element boshqa hech qachon kerak bo’lmaydi — algoritmning butun tejami shunda.
Stek — keyingi katta element
Stekdan nima chiqib ketayotganiga qarang: chiqqan element boshqa hech qachon kerak bo'lmaydi.
O'ngdan chapga yurib, stekda kamayuvchi bo'ylar saqlanadi; stek uchi — javob.
Algoritmning har qadami quyidagi ro‘yxatda matn sifatida ham berilgan — vizual faqat shu qadamlarni chizadi, yangi ma’lumot qo‘shmaydi.
- Har o'quvchi uchun o'ngdagi birinchi baland kishini qidiramiz. O'ngdan chapga yuramiz — o'ng tomon allaqachon ko'rilgan bo'ladi.
- Stek bo'sh: 9 dan o'ngda undan baland odam yo'q. Javob -1.
- 5 uchun javob — stek uchidagi 9.
- 1 uchun javob — stek uchidagi 5.
- 1 stekdan chiqdi: u 4 dan past. Endi u hech kimga «birinchi baland» bo'la olmaydi — 4 ham balandroq, ham yaqinroq.
- 4 uchun javob — stek uchidagi 5.
- 1 uchun javob — stek uchidagi 4.
- 1 stekdan chiqdi: u 3 dan past. Endi u hech kimga «birinchi baland» bo'la olmaydi — 3 ham balandroq, ham yaqinroq.
- 3 uchun javob — stek uchidagi 4.
- Tayyor. Ichkarida while sikli bo'lsa ham, jami 8 amal ketdi: har element stekka bir marta kirdi va bir marta chiqdi.
Har o'quvchi uchun o'ngdagi birinchi baland kishini qidiramiz. O'ngdan chapga yuramiz — o'ng tomon allaqachon ko'rilgan bo'ladi.
Amal0
Xatoni toping
“Xatoni toping” bo'limiga havolaTuzoq — xatoni toping
11 / 40
MasalaQavslar to'g'ri joylashganini tekshiring.
Taklif qilingan yechim
Bu javobning 4-qismi noto'g'ri. Satr tugaganda stek BO'SH ekanini ham tekshirish kerak. (( satrida hech qanday nomuvofiqlik yo'q, lekin ikkita qavs ochiq qoladi. Shuningdek ikkinchi qadamda stek bo'sh bo'lsa pop() xato beradi — ) bilan boshlanadigan satrda shunday bo'ladi.
Javobning qaysi qismi noto'g'ri? Bosib belgilang.
Satr tugaganda stek BO'SH ekanini ham tekshirish kerak. (( satrida hech qanday nomuvofiqlik yo'q, lekin ikkita qavs ochiq qoladi. Shuningdek ikkinchi qadamda stek bo'sh bo'lsa pop() xato beradi — ) bilan boshlanadigan satrda shunday bo'ladi.
Bu tuzoqda ikkita chegara holati bir joyga to’plangan: ortiqcha ochilgan va ortiqcha yopilgan qavs. Ikkalasi ham asosiy sikl ichida emas, uning chetlarida yashiringan — 15-darsning mavzusi aynan shunday joylar.
O’zingizni sinang
“O’zingizni sinang” bo'limiga havola1Python'da stek uchun qaysi ikki amal ishlatiladi?
Javobni ko'rish
append() — uchiga qo’shish, pop() — uchidan olish. Ikkalasi ham
o’zgarmas vaqtda ishlaydi, chunki ro’yxatning oxiri bilan ishlanadi.
2Nega qavslar masalasida aynan stek kerak?
Javobni ko'rish
Yopuvchi qavs har doim eng oxirgi ochilgan qavsga tegishli. «Eng oxirgisi» degan talab — stekning ta’rifi.
3Ichida while bo'lgan yechim nega O(n) bo'lib qoladi?
Javobni ko'rish
Har element stekka bir marta kiradi va bir marta chiqadi. Demak barcha
pop() chaqiruvlari jami n tadan oshmaydi.
4Bo'sh stekdan pop() qilinsa nima bo'ladi?
Javobni ko'rish
IndexError chiqadi va programma to’xtaydi. Shuning uchun har pop()
dan oldin if stek: tekshiruvi turishi kerak.
5Chaqiruv steki bilan bu darsdagi stek bir narsami?
Javobni ko'rish
Ha, bir tuzilma. Funksiya chaqirilganda chaqiruv stekiga qo’shiladi,
tugaganda olinadi. RecursionError — o’sha stek to’lgani.
Masalalar
“Masalalar” bo'limiga havolaMasalalar
3 ta
- Nearest Smaller ValuesCSES 1645o'rta
Darsdagi masalaning ko‘zgudagi aksi: chapda birinchi KICHIK element.
- Bracket SequenceCodeforces 223Ao'rta
Stekda indekslarni saqlang — uzunlikni hisoblash uchun o‘rin kerak bo‘ladi.
- TowersCSES 1073o'rta
Bu yerda stek emas, ko‘p stek kerak. Har kubni qaysi minoraga qo‘yish afzalligini o‘ylang.
Lokal mashq: mashqlar/11-keyingi-katta/ — masala matni, testlar va tekshir.py. Avval sekin.py ni o‘zingiz yozing, keyin tayyorini oching.
Topshiriq
“Topshiriq” bo'limiga havolaTopshiriq — darajangizni tanlang
Asos · 5–7-sinf — Vizual va aniq ko'rsatmali
3 1 4 1 5 9 2 6 qatori uchun har o’quvchining o’ngdagi birinchi
baland qo’shnisini qog’ozda toping. Keyin xuddi shuni stek bilan
qadamma-qadam yozib chiqing: stekda qachon nima turgan?
Mustahkam · 8–9-sinf — Matnli masala, o'zingiz tuzasiz
11-keyingi-katta masalasini yeching. Yechimingizni ikki chegara
holatida sinang: butunlay o’suvchi qator va butunlay kamayuvchi
qator. Qaysi birida stek eng katta bo’ladi?
Chuqur · 10–11-sinf — Algoritmik, chegara holatlari bilan
Qavslar masalasini kengaytiring: satr noto’g’ri bo’lsa, nechanchi belgida buzilganini ham chiqaring. Ochiq qolgan qavs holatida javob nima bo’lishi kerak?
Darsni belgilash uchun JavaScript kerak. Bu progressni saqlash uchun ishlatiladi — darslikning o'zi JavaScript'siz ham to'liq o'qiladi.