LeetCode 🟡 3737. Count Subarrays With Majority Element I
🔗 🟡 3737. Count Subarrays With Majority Element I
Problem Statement
題目簡述
給定整數陣列 nums 和整數 target,請計算有多少個非空子陣列滿足:target 在該子陣列中出現的次數嚴格大於子陣列長度的一半,也就是 target 是這個子陣列的多數元素。
Constraints
約束條件
思路:前綴和枚舉子陣列
本題的筆記中僅展示 的解法,其餘複雜度更優的寫法請見 LeetCode 🔴 3739. Count Subarrays With Majority Element II 此篇筆記。
如果直接枚舉子陣列的所有左右端點 ,再逐段統計 target 出現次數,會多出一層掃描,整體為 ,以本題的數據範圍來說是不接受的,因此需要可以考慮能不能把「某段裡 target 是否為多數元素」變成 判定。
等價轉換
對一個子陣列,設 target 的出現次數為 ,其餘元素的出現次數為 。題目要求 target 出現次數嚴格超過子陣列長度的一半,也就是:
移項後,條件等價於:
因此可以把子陣列中的每個元素做如下轉換:
- 等於
target的位置記為 - 不等於
target的位置記為
那麼一段子陣列的轉換後總和,正好就是:
所以問題變成:計算有多少個子陣列的轉換後區間和大於 。
Tip
遇到「某元素出現次數是否超過一半」時,可以嘗試把目標元素變成 ,其他元素變成 。這樣「多數」條件就會變成「區間和是否為正」。
用前綴和做到快速判定
有了上述轉換後,只要建立轉換陣列的前綴和,就能在 時間求出任意子陣列的總和。
不妨設轉換後的陣列為 ,其中:
定義前綴和:
對於子陣列 ,如果前綴和差值滿足:
就表示這段子陣列的 ,也就是 target 是多數元素。
條件必須是嚴格大於 ,不是大於等於 。如果區間和等於 ,只代表
target 和非 target 的數量一樣多,並沒有嚴格超過一半。因此只要枚舉所有子陣列,用前綴和差值判斷是否滿足題意即可。這樣就能把原本 的解法,降到 。
複雜度分析
- 時間複雜度:,需要枚舉所有子陣列。
- 空間複雜度:,需要儲存轉換後的前綴和。
Code
1 | class Solution: |
本部落格所有文章除特別聲明外,均採用CC BY-NC-SA 4.0 授權協議。轉載請註明來源 十六個天亮!
評論
WalineGiscus





