โจทย์
ให้อาร์เรย์ arr เราต้องลบสับอาร์เรย์ (subarray) หนึ่งช่วงออก เพื่อให้สมาชิกที่เหลือเรียงลำดับไม่ลดลง (non-decreasing) ต้องการหาความยาวของสับอาร์เรย์ที่สั้นที่สุดที่ต้องลบ
ตัวอย่าง: arr = [10,20,30,100,40,20,30,50] ผลลัพธ์คือ 3 เพราะลบ [100, 40, 20] (ความยาว 3) แล้วเหลือ [10,20,30,30,50] ที่เรียงไม่ลดลง
อัลกอริทึม
- ให้
nเป็นขนาดของarr - เพิ่มค่า
0ด้านซ้ายและinfinityด้านขวาของarr - สร้างลิสต์ว่าง
AและB - กำหนด
p = 1,q = len(arr) - 2,M = 0 - วนลูป بينما
p ≤ q:- ถ้า
arr[p-1] ≤ arr[p]: เพิ่มarr[p]ลงA, เพิ่มp - มิฉะนั้นถ้า
arr[q] ≤ arr[q+1]: เพิ่มarr[q]ลงB, แล้วลบสมาชิกท้ายของAทั้งหมดที่มากกว่าสมาชิกท้ายของB, ลดq - มิฉะนั้น: ออกจากลูป
- ถ้า
- อัปเดต
M = max(M, len(A) + len(B)) - คืนค่า
n - M
ตัวอย่างโค้ด
def solve(arr):
n = len(arr)
arr = [0] + arr + [float("inf")]
A, B = [], []
p, q = 1, len(arr) - 2
M = 0
while p <= q:
if arr[p-1] <= arr[p]:
A.append(arr[p])
p += 1
elif arr[q] <= arr[q+1]:
B.append(arr[q])
while A and A[-1] > B[-1]:
A.pop()
q -= 1
else:
break
M = max(M, len(A) + len(B))
return n - M
arr = [10, 20, 30, 100, 40, 20, 30, 50]
print(solve(arr)) # Output: 3
อินพุต / เอาต์พุต
Input: [10,20,30,100,40,20,30,50]
Output: 3