classSolution: defheightChecker(self, heights: List[int]) -> int: expected = sorted(heights) ans = 0 for x, y inzip(heights, expected): ans += (x != y) return ans
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
classSolution { public: intheightChecker(vector<int>& heights){ int n = heights.size(); vector<int> expected = heights; sort(expected.begin(), expected.end()); int ans = 0; for (int i = 0; i < n; i++) { if (heights[i] != expected[i]) { ans++; } } return ans; } };
對於值域中的每個數字 x ,我們只要統計 heights 陣列中值小於 x 的數字個數 s ,就可以得到 x 在排序後的陣列中的位置。在排序後的陣列中,expected[s],expected[s+1],…,expected[s+cnt[x]−1] 這些位置上的元素都應該等於 x 。而計算 s 的過程可以使用 前綴和(Prefix Sum) 來實現。
具體步驟如下:
創建一個大小為 101 的計數陣列 cnt,初始化為 0,cnt[i] 表示身高為 i 的學生數量。
遍歷 heights 陣列,對每個學生的身高進行計數。
使用 s 變量作為前綴和的起始位置,初始化為 0。
遍歷 cnt 陣列,檢查 cnt[i] 的值,對於每個 i,遍歷 s 到 s+cnt[i]−1 的位置,檢查 heights 陣列中相應位置的值是否和預期的身高 i 一致。如果不一致,將 ans 加 1。
將前綴和變量 s 更新為當前處理身高的結束位置,準備處理下一個身高。
返回 ans。
複雜度分析
時間複雜度:O(D),其中 D 表示值域的大小,本題中 D=101。
空間複雜度:O(D),cnt 陣列的大小與值域大小相同。
1 2 3 4 5 6 7 8 9 10 11 12 13
classSolution: defheightChecker(self, heights: List[int]) -> int: cnt = [0] * 101 for x in heights: cnt[x] += 1 s = 0# prefix sum ans = 0 for i inrange(101): for j inrange(s, s + cnt[i]): if heights[j] != i: ans += 1 s += cnt[i] return ans
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
classSolution { public: intheightChecker(vector<int>& heights){ int n = heights.size(); vector<int> cnt(101, 0); for (int x : heights) cnt[x]++; int ans = 0, s = 0; for (int i = 0; i < 101; i++) { for (int j = 0; j < cnt[i]; j++) { if (heights[s++] != i) ans++; } } return ans; } };
寫在最後
Cover photo is generated by @たろたろ, thanks for their work!