Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C++

Queue Reconstruction by Height ใน C++

โจทย์: 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

  1. เรียงลำดับคน: ส่วนสูง มากไปน้อย** หากส่วนสูงเท่ากัน k น้อยไปมาก
    • เหตุผล: คนสูงกว่าไม่ได้รับผลกระทบจากคนต่ำกว่า จึงวางคนสูงก่อน
  2. สร้างลิสต์ว่าง ans
  3. วนคนตามลำดับที่เรียงแล้ว (จากสูงสุดไปต่ำสุด):
    • แทรกคนคนนั้นที่ index k ใน ans (ans.insert(ans.begin() + k, person))
    • เพราะคนที่วางไว้ก่อนหน้านี้ สูงกว่าหรือเท่ากันหมดแล้ว การแทรกที่ index k จะทำให้มีคนสูง/เท่าอยู่หน้าพอดี k คน

ตัวอย่างโค้ด 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 ดีกว่า