Asosiy mazmunga o'tish

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

~5 daqiqajuftlikda5–6 ta kitob yoki daftar

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.

stekstack

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.

Avval o'ylang: bu kod nima chiqaradi? Ishga tushirishdan oldin yozing.

Bashorat qiling
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("(("))
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.

Endi asosiy masala. Qatorda o’quvchilar turibdi; har biri uchun o’ngdagi birinchi baland kishini toping. To’liq izlash har o’quvchidan o’ngga yuguradi.

sekin.py
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.

Bashorat qiling
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)
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.

Eng 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.

Yechimn = 1 000n = 5 000n = 200 000
Har birdan o‘ngga yugurishn^210⁶sig‘adi10⁷sig‘adi10¹⁰sig‘maydi
Stek bilan bir yurishn1 000sig‘adi5 000sig‘adi200 000sig‘adi

Yashil — yechim o‘tadi. Sariq — chegarada, konstanta va til muhim bo‘lib qoladi. Qizil — bu yechim bilan bormaydi, boshqasini qidiring.

O’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.

tez.py
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.

Bashorat qiling
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)
Javobni ko'rish
[4, 4, 5, 5, 9, -1]

Javob avvalgisi bilan bir xil. Farqi — bu yechim har elementni bir marta ko'radi.

Vizualda 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.

  1. Har o'quvchi uchun o'ngdagi birinchi baland kishini qidiramiz. O'ngdan chapga yuramiz — o'ng tomon allaqachon ko'rilgan bo'ladi.
  2. Stek bo'sh: 9 dan o'ngda undan baland odam yo'q. Javob -1.
  3. 5 uchun javob — stek uchidagi 9.
  4. 1 uchun javob — stek uchidagi 5.
  5. 1 stekdan chiqdi: u 4 dan past. Endi u hech kimga «birinchi baland» bo'la olmaydi — 4 ham balandroq, ham yaqinroq.
  6. 4 uchun javob — stek uchidagi 5.
  7. 1 uchun javob — stek uchidagi 4.
  8. 1 stekdan chiqdi: u 3 dan past. Endi u hech kimga «birinchi baland» bo'la olmaydi — 3 ham balandroq, ham yaqinroq.
  9. 3 uchun javob — stek uchidagi 4.
  10. Tayyor. Ichkarida while sikli bo'lsa ham, jami 8 amal ketdi: har element stekka bir marta kirdi va bir marta chiqdi.
bo'ylar
301142135495
javob
stek

Har o'quvchi uchun o'ngdagi birinchi baland kishini qidiramiz. O'ngdan chapga yuramiz — o'ng tomon allaqachon ko'rilgan bo'ladi.

Amal0

1/10

Tuzoq — 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.

1Python'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

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 — 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.