本思路需找到最高點左右遍歷,時間複雜度O(nlogn),如下爲向左遍歷的過程。python
def mcmp(a, b): val1,idx1 = a val2,idx2 = b if val1 == val2: return idx2-idx1 return val1-val2 from functools import cmp_to_key l = [] # l中存元組(val, idx) l.sort(reverse=True, key=cmp_to_key(Solution.mcmp))
代碼以下app
class Solution: # 利用functools中的cmp_to_key重載排序: def mcmp(a, b): val1,idx1 = a val2,idx2 = b if val1 == val2: return idx2-idx1 return val1-val2 def trap(self, height: List[int]) -> int: if len(height) == 0: return 0 from functools import cmp_to_key l = [] # 將(val, idx)存入l = []中 for i in range(0, len(height)): l.append((height[i],i)) ans = 0 # 往左找 l.sort(reverse=True) h, con = l[0] for i in range(1, len(l)): val, left = l[i] if left < con: for j in range(left+1, con): ans += val - height[j] con = left # 往右找 h, con = l[0] l.sort(reverse=True, key=cmp_to_key(Solution.mcmp)) for i in range(1, len(l)): val, right = l[i] if right > con: for j in range(con+1, right): ans += val - height[j] con = right return ans
本思路與Python相似,需找到最高點左右遍歷,時間複雜度O(nlogn)如下爲向左遍歷的過程。差異在於C++是存map,無須手動排序。code
// m中first存高度val,second存索引集合。 // set<int> s = m[2]表示高度爲2的點的位置集合。 map<int, set<int>> m;
實現代碼以下:排序
class Solution { public: int trap(vector<int>& height) { if(height.size() == 0) return 0; int ans = 0; // m中first存高度val,second存索引集合。 // set<int> s = m[2]表示高度爲2的點的位置集合。 map<int, set<int>> m; // itm表示m的一個迭代器 map<int, set<int>>::iterator itm; set<int> s; set<int>::iterator its; //將(val, idx)存入map int sz = height.size(); for(int i = 0;i < sz; ++i){ m[height[i]].insert(i); } //向左找 itm = --m.end(); s = itm->second; int h = itm->first; int left = *s.begin(); //每次找val小,idx小的 while(left != -1 && left >= 0){ s = m[h]; its = s.lower_bound(left); if(its == s.begin()){ if(itm == m.begin()){ left = -1; }else{ --itm; h = itm->first; } }else{ --its; for(int i = *its+1;i < left; ++i){ ans += h-height[i]; } left = *its; continue; } } //向右找 itm = --m.end(); s = itm->second; h = itm->first; int right = *s.begin(); //每次找val小,idx大的 while(right != -1 && right < sz){ s = m[h]; its = s.upper_bound(right); if(its == s.end()){ if(itm == m.begin()){ right = -1; }else{ --itm; h = itm->first; } }else{ for(int i = right+1;i < *its; ++i){ ans += h-height[i]; } right = *its; continue; } } return ans; } };