โจทย์: Queue Reconstruction by Height
มีคนยืนคิวสุ่ม แต่ละคนมีคู่ (h, k) โดย:
h= ส่วนสูงk= จำนวนคนที่อยู่ หน้าคนนี้** และมีส่วนสูง >= h
ต้องสร้างคิวใหม่ที่สอดคล้องกับเงื่อนไขทั้งหมด
ตัวอย่าง: [[7,0], [4,4], [7,1], [5,0], [6,1], [5,2]]
ผลลัพธ์: [[5,0], [7,0], [5,2], [6,1], [4,4], [7,1]]
อัลกอริทึม: Greedy + Insertion
- เรียงลำดับคน: ส่วนสูง มากไปน้อย** หากส่วนสูงเท่ากัน
kน้อยไปมาก - เหตุผล: คนสูงกว่าไม่ได้รับผลกระทบจากคนต่ำกว่า จึงวางคนสูงก่อน
- สร้างลิสต์ว่าง
ans - วนคนตามลำดับที่เรียงแล้ว (จากสูงสุดไปต่ำสุด):
- แทรกคนคนนั้นที่ index
kในans(ans.insert(ans.begin() + k, person)) - เพราะคนที่วางไว้ก่อนหน้านี้ สูงกว่าหรือเท่ากันหมดแล้ว การแทรกที่ index k จะทำให้มีคนสูง/เท่าอยู่หน้าพอดี k คน
- แทรกคนคนนั้นที่ index
ตัวอย่างโค้ด C++
#include <bits/stdc++.h>
using namespace std;
void print_queue(vector<vector<int>> v) {
cout << "[";
for (int i = 0; i < v.size(); i++) {
cout << "[";
for (int j = 0; j < v[i].size(); j++) {
cout << v[i][j];
if (j + 1 < v[i].size()) cout << ", ";
}
cout << "]";
if (i + 1 < v.size()) cout << ", ";
}
cout << "]" << endl;
}
class Solution {
public:
static bool cmp(const vector<int>& a, const vector<int>& b) {
if (a[0] == b[0]) return a[1] < b[1]; // สูงเท่ากัน: k น้อยกว่าก่อน
return a[0] > b[0]; // สูงกว่าก่อน
}
vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {
sort(people.begin(), people.end(), cmp);
vector<vector<int>> ans;
for (auto& p : people) {
ans.insert(ans.begin() + p[1], p);
}
return ans;
}
};
int main() {
Solution ob;
vector<vector<int>> v = {{7,0}, {4,4}, {7,1}, {5,0}, {6,1}, {5,2}};
print_queue(ob.reconstructQueue(v));
return 0;
}
Input
[[7,0], [4,4], [7,1], [5,0], [6,1], [5,2]]
Output
[[5,0], [7,0], [5,2], [6,1], [4,4], [7,1]]
ความซับซ้อน (Complexity)
- เวลา: O(n²) - sort O(n log n) + n ครั้ง insert ที่ O(n) ต่อครั้ง (vector shift)
- พื้นที่: O(n) สำหรับผลลัพธ์
Optimization: ใช้ list<vector<int>> แทน vector สำหรับ ans จะได้ insert O(1) แต่ต้องใช้ advance(iterator, k) ซึ่งก็ O(k) รวม O(n²) เหมือนกัน แต่ constant factor ดีกว่า