📘 題目敘述
給你一個整數陣列 nums。
請回傳一個整數,表示 nums 中從左到右掃描時,第一個出現且其出現次數是唯一的元素。
所謂「出現次數是唯一」指的是:沒有任何其他整數在 nums 中出現的次數和它一樣。若不存在,回傳 -1。
條件限制
1 <= nums.length <= 10^51 <= nums[i] <= 10^5
🧠 解題思路
題目要的是「第一個(從左到右)」而且要滿足「它的頻率沒有別人一樣」。
所以我分成三步:先統計每個數出現幾次 a[x],再統計某個頻率有幾個數擁有(time[f]),最後再按原陣列順序掃回去,找第一個 time[a[j]] == 1 的元素。
這樣可以同時保證頻率唯一與最先出現,而且整體是線性流程。
所有變數
a:a[x]表示數字x在nums中出現的次數time:time[f]表示頻率等於f的不同數字有幾個
🪜 主要流程步驟
1. 先統計每個數字出現次數 a[]
建立 a[100001] 初始為 0,掃過 nums,遇到 i 就做 a[i]++。
2. 再統計每種頻率有幾個數字擁有 time[]
建立 time[100001] 初始為 0,掃 i = 1..100000,若 a[i] > 0 則做 time[a[i]]++。
3. 從左到右找第一個頻率唯一的元素
再掃一次原本順序的 nums。對每個 j,若 time[a[j]] == 1,直接回傳 j。
4. 找不到就回傳 -1
如果整個陣列都掃完還沒有符合條件的元素,答案就是 -1。
⏱️ 複雜度
- 時間複雜度:
O(n + U),其中U = 100000。 - 空間複雜度:
O(U),使用兩個大小 100001 的陣列。
💻 程式碼實作
class Solution {
public:
int firstUniqueFreq(vector<int>& nums) {
int a[100001] = {0};
int time[100001] = {0};
for (int i : nums) {
a[i]++;
}
for (int i = 1; i < 100001; i++) {
if (a[i] > 0) {
time[a[i]]++;
}
}
for (int j : nums) {
if (time[a[j]] == 1) {
return j;
}
}
return -1;
}
};
🔗 題目連結
https://leetcode.com/contest/weekly-contest-489/problems/first-element-with-unique-frequency/