สแตกโมโนโทนิก: เพิ่มขึ้นเทียบกับลดลง
รักษาสแตกแบบเพิ่มขึ้นหรือลดลงเพื่อค้นหาค่าที่มากกว่าถัดไปและค่าน้อยกว่าก่อนหน้าอย่างมีประสิทธิภาพในเวลา O(n)
สแตกโมโนโทนิก: เพิ่มขึ้นเทียบกับลดลง เป็นบทเรียน Coding Interview Prep ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Coding Interview Prep และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Coding Interview Prep มีบทเรียนทั้งหมด 4 บทเรียน
สแตกแบบเพิ่มหรือลดอย่างเดียวคืออะไร
สแตกแบบเพิ่มหรือลดอย่างเดียว คือสแตกที่รักษาลำดับเรียงขององค์ประกอบไว้เสมอ โดยอาจเรียงเพิ่มจากล่างขึ้นบนตลอด หรือเรียงลดตลอด ก่อนดันองค์ประกอบใหม่เข้าไป เราจะดึงองค์ประกอบทั้งหมดที่ละเมิดค่าคงรูปแบบเพิ่มหรือลดออก โครงสร้างที่มีข้อจำกัดนี้ทำให้แก้ปัญหาที่เดิมต้องใช้ลูปซ้อนเวลา O(n²) ได้ในเวลา O(n)
แนวคิดสำคัญคือ องค์ประกอบแต่ละตัวจะถูกดันเข้าและดึงออกอย่างมากครั้งละหนึ่งครั้ง ดังนั้นจำนวนการดำเนินการรวมตลอดการวนผ่านอาร์เรย์จึงเป็น O(n) ไม่ใช่ O(n²) ทันทีที่เราดึงองค์ประกอบหนึ่งออก เราก็พบคำตอบที่องค์ประกอบนั้นรออยู่แล้ว
# Monotonic increasing stack (bottom to top: smallest to largest)
stack = []
for val in [3, 1, 4, 1, 5, 9, 2, 6]:
while stack and stack[-1] > val:
stack.pop() # maintain increasing invariant
stack.append(val)
print('Increasing stack (left-to-right):', stack) # [1, 1, 2, 6]
# Monotonic decreasing stack (bottom to top: largest to smallest)
stack = []
for val in [3, 1, 4, 1, 5, 9, 2, 6]:
while stack and stack[-1] < val:
stack.pop() # maintain decreasing invariant
stack.append(val)
print('Decreasing stack (left-to-right):', stack) # [9, 6]สมาชิกที่มากกว่าถัดไป I
ปัญหา สมาชิกที่มากกว่าถัดไป คือ สำหรับแต่ละองค์ประกอบ ให้ค้นหาองค์ประกอบแรกทางด้านขวาที่มีค่ามากกว่า การวนลูปซ้อนแบบตรวจสอบทุกคู่ซึ่งใช้เวลา O(n²) ช้าเกินไป เราแก้ปัญหานี้ได้ในเวลา O(n) ด้วย สแตกแบบเรียงลด
ประมวลผลองค์ประกอบจากซ้ายไปขวา ก่อนดันองค์ประกอบ i เข้าไป ให้ดึงองค์ประกอบทั้งหมดจากสแตกที่มีค่าน้อยกว่า nums[i] ออก เพราะ nums[i] คือสมาชิกที่มากกว่าถัดไปขององค์ประกอบเหล่านั้นทั้งหมด หลังจากประมวลผลครบทุกองค์ประกอบแล้ว รายการที่เหลืออยู่ในสแตกจะไม่มีองค์ประกอบที่มากกว่าอยู่ทางด้านขวา (คำตอบ = -1)
def next_greater_element(nums):
n = len(nums)
result = [-1] * n
stack = [] # stores indices; stack values are decreasing
for i in range(n):
# Pop elements smaller than nums[i]
while stack and nums[stack[-1]] < nums[i]:
idx = stack.pop()
result[idx] = nums[i] # nums[i] is next greater for idx
stack.append(i)
# Remaining elements in stack have no next greater => keep -1
return result
nums = [2, 1, 2, 4, 3]
print(next_greater_element(nums)) # [4, 2, 4, -1, -1]
nums2 = [1, 3, 2, 4]
print(next_greater_element(nums2)) # [3, 4, 4, -1]สมาชิกถัดไปที่มีค่ามากกว่า: การติดตามอัลกอริทึม
ให้ติดตาม [2, 1, 2, 4, 3] ทีละขั้นตอน เรารักษาสแตกของดัชนีแบบลดลง ซึ่งยังไม่พบสมาชิกถัดไปที่มีค่ามากกว่าสำหรับสมาชิกเหล่านั้น
- i=0, val=2: สแตกว่าง ให้ใส่ 0 สแตก: [0]
- i=1, val=1: 1 < nums[0]=2 ให้ใส่ 1 สแตก: [0,1]
- i=2, val=2: pop 1 (nums[1]=1 < 2), result[1]=2; ขณะนี้ nums[0]=2 ไม่ได้น้อยกว่า 2 ให้ใส่ 2 สแตก: [0,2]
- i=3, val=4: pop 2 (result[2]=4), pop 0 (result[0]=4) แล้วใส่ 3 สแตก: [3]
- i=4, val=3: 3 < nums[3]=4 ให้ใส่ 4 สแตก: [3,4]
- จบ: สมาชิกในสแตก [3,4] มีค่า result=-1
def next_greater_trace(nums):
n = len(nums)
result = [-1] * n
stack = []
for i in range(n):
print(f'i={i} val={nums[i]}: stack={[nums[s] for s in stack]}', end=' => ')
while stack and nums[stack[-1]] < nums[i]:
idx = stack.pop()
result[idx] = nums[i]
print(f'pop {nums[idx]}, NGE={nums[i]};', end=' ')
stack.append(i)
print(f'push {nums[i]}, stack={[nums[s] for s in stack]}')
print('Result:', result)
return result
next_greater_trace([2, 1, 2, 4, 3])สมาชิกก่อนหน้าที่มีค่าน้อยกว่า
สแตกแบบโมโนโทนิกยังใช้ตอบคำถามเกี่ยวกับ สมาชิกก่อนหน้าที่มีค่าน้อยกว่า (PSE) ได้ด้วย นั่นคือ สำหรับสมาชิกแต่ละตัว ให้ค้นหาสมาชิกที่อยู่ใกล้ที่สุดทางซ้ายและมีค่าน้อยกว่า แทนที่จะ pop เมื่อพบสมาชิกที่มีค่ามากกว่า เราจะ pop เมื่อพบสมาชิกที่มีค่ามากกว่าหรือเท่ากับ และบันทึกสมาชิกบนสุดของสแตกเป็น PSE ก่อนใส่สมาชิกปัจจุบัน
แนวทางจึงเปลี่ยนไป: เรายังคงประมวลผลจากซ้ายไปขวา แต่แทนที่จะตอบคำถามขณะ pop เราจะตอบคำถามทันทีก่อนใส่สมาชิก สมาชิกบนสุดของสแตกในขณะนั้นคือสมาชิกที่มีค่าน้อยกว่าซึ่งอยู่ใกล้ที่สุดทางซ้าย หากสแตกว่าง แสดงว่าไม่มีสมาชิกที่มีค่าน้อยกว่าทางซ้าย (คำตอบคือ -1 หรือค่าบ่งชี้พิเศษ)
def previous_smaller_element(nums):
n = len(nums)
result = [-1] * n
stack = [] # monotonic increasing (values increase bottom to top)
for i in range(n):
# Pop elements >= current (maintain strictly increasing invariant)
while stack and nums[stack[-1]] >= nums[i]:
stack.pop()
# Top of stack is previous smaller element (if exists)
if stack:
result[i] = nums[stack[-1]]
stack.append(i)
return result
nums = [4, 5, 2, 10, 8]
print('PSE:', previous_smaller_element(nums)) # [-1, 4, -1, 2, 2]
nums2 = [1, 3, 2, 5, 4]
print('PSE:', previous_smaller_element(nums2)) # [-1, 1, 1, 2, 2]อุณหภูมิรายวัน: รอวันที่อุ่นขึ้น
ปัญหา อุณหภูมิรายวัน (LeetCode 739): เมื่อกำหนดอุณหภูมิของแต่ละวัน ให้คืนค่าอาร์เรย์ที่สมาชิกแต่ละตัวระบุจำนวนวันก่อนจะพบอุณหภูมิที่อุ่นกว่า ปัญหานี้ใช้รูปแบบเดียวกับสมาชิกถัดไปที่มีค่ามากกว่า แต่แทนที่จะต้องการค่าที่มากกว่า เราต้องการจำนวนวัน (ผลต่างของดัชนี)
ให้ใช้สแตกแบบลดลงของดัชนี เมื่อพบอุณหภูมิที่อุ่นกว่าที่ดัชนี i ให้ pop ดัชนี j ทั้งหมดจากสแตกที่ temps[j] < temps[i] แล้วกำหนด result[j] = i - j ดัชนีที่เหลือไม่มีวันที่อุ่นกว่าในอนาคต (result = 0)
def daily_temperatures(temperatures):
n = len(temperatures)
result = [0] * n
stack = [] # indices of unresolved days
for i in range(n):
while stack and temperatures[stack[-1]] < temperatures[i]:
j = stack.pop()
result[j] = i - j # days until warmer
stack.append(i)
return result
temps = [73, 74, 75, 71, 69, 72, 76, 73]
print(daily_temperatures(temps)) # [1, 1, 4, 2, 1, 1, 0, 0]
temps2 = [30, 40, 50, 60]
print(daily_temperatures(temps2)) # [1, 1, 1, 0] (always warmer next day)
temps3 = [30, 60, 90]
print(daily_temperatures(temps3)) # [1, 1, 0]สแตกแบบเพิ่มขึ้นเทียบกับแบบลดลง: ควรใช้เมื่อใด
การเลือกทิศทางของสแตกให้ถูกต้องเป็นสิ่งสำคัญ:
- สแตกแบบลดลง (pop เมื่อค่าปัจจุบัน > ค่าบนสุด): ใช้ตอบคำถามเกี่ยวกับ สมาชิกถัดไปที่มีค่ามากกว่า และ สมาชิกก่อนหน้าที่มีค่ามากกว่า ใช้ในปัญหาอุณหภูมิรายวัน สี่เหลี่ยมผืนผ้าที่ใหญ่ที่สุด และการดักน้ำฝน
- สแตกแบบเพิ่มขึ้น (pop เมื่อค่าปัจจุบัน < ค่าบนสุด): ใช้ตอบคำถามเกี่ยวกับ สมาชิกถัดไปที่มีค่าน้อยกว่า และ สมาชิกก่อนหน้าที่มีค่าน้อยกว่า ใช้ในการหาช่วงของราคาหุ้นและจำนวนบุคคลที่มองเห็นได้ในแถว
โปรดจำไว้ว่า สมาชิกที่ทำให้เกิด pop คือคำตอบของคำถามสำหรับสมาชิกที่ถูกนำออกจากสแตก ซึ่งอาจเป็นสมาชิกถัดไปที่มีค่ามากกว่าหรือสมาชิกถัดไปที่มีค่าน้อยกว่า ขึ้นอยู่กับค่าคงที่ที่คุณรักษาไว้
# Summary: which stack type for which query?
queries = {
'Next Greater Element': 'Decreasing stack (pop when new > top)',
'Next Smaller Element': 'Increasing stack (pop when new < top)',
'Previous Greater Element': 'Decreasing stack (answer = top before push)',
'Previous Smaller Element': 'Increasing stack (answer = top before push)',
}
for query, approach in queries.items():
print(f'{query}:\n => {approach}\n')
# Mnemonic:
# NGE/PGE => decreasing stack (we pop smaller elements, finding their next/prev larger)
# NSE/PSE => increasing stack (we pop larger elements, finding their next/prev smaller)สมาชิกถัดไปที่มีค่ามากกว่าในอาร์เรย์วงกลม
สมาชิกถัดไปที่มีค่ามากกว่า II (LeetCode 503): เมื่อกำหนดอาร์เรย์วงกลม (วนกลับไปต้นอาร์เรย์ได้) ให้ค้นหาสมาชิกถัดไปที่มีค่ามากกว่า เคล็ดลับคือประมวลผลอาร์เรย์ สองครั้ง โดยทำให้ดัชนีเสมือนเพิ่มเป็นสองเท่า: วนตั้งแต่ 0 ถึง 2n-1 และใช้ index % n เพื่อวนกลับไปยังดัชนีที่ถูกต้อง ให้ใส่เฉพาะดัชนีตั้งแต่ 0 ถึง n-1 (ในการวนครั้งแรก) เพื่อไม่ให้นับซ้ำ
อีกวิธีหนึ่งคือ ในการวนครั้งที่สองให้ประมวลผลอาร์เรย์โดยไม่ใส่ดัชนีใหม่ ทำเฉพาะ pop เท่านั้น วิธีนี้จัดการการมองไปข้างหน้าในอาร์เรย์วงกลมได้ถูกต้องโดยไม่ต้องสร้างอาร์เรย์ซ้ำจริง และใช้พื้นที่ O(n)
def next_greater_element_circular(nums):
n = len(nums)
result = [-1] * n
stack = []
for i in range(2 * n):
while stack and nums[stack[-1]] < nums[i % n]:
idx = stack.pop()
result[idx] = nums[i % n]
if i < n:
stack.append(i) # only push real indices (0..n-1)
return result
print(next_greater_element_circular([1, 2, 1])) # [2, -1, 2]
print(next_greater_element_circular([1, 2, 3, 4, 3])) # [2, 3, 4, -1, 4]
print(next_greater_element_circular([5, 4, 3, 2, 1])) # [-1, 5, 5, 5, 5]ปัญหาช่วงราคาหุ้น
ปัญหา ช่วงราคาหุ้น: เมื่อกำหนดราคาหุ้นรายวัน ให้คำนวณช่วงของแต่ละวัน ซึ่งคือจำนวนวันก่อนหน้าที่ต่อเนื่องกันและมีราคาน้อยกว่าหรือเท่ากับราคาของวันนี้ แท้จริงแล้วนี่คือปัญหาสมาชิกก่อนหน้าที่มีค่ามากกว่าในรูปแบบหนึ่ง โดยช่วงคือระยะทางจากวันนี้ย้อนกลับไปยังวันที่ใกล้ที่สุดซึ่งมีราคาสูงกว่าอย่างเคร่งครัด
ให้ใช้สแตกแบบลดลง เมื่อประมวลผลวันที่ i ให้ pop ทุกวันที่มีราคา ≤ ราคาปัจจุบัน ช่วงคือ i - stack[-1] หากสแตกไม่ว่าง หรือคือ i + 1 หากสแตกว่าง (ราคาเป็นค่าสูงสุดจนถึงขณะนี้) จากนั้นให้ใส่ i ลงในสแตก
def stock_span(prices):
spans = []
stack = [] # indices of prices forming decreasing sequence
for i, price in enumerate(prices):
while stack and prices[stack[-1]] <= price:
stack.pop()
span = i - stack[-1] if stack else i + 1
spans.append(span)
stack.append(i)
return spans
prices = [100, 80, 60, 70, 60, 75, 85]
print('Prices:', prices)
print('Spans: ', stock_span(prices)) # [1, 1, 1, 2, 1, 4, 6]
# Verification for day 5 (price=75): prev higher is day 1 (80), span = 5-1 = 4
# Day 6 (price=85): prev higher is day 0 (100), span = 6-0 = 6สแตกแบบโมโนโทนิกสำหรับบุคคลที่มองเห็นได้ในแถว
ปัญหา จำนวนบุคคลที่มองเห็นได้ในแถว: บุคคลยืนต่อกันเป็นแถว โดยแต่ละคนมีความสูง บุคคล i สามารถมองเห็นบุคคล j (j > i) ได้ หากบุคคลทุกคนที่อยู่ระหว่างกลางเตี้ยกว่าคนทั้งสอง ปัญหานี้ใช้สแตกแบบลดลง
ประมวลผลจากขวาไปซ้าย รักษาสแตกของความสูงแบบลดลง สำหรับแต่ละคน ให้คำนวณจำนวนคนที่มองเห็นได้โดย pop คนที่เตี้ยกว่าทั้งหมด (มองเห็นได้ แต่หลังจากนั้นจะถูกคนที่สูงกว่าบัง) แล้วบวก 1 หากหลังจากนั้นสแตกไม่ว่าง (คนที่สูงกว่าคนแรกก็มองเห็นได้เช่นกัน) วิธีนี้ใช้เวลา O(n) โดยรวม เนื่องจากแต่ละคนถูกใส่และถูกนำออกจากสแตกไม่เกินหนึ่งครั้ง
def visible_people(heights):
n = len(heights)
result = [0] * n
stack = [] # decreasing monotonic stack (heights)
for i in range(n - 1, -1, -1): # right to left
count = 0
while stack and stack[-1] < heights[i]:
stack.pop()
count += 1 # can see this shorter person
if stack:
count += 1 # can see the first person >= heights[i]
result[i] = count
stack.append(heights[i])
return result
heights = [10, 6, 8, 5, 11, 9]
print('Heights:', heights)
print('Visible:', visible_people(heights)) # [3, 1, 2, 1, 1, 0]การรับประกัน O(n): เหตุใดสมาชิกทุกตัวจึงถูกใส่และนำออกจากสแตกไม่เกินหนึ่งครั้ง
การรับประกันเวลา O(n) ของอัลกอริทึมสแตกแบบโมโนโทนิกมาจากการวิเคราะห์ต้นทุนเฉลี่ยอย่างง่าย: สมาชิกแต่ละตัวถูกใส่ลงในสแตกหนึ่งครั้งพอดี และถูก pop อย่างมากหนึ่งครั้ง ไม่มีสมาชิกตัวใดถูกใส่หรือถูก pop มากกว่าหนึ่งครั้ง ดังนั้น จำนวนการดำเนินการเพิ่ม + pop ตลอดลูปทั้งหมดจึงไม่เกิน 2n ทำให้มีงานรวมเป็น O(n) แม้ลูป while ที่ซ้อนกันจะดูเหมือนบ่งชี้ว่าเป็น O(n²) ก็ตาม
การวิเคราะห์ต้นทุนเฉลี่ยนี้สำคัญเมื่อต้องอธิบายในสัมภาษณ์งาน ลูป while ไม่ได้ทำงาน n ครั้งต่อการวนแต่ละครั้ง แต่ทำงานเท่าที่จำเป็นเพื่อ pop สมาชิกที่รออยู่ และสมาชิกเหล่านั้นจะหายไปถาวรหลังจากถูก pop
def next_greater_instrumented(nums):
result = [-1] * len(nums)
stack = []
pushes = pops = 0
for i in range(len(nums)):
while stack and nums[stack[-1]] < nums[i]:
idx = stack.pop()
result[idx] = nums[i]
pops += 1
stack.append(i)
pushes += 1
print(f'n={len(nums)}, pushes={pushes}, pops={pops}')
print(f'Total operations = {pushes + pops} <= 2n = {2*len(nums)}')
return result
import random
nums = random.sample(range(1000), 100)
next_greater_instrumented(nums)
# Confirm: total operations always <= 2nการสังเกตปัญหาที่ใช้สแตกแบบโมโนโทนิก
ปัญหาน่าจะต้องใช้สแตกแบบโมโนโทนิก หากโจทย์ถามหา สมาชิกที่มีค่ามากกว่าหรือน้อยกว่าที่อยู่ใกล้ที่สุด ช่วงของราคา สมาชิกที่มองเห็นได้ในแถว หรือ พื้นที่ที่อิงจากฮิสโตแกรม ให้มองหาคำสำคัญและรูปแบบเหล่านี้: สมาชิกแต่ละตัวต้องการคำตอบจากสมาชิกที่เกี่ยวข้องซึ่งอยู่ใกล้ที่สุดในทิศทางใดทิศทางหนึ่ง (ซ้ายหรือขวา)
หากวิธีตรวจสอบทุกกรณีต้องสแกนไปทางซ้ายหรือขวาจากสมาชิกแต่ละตัว (O(n²)) ให้แทนที่การสแกนนั้นด้วยสแตกแบบโมโนโทนิก สแตกจะจดจำคำตอบที่เป็นตัวเลือก นำคำตอบที่ไม่เกี่ยวข้องออก และทำ pop คำตอบที่ถูกต้องในจังหวะที่ต้องการพอดี
# Monotonic stack problem recognition guide
patterns = [
('Next/previous greater element', 'Decreasing stack; answer found on pop'),
('Next/previous smaller element', 'Increasing stack; answer found on pop'),
('Days until warmer/colder', 'Stack of indices; answer = i - j'),
('Stock span', 'Decreasing stack; span = i - prev larger idx'),
('Largest rectangle in histogram', 'Increasing stack; area computed on pop'),
('Trapping rain water', 'Decreasing stack or two-pointer'),
('Sliding window maximum', 'Decreasing deque of indices'),
]
print('Monotonic Stack / Deque Pattern Guide:')
print('='*60)
for problem, approach in patterns:
print(f'Problem: {problem}')
print(f' Approach: {approach}')
print()ตรวจสอบความเข้าใจ
ทดสอบความเข้าใจแนวคิดเกี่ยวกับโครงสร้างข้อมูลและอัลกอริทึม — การเตรียมตัวสัมภาษณ์การเขียนโปรแกรมจากบทเรียนนี้
สรุปบทเรียน
ในบทเรียนนี้ คุณได้เรียนรู้ว่า สแตกแบบโมโนโทนิกจะรักษาลำดับแบบเพิ่มขึ้นหรือลดลง โดยนำสมาชิกที่ละเมิดค่าคงที่ออกก่อนใส่สมาชิกใหม่ สแตกแบบลดลงใช้ตอบคำถามเกี่ยวกับสมาชิกถัดไปหรือก่อนหน้าที่มีค่ามากกว่า ส่วนสแตกแบบเพิ่มขึ้นใช้ตอบคำถามเกี่ยวกับสมาชิกถัดไปหรือก่อนหน้าที่มีค่าน้อยกว่า และ สมาชิกแต่ละตัวถูกใส่และถูก pop ไม่เกินหนึ่งครั้ง จึงใช้เวลารวม O(n) ไม่ใช่ O(n²) ต่อไปเราจะประยุกต์ใช้สแตกแบบโมโนโทนิกเพื่อหาสี่เหลี่ยมผืนผ้าที่ใหญ่ที่สุดในฮิสโตแกรม
คำถามที่พบบ่อย
บทเรียน “สแตกโมโนโทนิก: เพิ่มขึ้นเทียบกับลดลง” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “สแตกโมโนโทนิก: เพิ่มขึ้นเทียบกับลดลง” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Coding Interview Prep ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Coding Interview Prep มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “สแตกโมโนโทนิก: เพิ่มขึ้นเทียบกับลดลง”
รักษาสแตกแบบเพิ่มขึ้นหรือลดลงเพื่อค้นหาค่าที่มากกว่าถัดไปและค่าน้อยกว่าก่อนหน้าอย่างมีประสิทธิภาพในเวลา O(n) คุณปฏิบัติ Coding Interview Prep ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Coding Interview Prep หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Coding Interview Prep บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน
บทเรียน “สแตกโมโนโทนิก: เพิ่มขึ้นเทียบกับลดลง” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Coding Interview Prep นี้ได้ไหม
ได้ บทเรียน Coding Interview Prep ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- สแตกโมโนโทนิก: เพิ่มขึ้นเทียบกับลดลง
- สี่เหลี่ยมผืนผ้าที่ใหญ่ที่สุดในฮิสโตแกรม
- ค่าสูงสุดในหน้าต่างเลื่อนด้วยคิวสองทางโมโนโทนิก
- กักเก็บน้ำฝน: สแตกและตัวชี้สองตัว