งานคือแบ่งอาร์เรย์ arr[] เป็น K ช่วงย่อยติดต่อกัน (consecutive sub-arrays) และหาค่าสูงสุดที่เป็นไปได้ของ "ค่าสูงสุดของค่าต่ำสุด" ของ K ช่วงย่อยเหล่านั้น
ตัวอย่าง
ตัวอย่างที่ 1
Input: arr[] = {2,8,4,3,9,1,5}, K=3
Output: 9
คำอธิบาย: แบ่งเป็น 3 ช่วง: {2,8,4,3}, {9}, {1,5}
ค่าต่ำสุดแต่ละช่วง: 2, 9, 1 → ค่าสูงสุดของค่าเหล่านี้ = 9
ตัวอย่างที่ 2
Input: arr[] = {8,4,1,9,11}, K=1
Output: 11
K=1 → ช่วงเดียว = อาร์เรย์ทั้งหมด → ค่าต่ำสุด = 1 แต่ output บอก 11? สังเกต: โจทย์อาจหมายถึง "ค่าสูงสุดของค่าต่ำสุด" แต่ K=1 ค่าต่ำสุดคือ min ของอาร์เรย์ทั้งหมด ตัวอย่าง output 11 ไม่สอดคล้อง → น่าจะเป็น ค่าสูงสุดของอาร์เรย์ (max) เมื่อ K=1
ข้อสังเกตสำคัญ (Key Insight)
ปัญหานี้มี 3 กรณีหลัก:
กรณี 1: K = 1
มีแค่ 1 ช่วง = อาร์เรย์ทั้งหมด → "ค่าต่ำสุดของช่วง" = min ของอาร์เรย์ → "ค่าสูงสุดของค่าต่ำสุด" = min ของอาร์เรย์
แต่ตัวอย่าง output ให้ 11 (max) → โจทย์จริงอาจเป็น: หา max ของ min แต่ K=1 ให้ max ของอาร์เรย์ (อาจเป็นข้อผิดพลาดในโจทย์ต้นฉบับ)
กรณี 2: K = 2
แบ่งเป็น 2 ช่วง: prefix และ suffix ต้องหาจุดแบ่งที่ทำให้ max(min(prefix), min(suffix)) สูงสุด
- คำนวณ
prefixMin[i]= min จาก index 0 ถึง i - คำนวณ
suffixMin[i]= min จาก index i ถึง n-1 - ลองจุดแบ่งทุกจุด:
maxVal = max(maxVal, max(prefixMin[i], suffixMin[i+1]))
กรณี 3: K ≥ 3
สามารถแยกองค์ประกอบ มากที่สุด (max element) ออกมาเป็นช่วงย่อยเดี่ยวได้เสมอ (เพราะมี K ≥ 3 ช่วง จัดช่วงอื่นๆ ไปได้) → คำตอบคือ max ของอาร์เรย์
ตัวอย่างโค้ด (แก้ไขจากต้นฉบับ)
#include <bits/stdc++.h>
using namespace std;
int maxOfMinOfKSubarrays(const vector<int>& arr, int K) {
int n = arr.size();
if (n == 0) return 0;
int minVal = *min_element(arr.begin(), arr.end());
int maxVal = *max_element(arr.begin(), arr.end());
if (K == 1) {
return minVal; // หรือ maxVal ตามการตีความโจทย์
} else if (K >= 3) {
return maxVal;
} else { // K == 2
vector<int> prefixMin(n), suffixMin(n);
prefixMin[0] = arr[0];
for (int i = 1; i < n; i++)
prefixMin[i] = min(prefixMin[i-1], arr[i]);
suffixMin[n-1] = arr[n-1];
for (int i = n-2; i >= 0; i--)
suffixMin[i] = min(suffixMin[i+1], arr[i]);
int ans = INT_MIN;
for (int i = 0; i < n-1; i++) {
ans = max(ans, max(prefixMin[i], suffixMin[i+1]));
}
return ans;
}
}
int main() {
vector<int> arr = {9, 4, 12, 5, 6, 11};
int K = 2;
cout << "Result: " << maxOfMinOfKSubarrays(arr, K) << endl;
return 0;
}
ผลลัพธ์
Result: 11
K=2: prefixMin={9,4,4,4,4,4}, suffixMin={4,4,5,5,6,11} → max ของ max(prefixMin[i], suffixMin[i+1]) = 11
สรุป Logic
| K | คำตอบ | เหตุผล |
|---|---|---|
| 1 | min(arr) | ช่วงเดียว = ทั้งอาร์เรย์ |
| 2 | max over splits of max(prefixMin, suffixMin) | ต้องลองจุดแบ่งทุกจุด |
| ≥3 | max(arr) | แยก max element ออกมาเป็นช่วงเดี่ยวได้ |