參考資料來源靈神在力扣所發的題單,僅供分享學習筆記和記錄,無商業用途。
核心思路:參考枚舉中間位置基礎篇-CSDN博客
力扣題單練習(靈神題單中摘取題目)
447. 回旋鏢的數量
核心思路:
因給出的點都不相同,所以不會出現枚舉到當前點的次數會>=2的情況,枚舉每一個點對當前點的距離,從而得出有多少個點到當前點距離一致。
若有 m 個點到點 i 的距離都相同,那么能夠組成的回旋鏢數量就是 m * (m - 1)。這是因為從 m 個點里選 2 個點進行排列,排列數為 A(m, 2) = m * (m - 1)。
計算從m個點中選2個點進行排列動態(邊統計數量)計算:ret+=map[buff]++*2;
class Solution {
public:int numberOfBoomerangs(vector<vector<int>>& points) {//核心思路:因給出的點都不相同,所以不會出現枚舉到當前點的次數會>=2的情況,枚舉每一個點對當前點的距離,從而得出有多少個點到當前點距離一致。//若有 m 個點到點 i 的距離都相同,那么能夠組成的回旋鏢數量就是 m * (m - 1)。這是因為從 m 個點里選 2 個點進行排列,排列數為 A(m, 2) = m * (m - 1)。int ret=0;unordered_map<int,int> map;for(auto& x:points){int buff=0;for(auto& y:points){buff=(x[0]-y[0])*(x[0]-y[0])+(x[1]-y[1])*(x[1]-y[1]);//采用的是動態計算的方式,在每次發現新點時,就把新增的組合數量累加到 ret 中。這樣一來,當統計完所有點之后,ret 中存儲的就是最終的結果。ret+=map[buff]++*2;}map.clear();}return ret;}
};
456. 132 模式
核心思路:
枚舉中間位置 j,尋找左側最小值與右側次小值。采用自底向上單調遞減棧維護右側,保證滿足棧頂大于左側最小值的同時并且嘗試滿足小于當前元素
class Solution {
public:bool find132pattern(vector<int>& nums) {//核心思路:枚舉中間位置 j,尋找左側最小值與右側次小值。采用自底向上單調遞減棧維護右側,保證滿足棧頂大于左側最小值的同時并且嘗試滿足小于當前元素int n=nums.size();if(n<3) return false;vector<int> left_min(n);left_min[0]=INT_MAX;//維護當前下標前面區間的最小值for(int i=1;i<n;i++) left_min[i]=min(left_min[i-1],nums[i-1]);stack<int> s; //存放可能滿足條件的nums[k],維護自底向上遞減棧,j實際上就是a[k]左側第一個嚴格大于a[k]的元素下標for(int i=n-1;i>=1;i--){int current=nums[i]; //當前元素int buff=left_min[i]; //左側區間最小值if(buff>=current) continue; //當前位置元素不合法while(!s.empty() && s.top()<=buff) s.pop(); //保證nums[k]>nums[i]if(!s.empty() && s.top()<current) return true; //棧頂元素為可能滿足條件的最小元素,如果存在棧頂元素<nums[j]則存在132模式s.push(current);}return false;}
};
3067. 在帶權樹網絡中統計可連接服務器對數目
題意:
給定一個雙向路徑帶權節點數組,要求找到一個節點有至少2條不同的路徑并且到路徑上的節點的權重可以被signalSpeed整除,統計有多少對滿足條件的服務器對組合。
核心思路:
根據給定數組構建路徑圖,枚舉每一個節點,保證有至少兩條不同路徑。深搜找滿足條件的數量,然后進行局部計算組合數量最終得到全部滿足條件的組合數量
乘法原理:累加使用過的節點數*當前新統計節點,然后更新使用過的節點數
class Solution {
public://深搜:查找根元素到當前元素的權重可以被signalSpeed整除的節點數量int dfs(vector<vector<pair<int,int>>>& f, int x, int i, int sum, int signalSpeed){int cnt=sum%signalSpeed==0;for(auto &[y,w]:f[x]){if(y!=i) cnt+=dfs(f,y,x,sum+w,signalSpeed);}return cnt;}vector<int> countPairsOfConnectableServers(vector<vector<int>>& edges, int signalSpeed) {//題意:給定一個雙向路徑帶權節點數組,要求找到一個節點有至少2條不同的路徑并且到路徑上的節點的權重可以被signalSpeed整除,統計有多少對滿足條件的服務器對組合。//核心思路:根據給定數組構建路徑圖,枚舉每一個節點,保證有至少兩條不同路徑。深搜找滿足條件的數量,然后進行局部計算組合數量最終得到全部滿足條件的組合數量int n=edges.size()+1;vector<vector<pair<int,int>>> f(n+1);//建立路徑圖for(auto &k:edges){int x=k[0],y=k[1],w=k[2];f[x].push_back({y,w});f[y].push_back({x,w});}vector<int> ret(n);for(int i=0;i<=n;i++){if(f[i].size()<=1) continue;int cnt=0;for(auto &[x,w]:f[i]){int buff=dfs(f,x,i,w,signalSpeed);ret[i]+=buff*cnt; //用前面統計過局部答案的節點數*新滿足條件的節點數獲得當前局部答案。保證了最后能算出總組合數cnt+=buff; //前面統計過組合的節點數} }return ret;}
};
靈神枚舉中間題單2000分以下題目以完成,后續會更新2000+題目的題解