sort(nums.begin(), nums.end());
預設排序為升序排列。
適用於 vector、array、deque 等隨機訪問容器。
時間複雜度:
演算法原理:
C++ STL sort() 採用 Introsort(混合演算法)
平均情況下用 QuickSort。
遇到遞迴過深時改用 HeapSort,避免最壞退化。
小區間時會切換 InsertionSort 提高效能。
sort(nums.begin()+1, nums.end()-1);
僅排序部分資料,例如只排序索引 [1, n-2] 的元素。
bool cmp(int a, int b) {
return a > b; // 降序排列,元素會由大到小
}
sort(nums.begin(), nums.end(), cmp);
sort(nums.begin(), nums.end(),
[](int a, int b) {
return a > b; // 降序
});
lambda 優點:
例如,排序一個區間陣列 vector<pair<int,int>>
,
按照「起點升序,若起點相同則依終點升序」:
sort(intervals.begin(), intervals.end(),
[](const pair<int,int>& a, const pair<int,int>& b) {
if (a.first == b.first) return a.second < b.second;
else return a.first < b.first;
});
原題:
https://cses.fi/problemset/task/1083
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
vector<int> nums(n-1);
for (int i = 0; i < n-1; i++) cin >> nums[i];
sort(nums.begin(), nums.end());
for (int i = 0; i < n-1; i++) {
if (nums[i] != i+1) {
cout << i+1 << endl;
return 0;
}
}
cout << n << endl;
return 0;
}
利用數列和公式:
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
long long total = 1LL * n * (n+1) / 2;
long long sum = 0;
for (int i = 0; i < n-1; i++) {
int x;
cin >> x;
sum += x;
}
cout << total-sum << endl;
return 0;
}
原理:
如果我們 XOR 所有 1∼n 的數字,再XOR輸入的所有數字,最後結果就是缺少的數。
#include <bits/stdc++.h>
using namespace std;
int main() {
int n;
cin >> n;
int x = 0;
for (int i = 1; i <= n; i++) x ^= i;
for (int i = 0; i < n-1; i++) {
int val;
cin >> val;
x ^= val;
}
cout << x << endl;
return 0;
}
三種解法總整理:
解法 | 思路 | 時間複雜度 | 空間複雜度 |
---|---|---|---|
排序 | sort + 遍歷 |
O(n log n) | O(1) |
數學公式 | 總和減去現有總和 | O(n) | O(1) |
XOR | XOR 運算 | O(n) | O(1) |
原題:
https://cses.fi/problemset/task/1084
題意:
有 n 個申請者想租房子,每個人有期望房間大小。
有 m 間房子,每間房子有實際大小。
給一個容忍度 k:若房子大小與期望差距 ≤ k,則可匹配。
問最多可以成功匹配多少人。
思路:
#include<bits/stdc++.h>
using namespace std;
int main(){
int n,m,k; //申請者、空公寓、申請者理想大小可接受的最大差距
cin>>n>>m>>k;
vector<long long> people(n);
vector<long long> apartment(m);
for(int i=0;i<n;i++) cin>>people[i];
for(int i=0;i<m;i++) cin>>apartment[i];
int ans=0,j=0; //j:指向哪一個apartment
sort(people.begin(),people.end());
sort(apartment.begin(),apartment.end());
for(int i=0;i<n;i++){
while(j<m and apartment[j]<people[i]-k){
++j;
}
if (j<m && apartment[j]<=people[i]+k){
ans++;
++j; // 這間公寓被用掉,指到下一間
}
}
cout<<ans<<endl;
return 0;
}
原題:
https://leetcode.com/problems/merge-intervals/description/
題意:
給定一個區間陣列 intervals,將所有重疊的區間合併,並回傳結果。
思路:
class Solution {
public:
vector<vector<int>> merge(vector<vector<int>>& intervals) {
// 依照起點升序排序
sort(intervals.begin(), intervals.end());
vector<vector<int>> result;
result.push_back(intervals[0]);
for (int i = 1; i<intervals.size(); i++) {
if (intervals[i][0] <= result.back()[1]) {
// 有重疊 → 更新結束點
result.back()[1] = max(result.back()[1], intervals[i][1]);
} else {
// 沒有重疊 → 直接加入
result.push_back(intervals[i]);
}
}
return result;
}
};
原題:
https://leetcode.com/problems/non-overlapping-intervals/description/
題意:
給定一組區間,找出最少刪除多少區間,使剩下的區間互不重疊。
思路:
class Solution {
public:
int eraseOverlapIntervals(vector<vector<int>>& intervals) {
sort(intervals.begin(), intervals.end(),
[](const vector<int>& a, const vector<int>& b) {
return a[1] < b[1]; // 按照結束時間排序
});
int count = 0;
int prevEnd = intervals[0][1];
for (int i = 1; i < intervals.size(); i++) {
if (intervals[i][0] < prevEnd) {
// 與前一個區間重疊 → 刪除當前區間
count++;
} else {
// 無重疊 → 更新 prevEnd
prevEnd = intervals[i][1];
}
}
return count;
}
};
題目 | 類型 | 技巧 | 時間複雜度 |
---|---|---|---|
CSES Missing Number | 找缺失數字 | 排序 / 總和公式 / XOR | O(n log n) / O(n) |
CSES Apartments | 雙指針匹配 | 排序 + 雙指針 | O(n log n + m log m) |
LeetCode Merge Intervals | 區間合併 | 排序 + 動態合併 | O(n log n) |
LeetCode Non-overlapping Intervals | 最少刪除區間 | 排序 + 貪心 | O(n log n) |