代码随想录复习
这篇博客是二刷代码随想录过程中的一些笔记以及记录。
ch1 数组 二分查找 二分查找相对简单,重点是要搞清楚边界,我记二分模版的方法是:
while (l <= r) 为什么是<=,可以这样考虑,如果数组只有一个数据,那么也应当执行一次循环。
根据nums[mid] > target,nums[mid] < target,nums[mid] == target,三种情况分别讨论,保证不重不漏。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 class Solution {public : int search (vector<int >& nums, int target) { int l = 0 , r = nums.size () - 1 ; while (l <= r) { int mid = (l + r) >> 1 ; if (nums[mid] > target) { r = mid - 1 ; } else if (nums[mid] < target) { l = mid + 1 ; } else { return mid; } } return -1 ; } };
相关题目:
35. 搜索插入位置 - 力扣(LeetCode)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class Solution {public : int searchInsert (vector<int >& nums, int target) { int l = 0 , r = nums.size () - 1 ; while (l <= r) { int mid = (l + r) >> 1 ; if (nums[mid] > target) { r = mid - 1 ; } else if (nums[mid] < target) { l = mid + 1 ; } else { return mid; } } return l; } };
34. 在排序数组中查找元素的第一个和最后一个位置 - 力扣(LeetCode)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 class Solution {public : vector<int > searchRange (vector<int >& nums, int target) { int left = -1 , right = -1 ; int l = 0 , r = nums.size () - 1 ; while (l <= r) { int mid = (l + r) >> 1 ; if (nums[mid] > target) { r = mid - 1 ; } else if (nums[mid] < target) { l = mid + 1 ; } else { left = mid; r = mid - 1 ; } } l = 0 , r = nums.size () - 1 ; while (l <= r) { int mid = (l + r) >> 1 ; if (nums[mid] > target) { r = mid - 1 ; } else if (nums[mid] < target) { l = mid + 1 ; } else { right = mid; l = mid + 1 ; } } return {left, right}; } };
69. x 的平方根 - 力扣(LeetCode)
注意这里在求mid的时候,不能使用(l + r) >> 1
因为数据范围可能爆int
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class Solution {public : int mySqrt (int x) { if (x == 0 ) return 0 ; int l = 1 , r = x; while (l <= r) { int mid = l + (r - l) / 2 ; if (x / mid > mid) { l = mid + 1 ; } else if (x / mid < mid) { r = mid - 1 ; } else { return mid; } } return r; } };
367. 有效的完全平方数 - 力扣(LeetCode)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class Solution {public : bool isPerfectSquare (int num) { int l = 1 , r = num; while (l <= r) { int mid = l + (r - l) / 2 ; if (num * 1.0 / mid > mid) { l = mid + 1 ; } else if (num * 1.0 / mid < mid) { r = mid - 1 ; } else { return true ; } } return false ; } };
双指针 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class Solution {public : int removeElement (vector<int >& nums, int val) { int i = 0 , j = 0 ; for (; i < nums.size (); i ++ ) { if (nums[i] != val) { nums[j] = nums[i]; j ++; } } return j; } };
26. 删除有序数组中的重复项 - 力扣(LeetCode)
1 2 3 4 5 6 7 8 9 10 11 12 13 class Solution {public : int removeDuplicates (vector<int >& nums) { int i = 1 , j = 1 ; for (; i < nums.size (); i ++ ) { if (nums[i] != nums[i - 1 ]) { nums[j] = nums[i]; j ++; } } return j; } };
283. 移动零 - 力扣(LeetCode)
(灵神的代码,非常简洁)
1 2 3 4 5 6 7 8 9 10 11 12 class Solution {public : void moveZeroes (vector<int >& nums) { int i = 0 ; for (int & x : nums) { if (x) { swap (x, nums[i]); i++; } } } };
844. 比较含退格的字符串 - 力扣(LeetCode)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 class Solution {public : bool backspaceCompare (string s, string t) { stack<char > st1, st2; for (int i = 0 ; i < s.size (); i ++ ) { if (s[i] != '#' ) { st1. push (s[i]); } else { if (!st1. empty ()) st1. pop (); } } for (int i = 0 ; i < t.size (); i ++ ) { if (t[i] != '#' ) { st2. push (t[i]); } else { if (!st2. empty ()) st2. pop (); } } if (st1. size () != st2. size ()) return false ; while (!st1. empty ()) { char a = st1. top (), b = st2. top (); if (a != b) return false ; st1. pop (), st2. pop (); } return true ; } };
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 class Solution {public : bool backspaceCompare (string s, string t) { int i = s.size () - 1 , j = t.size () - 1 ; int skip_s = 0 , skip_t = 0 ; while (i >= 0 || j >= 0 ) { while (i >= 0 ) { if (s[i] == '#' ) skip_s++, i --; else if (skip_s > 0 ) skip_s--, i --; else { break ; } } while (j >= 0 ) { if (t[j] == '#' ) skip_t ++, j --; else if (skip_t > 0 ) skip_t --, j --; else { break ; } } if (i >= 0 && j >= 0 ) { if (s[i] != t[j]) return false ; } else { if (i >= 0 || j >= 0 ) return false ; } i --, j --; } return true ; } };
977. 有序数组的平方 - 力扣(LeetCode)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 class Solution {public : vector<int > sortedSquares (vector<int >& nums) { int index = 0 ; while (index < nums.size () && nums[index] <= 0 ) index ++; vector<int > a (index, 0 ) ; vector<int > b (nums.size() - index, 0 ) ; int i = index - 1 , j = index, k = 0 ; for (; i >= 0 ; i -- ) { a[k ++ ] = nums[i] * nums[i]; } k = 0 ; for (; j < nums.size (); j ++ ) { b[k ++ ] = nums[j] * nums[j]; } i = 0 , j = 0 , k = 0 ; while (i < a.size () && j < b.size ()) { if (a[i] <= b[j]) nums[k ++ ] = a[i ++ ]; else nums[k ++ ] = b[j ++ ]; } while (i < a.size ()) nums[k ++ ] = a[i ++ ]; while (j < b.size ()) nums[k ++ ] = b[j ++ ]; return nums; } };
滑动窗口 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class Solution {public : int minSubArrayLen (int target, vector<int >& nums) { int i = 0 , j = 0 , sum = 0 , ans = INT_MAX; for (; i < nums.size (); i ++ ) { sum += nums[i]; while (j <= i && sum >= target) { ans = min (ans, i - j + 1 ); sum -= nums[j], j ++; } } if (ans == INT_MAX) return 0 ; else return ans; } };
904. 水果成篮 - 力扣(LeetCode)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 class Solution {public : int totalFruit (vector<int >& fruits) { int cnt = 0 ; int ans = 0 ; pair<int , int > p1 = {-1 , 0 }; pair<int , int > p2 = {-1 , 0 }; int i = 0 , j = 0 ; for (; i < fruits.size (); i ++ ) { if (fruits[i] == p1.f irst) { p1. second ++; } else if (fruits[i] == p2.f irst) { p2. second ++; } else { while (cnt >= 2 ) { if (fruits[j] == p1.f irst) { p1. second --; if (p1. second == 0 ) cnt --; } else { p2. second --; if (p2. second == 0 ) cnt --; } j ++; } if (p1. second == 0 ) {p1.f irst = fruits[i]; p1. second = 1 ;} else {p2.f irst = fruits[i]; p2. second = 1 ;} cnt ++; } ans = max (ans, p1. second + p2. second); } return ans; } };
76. 最小覆盖子串 - 力扣(LeetCode)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 class Solution {public : string minWindow (string s, string t) { if (s.size () < t.size ()) return "" ; unordered_map<char , int > umap; for (auto c : t) umap[c] ++; int left = 0 , right = s.size () + 10 ; int i = 0 , j = 0 , cnt = 0 ; for (; i < s.size (); i ++ ) { if (umap.find (s[i]) != umap.end ()) { umap[s[i]] --; if (umap[s[i]] >= 0 ) cnt ++; } while (cnt == t.size ()) { if (right - left > i - j) { left = j; right = i; } if (umap.find (s[j]) != umap.end ()) { umap[s[j]] ++; if (umap[s[j]] > 0 ) cnt --; } j ++; } } if (right == s.size () + 10 ) return "" ; string ans = s.substr (left, right - left + 1 ); return ans; } };
模拟 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 class Solution {public : vector<vector<int >> generateMatrix (int n) { vector<vector<int >> matrix (n, vector <int >(n, 0 )); int count = n * n; int k = 1 ; int up = 0 , down = n - 1 , left = 0 , right = n - 1 ; while (k <= count) { for (int i = left; i <= right && k <= count; i ++ ) matrix[up][i] = k ++; up ++; for (int i = up; i <= down && k <= count; i ++ ) matrix[i][right] = k ++; right --; for (int i = right; i >= left && k <= count; i -- ) matrix[down][i] = k ++; down --; for (int i = down; i >= up && k <= count; i -- ) matrix[i][left] = k ++; left ++; } return matrix; } };
54. 螺旋矩阵 - 力扣(LeetCode)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class Solution {public : vector<int > spiralOrder (vector<vector<int >>& matrix) { vector<int > ans; int m = matrix.size (), n = matrix[0 ].size (); int k = 1 , count = m * n; int up = 0 , down = m - 1 , left = 0 , right = n - 1 ; while (k <= count) { for (int i = left; i <= right && k <= count; i ++, k ++ ) ans.push_back (matrix[up][i]); up ++; for (int i = up; i <= down && k <= count; i ++, k ++ ) ans.push_back (matrix[i][right]); right --; for (int i = right; i >= left && k <= count; i --, k ++ ) ans.push_back (matrix[down][i]); down --; for (int i = down; i >= up && k <= count; i --, k ++ ) ans.push_back (matrix[i][left]); left ++; } return ans; } };
LCR 146. 螺旋遍历二维数组 - 力扣(LeetCode)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 class Solution {public : vector<int > spiralArray (vector<vector<int >>& array) { if (array.size () == 0 ) return {}; vector<int > ans; int m = array.size (), n = array[0 ].size (); int k = 1 , count = m * n; int up = 0 , down = m - 1 , left = 0 , right = n - 1 ; while (k <= count) { for (int i = left; i <= right && k <= count; i ++, k ++ ) ans.push_back (array[up][i]); up ++; for (int i = up; i <= down && k <= count; i ++, k ++ ) ans.push_back (array[i][right]); right --; for (int i = right; i >= left && k <= count; i --, k ++ ) ans.push_back (array[down][i]); down --; for (int i = down; i >= up && k <= count; i --, k ++ ) ans.push_back (array[i][left]); left ++; } return ans; } };
前缀和 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 #include <iostream> #include <bits/stdc++.h> using namespace std;const int N = 1e5 + 10 ;int n;int a[N], b[N];int main () { cin >> n; for (int i = 1 ; i <= n; i ++ ) {cin >> a[i]; b[i] = b[i - 1 ] + a[i];} int l, r; while (cin >> l >> r) { cout << b[r + 1 ] - b[l] << endl; } return 0 ; }