สมมติว่าเรามีอาร์เรย์ arr เราสามารถเลือกชุดของจำนวนเต็มและลบการเกิดของจำนวนเต็มเหล่านี้ทั้งหมดในอาร์เรย์ เราต้องหาขนาดต่ำสุดของชุดเพื่อลบจำนวนเต็มของอาร์เรย์อย่างน้อยครึ่งหนึ่ง ตัวอย่างเช่น ถ้า arr =[3,3,3,3,5,5,5,2,2,7] ผลลัพธ์จะเป็น 2 เนื่องจากถ้าเราเลือก {3,7} จะทำให้ อาร์เรย์ใหม่ [5,5,5,2,2] ซึ่งมีขนาด 5 (ซึ่งเท่ากับครึ่งหนึ่งของขนาดอาร์เรย์เก่า) ชุดที่เป็นไปได้ของขนาด 2 คือ {3,5},{3,2},{5,2} ไม่สามารถเลือกชุด {2,7} ได้ เนื่องจากจะทำให้อาร์เรย์ใหม่ [3,3,3,3,5,5,5] ซึ่งมีขนาดมากกว่าครึ่งหนึ่งของขนาดอาร์เรย์เก่า
เพื่อแก้ปัญหานี้ เราจะทำตามขั้นตอนเหล่านี้ -
-
กำหนดแผนที่ m, n :=ขนาดของ arr, เก็บความถี่ของแต่ละองค์ประกอบที่มีอยู่ใน arr ลงในแผนที่ m
-
กำหนดอาร์เรย์ที่เรียกว่า temp, sz :=n และ ret :=0
-
สำหรับแต่ละคีย์-ค่าจับคู่ในหน่วย m
-
ใส่ค่าของมันลงใน temp
-
-
จัดเรียงอาร์เรย์ชั่วคราว
-
สำหรับผมอยู่ในช่วง 0 ถึงขนาดของอุณหภูมิ
-
ถ้า sz <=n / 2 ให้แยกออกจากลูป
-
เพิ่มขึ้น 1
-
ลด sz โดย temp[i]
-
-
รีเทิร์น
ตัวอย่าง (C++)
ให้เราดูการใช้งานต่อไปนี้เพื่อความเข้าใจที่ดีขึ้น -
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
int minSetSize(vector<int>& arr) {
unordered_map <int, int> m;
int n = arr.size();
for(int i = 0; i < n; i++){
m[arr[i]]++;
}
vector <int> temp;
unordered_map <int, int> :: iterator it = m.begin();
int sz = n;
int ret = 0;
while(it != m.end()){
temp.push_back(it->second);
it++;
}
sort(temp.rbegin(), temp.rend());
for(int i = 0; i < temp.size(); i++){
if(sz <= n / 2)break;
ret++;
sz -= temp[i];
}
return ret;
}
};
main(){
vector<int> v = {3,3,3,3,5,5,5,2,2,7};
Solution ob;
cout << (ob.minSetSize(v));
} อินพุต
[3,3,3,3,5,5,5,2,2,7]
ผลลัพธ์
2