数组的遍历:414
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #include <set> class Solution {public : int thirdMax (vector<int >& nums) { set<int >s; for (int num:nums){ s.insert (num); if (s.size ()>3 ){ s.erase (s.begin ()); } } return s.size ()==3 ?*s.begin ():*s.rbegin (); } };
统计数组中的元素:645(哈希表解法)。关键思想:原地哈希
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #include <map> #include <vector> class Solution {public : vector<int > findErrorNums (vector<int >& nums) { vector<int >res (2 ); unordered_map<int ,int >mp; for (auto & num:nums){ mp[num]++; } for (int i=1 ;i<=nums.size ();i++){ int count=mp[i]; if (count==2 ){ res[0 ]=i; } else if (count==0 ){ res[1 ]=i; } } return res; } };
难题:41
二分搜索:274
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 class Solution {public : int hIndex (vector<int >& citations) { int left = 0 , right = citations.size (); int mid = 0 , count = 0 ; while (left < right) { mid = (left + right + 1 ) / 2 ; count = 0 ; for (int i = 0 ; i < citations.size (); i++) { if (citations[i] >= mid) { count++; } } if (count >= mid) { left = mid; } else { right = mid - 1 ; } } return left; } };
类似min的函数:
1 int minNum = *min_element (nums.begin (),nums.end ());
扫描:419
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class Solution {public : int countBattleships (vector<vector<char >>& board) { int res = 0 ; int row = board.size (), col = board[0 ].size (); for (int i = 0 ; i < row; i++) { for (int j = 0 ; j < col; j++) { if (board[i][j] == 'X' ) { if ((i >= 1 && board[i - 1 ][j] == 'X' ) || (j >= 1 && board[i][j - 1 ] == 'X' )) { continue ; } res++; } } } return res; } };
迭代:396
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 #include <algorithm> #include <climits> #include <numeric> #include <vector> class Solution {public : int maxRotateFunction (vector<int >& nums) { int n = nums.size (), res = INT_MIN, Fk = 0 ; int sum = accumulate (nums.begin (), nums.end (), 0 ); for (int i = 0 ; i < n; i++) { Fk += i * nums[i]; } res = Fk; for (int i = n - 1 ; i > 0 ; i--) { Fk += sum - n * nums[i]; res = max (res, Fk); } return res; } };
模拟:54、59
对角线遍历498:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 for (int i = 0 ; i < m + n - 1 ; i++) { if (i % 2 ) { int x = (i < n ? 0 : i - n + 1 ); int y = (i < n ? i : n - 1 ); while (x < m && y >= 0 ) { res.emplace_back (mat[x][y]); x++; y--; } } else { int x = (i < m ? i : m - 1 ); int y = (i < m ? 0 : i - m + 1 ); while (x >= 0 && y < n) { res.emplace_back (mat[x][y]); x--; y++; } } }
在选择使用 emplace_back
还是 push_back
时,通常情况下,emplace_back
更好一些。这是因为 emplace_back
可以避免创建临时对象,从而提高了性能。
另外,emplace_back
也更加灵活,因为它允许你直接传递构造元素所需的参数,而不需要显式地创建对象。
总的来说,如果你需要向 vector
中添加新元素,通常情况下优先考虑使用 emplace_back
。
二维数组变换行列长宽:566
1 2 3 4 5 int m = mat.size (), n = mat[0 ].size ();for (int i = 0 ; i < m * n; i++) { res[i / c][i % c] =mat[i / n][i % n]; }
二维矩阵顺时针旋转(48)=水平
翻转(竖直线对称翻转)+(沿)主对角
线翻转
矩阵原地置换(73) :用矩阵第一行和第一列代替标记行和列的两个标记数组,使得空间复杂度为$O(1)$,时间复杂度为$O(row*col)$.但这样会导致原数组的第一行和第一列被修改,无法记录它们是否原本包含 0。因此我们需要额外使用两个标记变量分别记录第一行和第一列是否原本包含 0。
在实际代码中,我们首先预处理出两个标记变量,接着使用其他行与列去处理第一行与第一列,然后反过来使用第一行与第一列去更新其他行与列,最后使用两个标记变量更新第一行与第一列即可。
我们可以对方法二进一步优化,只使用一个标记变量记录第一列是否原本存在 0。这样,第一列的第一个元素即可以标记第一行是否出现 0。但为了防止每一列的第一个元素被提前更新,我们需要从最后一行开始,倒序地处理矩阵元素。
矩阵原地置换拓展(289) :创建复合状态2,可以知道修改前是0,而之后变为1.常用于需要同步更新情况。
涉及到类:303
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class NumArray {public : vector<int > sum; NumArray (vector<int >& nums) { int n = nums.size (); sum.resize (n + 1 ); for (int i = 0 ; i < n; i++) { sum[i + 1 ] = sum[i] + nums[i]; } } int sumRange (int left, int right) { return sum[right + 1 ] - sum[left]; } };
二维数组resize:
1 sums.resize (m + 1 , vector <int >(n + 1 ));
二维数组定义:(创建n×n的数组,默认初始化所有元素为0)
1 vector<vector<int >> res (n, vector <int >(n));
前缀/后缀之和/之积:238
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class Solution {public : vector<int > productExceptSelf (vector<int >& nums) { vector<int > res (nums.size()) ; res[0 ]=1 ; for (int i = 1 ; i < nums.size (); i++) { res[i]=res[i-1 ]*nums[i-1 ]; } int r=1 ; for (int i=nums.size ()-1 ;i>=0 ;i--){ res[i]=res[i]*r; r*=nums[i]; } return res; } };