C++算法實現(xiàn)leetcode 1252奇數(shù)值單元格數(shù)目
題目描述
題目鏈接:1252. 奇數(shù)值單元格的數(shù)目
給你一個 m x n 的矩陣,最開始的時候,每個單元格中的值都是 0。
另有一個二維索引數(shù)組 indices,indices[i] = [ri, ci] 指向矩陣中的某個位置,其中 ri 和 ci 分別表示指定的行和列(從 0 開始編號)。
對 indices[i] 所指向的每個位置,應(yīng)同時執(zhí)行下述增量操作:
- ri 行上的所有單元格,加 1 。
- ci 列上的所有單元格,加 1 。 給你 m、n 和 indices 。請你在執(zhí)行完所有 indices 指定的增量操作后,返回矩陣中 奇數(shù)值單元格 的數(shù)目。
進階: 你可以設(shè)計一個時間復(fù)雜度為 O(n + m + indices.length) 且僅用 O(n + m) 額外空間的算法來解決此問題嗎?
提示:
1 <= m, n <= 50
1 <= indices.length <= 100
0 <= ri < m
0 <= ci < n
示例 1:
輸入:m = 2, n = 3, indices = [[0,1],[1,1]]
輸出:6
解釋:最開始的矩陣是 [[0,0,0],[0,0,0]]。
第一次增量操作后得到 [[1,2,1],[0,1,0]]。
最后的矩陣是 [[1,3,1],[1,3,1]],里面有 6 個奇數(shù)。
示例 2:
輸入: m = 2, n = 2, indices = [[1,1],[0,0]]
輸出: 0
解釋: 最后的矩陣是 [[2,2],[2,2]],里面沒有奇數(shù)。
整理題意
題目給定一個 m x n 的矩陣,矩陣中每個元素最開始都為 0,然后給定一個二維數(shù)組 indices,數(shù)組中每個元素包含兩個值 indices[i][0] 和 indices[i][1],分別表示對 m x n 的矩陣的第 indices[i][0] 行和第 indices[i][1] 列進行加一操作。
在執(zhí)行完所有 indices 指定的增量操作后,返回矩陣中 奇數(shù)值單元格 的數(shù)目。
需要注意行和列重疊的地方是累計加的
解題思路分析
觀察題目數(shù)據(jù)范圍較小,采用較為暴力的模擬也是可以通過的,但是我們這里按照進階的標準來進行解題,時間復(fù)雜度為 O(n + m + indices.length) 且僅用 O(n + m) 額外空間的算法來解決此問題。
考慮到對于每一行和每一列來說,如果在 indices 中出現(xiàn)偶數(shù)次那么就相當于沒有出現(xiàn),所以我們可以統(tǒng)計在 indices 中行和列出現(xiàn)奇數(shù)的次數(shù),這里令統(tǒng)計好的行和列分別記為:
- 出現(xiàn)奇數(shù)次行的總和為 sumr
- 出現(xiàn)奇數(shù)次列的總和為 sumc 那么可以通過數(shù)學計算的方式來得出最后執(zhí)行完所有 indices 指定的增量操作后,返回矩陣中 奇數(shù)值單元格 的數(shù)目。
- 因為對于統(tǒng)計出來出現(xiàn)奇數(shù)次的行和列來說,他們相交的部分為偶數(shù)次,所以只需要減去相交部分的單元格數(shù)量即可,那么最后答案就是 sumr * n + sumc * m - sumr * sumc * 2
為什么要 * 2:是因為在 sumr * n 和 sumc * m 的時候分別加了一次相交的部分,總共就是加了兩次,所以需要 * 2
具體實現(xiàn)
- 在統(tǒng)計 indices 中進行和列出現(xiàn)是否為奇數(shù)次時,我們可以使用兩個一維數(shù)組進行統(tǒng)計 sr[m] 和 sc[n],分別表示行和列出現(xiàn)的次數(shù)。
- 因為我們只需統(tǒng)計出現(xiàn)奇數(shù)次的行和列,那么我們可以采用異或 ^ 運算進行優(yōu)化。
- 最后統(tǒng)計行和列出現(xiàn)奇數(shù)次的個數(shù)即可。
復(fù)雜度分析
- 時間復(fù)雜度:O(n + m + indices.length),n 和 m 分別為矩陣的長和寬,indices.length 為數(shù)組 indices 的長度。
- 空間復(fù)雜度:O(n + m),僅需用于保存行和列的一維數(shù)組。
代碼實現(xiàn)
class Solution { public: int oddCells(int m, int n, vector<vector<int>>& indices) { //統(tǒng)計被加上奇數(shù)次的行和列 int sr[m], sc[n]; memset(sr, 0, sizeof(sr)); memset(sc, 0, sizeof(sc)); int sumr, sumc; sumr = sumc = 0; for(auto &v : indices){ //如果為偶數(shù)次就是 0,奇數(shù)次為 1,用異或來變化0和1 sr[v[0]] ^= 1; //統(tǒng)計奇數(shù)次的行 if(sr[v[0]]) sumr++; else sumr--; sc[v[1]] ^= 1; //統(tǒng)計奇數(shù)次的列 if(sc[v[1]]) sumc++; else sumc--; } //奇數(shù)次行個數(shù)加上奇數(shù)次列個數(shù),減去相交為偶數(shù)次的點,因為加了兩遍所以要 *2 int ans = sumr * n + sumc * m - sumr * sumc * 2; return ans; } };
總結(jié)
- 該題難點在于如何優(yōu)化時間復(fù)雜度為 O(n + m + indices.length) 且僅用 O(n + m) 額外空間的算法來解決此問題。
- 通過統(tǒng)計行和列出現(xiàn)的次數(shù)便能進一步實現(xiàn)優(yōu)化。核心思想在于計數(shù)。
測試結(jié)果:
以上就是C++實現(xiàn)leetcode 1252奇數(shù)值單元格的數(shù)目題解的詳細內(nèi)容,更多關(guān)于C++奇數(shù)值單元格的數(shù)目的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Matlab利用隨機森林(RF)算法實現(xiàn)回歸預(yù)測詳解
這篇文章主要為大家詳細介紹了Matlab如何利用隨機森林(RF)算法實現(xiàn)回歸預(yù)測,以及自變量重要性排序的操作,感興趣的小伙伴可以了解一下2023-02-02Objective-C中使用STL標準庫Queue隊列的方法詳解
這篇文章主要介紹了Objective-C中使用STL標準庫Queue隊列的方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧2024-01-01