classSolution: defcountCompleteDayPairs(self, hours: List[int]) -> int: n = len(hours) ans = 0 for i inrange(n): for j inrange(i+1, n): if (hours[i] + hours[j]) % 24 == 0: ans += 1 return ans
1 2 3 4 5 6 7 8 9 10 11
classSolution { public: intcountCompleteDayPairs(vector<int>& hours){ int n = hours.size(), ans = 0; for (int i = 0; i < n; i++) for (int j = i+1; j < n; j++) if ((hours[i] + hours[j]) % 24 == 0) ans++; return ans; } };
如果 x 不為 0,則將 cnt[24−x] 加到答案 ans 上(因為 hours[i]+hours[j]=24 時,i 和 j 就是一對);如果 x 為 0,則將 cnt[0] 加到答案 ans 上。
或是做二次取模,將 cnt[(24−x)mod24] 加到答案 ans 上。
將 cnt[x] 加 1,更新計數。
最後返回答案 ans。
複雜度分析
時間複雜度:O(n) ,其中 n 為陣列的長度。
空間複雜度:O(24)=O(1) 。
1 2 3 4 5 6 7 8 9 10
classSolution: defcountCompleteDayPairs(self, hours: List[int]) -> int: ans = 0 cnt = [0] * 24 for x in hours: x %= 24 # ans += cnt[24 - x] if x != 0 else cnt[0] # 特判 ans += cnt[(24 - x) % 24] # 二次取模 cnt[x] += 1 return ans
1 2 3 4 5 6 7 8 9 10 11 12 13 14
classSolution { public: longlongcountCompleteDayPairs(vector<int>& hours){ longlong ans = 0; vector<int> cnt(24, 0); for (int x : hours) { x %= 24; // ans += (x != 0) ? cnt[24 - x] : cnt[0]; ans += cnt[(24 - x) % 24]; cnt[x]++; } return ans; } };
def__init__(self, nums: List[int]): # 下標從 1 開始 n = len(nums) self.nums = nums tree = [0] * (n + 1) # 下標從 1 開始 for i, x inenumerate(nums, 1): # initialization: O(n) tree[i] += x nxt = i + (i & -i) # 下一個關鍵區間的右端點 if nxt <= n: tree[nxt] += tree[i] self.tree = tree
defadd(self, k: int, x: int) -> None: # 令 nums[k] += x k += 1 while k < len(self.tree): self.tree[k] += x k += (k & -k)
defupdate(self, k: int, x: int) -> None: # 令 nums[k] = x self.add(k, x - self.nums[k]) self.nums[k] = x
defsum(self, l: int, r: int) -> int: # 區間查詢 (區間求和): 求 nums[l] 到 nums[r] 之和 if l > r: # 本題中會出現 l > r 的情況 return0 return self.preSum(r+1) - self.preSum(l)
defpreSum(self, k: int) -> int: # 求前綴和: 求 nums[0] 到 nums[k] 的區間和 s = 0 while k > 0: s += self.tree[k] k &= k - 1# 等同 k -= (k & -k) return s classSolution: defcountOfPeaks(self, nums: List[int], queries: List[List[int]]) -> List[int]: n = len(nums) # peaks[i] = 1 if nums[i-1] < nums[i] > nums[i+1] peaks = [0] + [1if nums[i-1] < nums[i] > nums[i+1] else0for i inrange(1, n-1)] + [0] bit = FenwickTree(peaks) ans = [] for op, *args in queries: if op == 1: l, r = args ans.append(bit.sum(l+1, r-1)) # 不包含頭尾 else: idx, val = args nums[idx] = val for i inrange(idx-1, idx+2): # 更新 idx-1, idx, idx+1 三個位置 if i <= 0or i >= n-1: continue if nums[i-1] < nums[i] > nums[i+1]: # 現在是峰值 if bit.nums[i] == 0: # 之前不是峰值 bit.update(i, 1) else: # 現在不是峰值 if bit.nums[i] == 1: # 之前是峰值 bit.update(i, 0) return ans
classSegmentTree { private: vector<int> nums; vector<int> tree; public: SegmentTree(vector<int>& nums) { int n = nums.size(); this->nums = vector<int>(n + 1, 0); for (int i = 1; i <= n; i++) this->nums[i] = nums[i - 1]; // 1-indexed this->tree = vector<int>(4 * n, 0); build(1, 1, n); }
voidbuild(int o, int left, int right){ if (left == right) { tree[o] = 0; return; } int mid = (left + right) / 2; build(2 * o, left, mid); build(2 * o + 1, mid + 1, right); tree[o] = merge(tree[2 * o], tree[2 * o + 1], left, mid, right); }
intmerge(int l, int r, int left, int mid, int right){ int res = l + r; if (mid - 1 >= left && nums[mid-1] < nums[mid] && nums[mid] > nums[mid+1] || mid + 2 <= right && nums[mid] < nums[mid+1] && nums[mid+1] > nums[mid+2]) res += 1; return res; }
voidupdate(int o, int left, int right, int idx, int val){ if (left == right) { nums[idx] = val; tree[o] = 0; return; } int mid = (left + right) / 2; if (idx <= mid) update(2 * o, left, mid, idx, val); elseupdate(2 * o + 1, mid + 1, right, idx, val); tree[o] = merge(tree[2 * o], tree[2 * o + 1], left, mid, right); }
intquery(int o, int left, int right, int l, int r){ if (left == l && r == right) return tree[o]; int mid = (left + right) / 2; if (r <= mid) returnquery(2 * o, left, mid, l, r); // 只需要查詢左半部分 if (mid < l) returnquery(2 * o + 1, mid + 1, right, l, r); // 只需要查詢右半部分 int left_part = query(2 * o, left, mid, l, mid); // 左半部分 int right_part = query(2 * o + 1, mid + 1, right, mid + 1, r); // 右半部分 returnmerge(left_part, right_part, l, mid, r); // 合併左右兩部分 } };
classSolution { public: vector<int> countOfPeaks(vector<int>& nums, vector<vector<int>>& queries){ int n = nums.size(); SegmentTree seg(nums); vector<int> ans; for (auto& q : queries) { if (q[0] == 1) { int l = q[1], r = q[2]; ans.push_back(seg.query(1, 1, n, l+1, r+1)); } else { int idx = q[1], val = q[2]; seg.update(1, 1, n, idx+1, val); } } return ans; } };
Cover photo is generated by @自由的风, thanks for their work!
I did not find any copyright declaration on the author’s personal page regarding permission or prohibition of use. Because of this, I used Pixiv.Cat to proxy the cover image. I actually do not save that image.
If the content of the article infringes on your copyright, please contact me through email or leave a comment to let me know, and I will promptly remove the relevant content.