思路
拷贝把备份排序,然后两个指针,依次从头到尾(i),从尾到头(j)比较排序前后两个数组相同下标的值,把第一次不同的下标值记录,最后返回j - i + 1,如果为负数返回0。
AC代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class Solution {public : int findUnsortedSubarray (vector<int >& nums) { vector<int > cpy (nums.begin(), nums.end()) ; sort (cpy.begin (), cpy.end ()); int len = nums.size (); int j = len - 1 , i = 0 ; for ( ; j >= 0 ; j--) { if (nums[j] != cpy[j]) { break ; } } for (; i < len; i++) { if (nums[i] != cpy[i]) { break ; } } int ans = j - i + 1 ; return ans > 0 ? ans : 0 ; } };
思路
从前到后遍历,一边找最大值,一边找当前值是不是最大值,如果不是,记录当前下标
从后向前遍历,一边找最小值,一边找当前值是不是最小值,如果不是,记录当前下标
返回下标之间的元素数,注意差值为0返回1
AC代码
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 static int pr = []() { std::ios::sync_with_stdio (false ); cin.tie (NULL ); return 0 ; }(); class Solution {public : int findUnsortedSubarray (vector<int >& nums) { int len = nums.size (); int j = len - 1 , i = 0 ; int max = INT_MIN, min = INT_MAX; int pre = 0 , back = len - 1 ; for (;i < len;i++, j--) { max = max > nums[i] ? max : nums[i]; if (max != nums[i]) { pre = i; } min = min < nums[j] ? min : nums[j]; if (min != nums[j]) { back = j; } } int ans = pre - back + 1 ; return ans > 1 ? ans : 0 ; } };
大佬思路
没看懂,为毛遍历这么多次可以这么快?
大佬代码
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 static int pr = []() { std::ios::sync_with_stdio (false ); cin.tie (NULL ); return 0 ; }(); class Solution {public : int findUnsortedSubarray (vector<int >& nums) { int n = nums.size (); int left = 0 ; int right = n - 1 ; while (left < n - 1 && nums[left] <= nums[left + 1 ]) left += 1 ; if (left == n - 1 ) return 0 ; while (right > 0 && nums[right] >= nums[right - 1 ]) right -= 1 ; int min_value = INT32_MAX; int max_value = INT32_MIN; for (int i = left; i < right + 1 ; i++) { min_value = min (nums[i], min_value); max_value = max (nums[i], max_value); } while (left > -1 && nums[left] > min_value) left -= 1 ; while (right < n && nums[right] < max_value) right += 1 ; return right - left - 1 ; } };
思路
每次反转k或者小于k个字符,然后指针+=2*k
AC代码
1 2 3 4 5 6 7 8 9 10 11 12 13 class Solution {public : string reverseStr (string s, int k) { int i = 0 ; int len = s.length (); while (i < len) { int l = len - i > k ? k : len - i; reverse (s.begin () + i, s.begin () + i + l); i += 2 *k; } return s; } };
思路
递归
AC代码
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 class Solution {public : vector<int > preorder (Node* root) { vector<int > ans; go (root, ans); return ans; } void go (Node* root, vector<int >& v) { if (root == NULL ) return ; v.push_back (root->val); for (auto x : root->children) { go (x, v); } } };
大佬思路
大佬代码
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 : vector<int > preorder (Node* root) { if (!root) { return vector <int >(); } stack<Node*> s; s.push (root); vector<int > ret; while (!s.empty ()) { Node* p = s.top (); s.pop (); ret.push_back (p->val); int n = (p->children).size (); for (int i = n - 1 ; i >= 0 ; --i) { if (p->children[i]) { s.push ((p->children)[i]); } } } return ret; } }; static auto _ = []() { std::ios::sync_with_stdio (false ); std::cin.tie (nullptr ); return 0 ; }();
AC代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class Solution {public : vector<int > postorder (Node* root) { vector<int > ans; go (root, ans); return ans; } void go (Node* root, vector<int >& v) { if (root == NULL ) return ; for (auto x : root->children) { go (x, v); } v.push_back (root->val); } };
思路
每次操作,左上角一定是重叠最大的,直接找最小的x,y就可以了
AC代码
1 2 3 4 5 6 7 8 9 10 11 class Solution {public : int maxCount (int m, int n, vector<vector<int >>& ops) { int minFirst = m, minSecond = n; for (auto x : ops) { minSecond = minSecond > x[1 ] ? x[1 ] : minSecond; minFirst = minFirst > x[0 ] ? x[0 ] : minFirst; } return minFirst*minSecond; } };
思路
一个map记录第一个数组的下标+1,然后遍历第二个数组,搞一个map,记录下标和对应的餐厅数组
优化,遍历第二个数组的时候,查询,计算下标和,如果下标和小于当前的最小值,那么就clear当前数组,重新把当前这个餐厅push进去,如果等于,直接push餐厅,大于则不管
AC代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class Solution {public : vector<string> findRestaurant (vector<string>& list1, vector<string>& list2) { unordered_map<string, int > m; map<int , vector<string>> ans; int len1 = list1.size (); int len2 = list2.size (); for (int i = 0 ; i < len1; i++) { m[list1[i]] = i + 1 ; } for (int i = 0 ; i < len2 ; i++) { int pos = m[list2[i]]; if (pos) { ans[pos - 1 + i].push_back (list2[i]); } } return ans.begin ()->second; } };
AC代码(优化)
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<string> findRestaurant (vector<string>& list1, vector<string>& list2) { unordered_map<string, int > m; vector<string> ans; int len1 = list1.size (); int len2 = list2.size (); int min = INT_MAX; for (int i = 0 ; i < len1; i++) { m[list1[i]] = i + 1 ; } for (int i = 0 ; i < len2 ; i++) { int pos = m[list2[i]]; if (pos) { int sum = pos - 1 + i; if (sum < min) { ans.clear (); min = sum; ans.push_back (list2[i]); } else if (sum == min) { ans.push_back (list2[i]); } } } return ans; } };
思路
遍历每一个花盆,看它前后有没有花盆,枚举判断,注意如果n == 0时要退出循环
优化:把第一个和最后一个单独拿出来,简化循环时的判断数目
AC代码
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 class Solution {public : bool canPlaceFlowers (vector<int >& flowerbed, int n) { int len = flowerbed.size (); for (int i = 0 ; i < len && n > 0 ; i++) { if (flowerbed[i]) { } else { if (i == 0 ) { if (len == 1 || (i + 1 < len && !flowerbed[i + 1 ])) { n--; flowerbed[i] = 1 ; } } else if (i == len - 1 ) { if (i - 1 >= 0 && !flowerbed[i - 1 ]) { n--; flowerbed[i] = 1 ; } } else { if (!flowerbed[i - 1 ] && !flowerbed[i + 1 ]) { n--; flowerbed[i] = 1 ; } } } } return n == 0 ; } };
AC代码(优化)
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 : bool canPlaceFlowers (vector<int >& flowerbed, int n) { if (n <= 0 ) return true ; int len = flowerbed.size (); if (len <= 0 ) return false ; if (len == 1 ) return n <= 1 && !flowerbed[0 ]; int sum = 0 ; if (!flowerbed[0 ] && !flowerbed[1 ]) { sum++; flowerbed[0 ] = 1 ; } for (int i = 1 ; i < len - 2 ; i++) { if (!flowerbed[i] && !flowerbed[i - 1 ] && !flowerbed[i + 1 ]) { flowerbed[i] = 1 ; sum++; } } if (!flowerbed[len - 2 ] && !flowerbed[len - 1 ]) { sum++; flowerbed[len - 1 ] = 1 ; } return n <= sum; } };
思路
参考414. 第三大的数 的思路,用一次遍历,得到第一,第二第三大的数(a、b、c),和第一,第二小的数(m1,m2)
分别计算a ∗ b ∗ c a*b*c a ∗ b ∗ c 和a ∗ m 1 ∗ m 2 a*m1*m2 a ∗ m 1 ∗ m 2 ,返回较大的一个
AC代码
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 : int maximumProduct (vector<int >& nums) { int first = INT_MIN, second = INT_MIN, third = INT_MIN; int min1 = INT_MAX, min2 = INT_MAX; for (auto x : nums) { if (x >= first) { third = second; second = first; first = x; } else if (x < first && x >= second) { third = second; second = x; } else if (x < second && x >= third) { third = x; } if (x < min1) { min2 = min1; min1 = x; } else if (x >= min1 && x < min2) { min2 = x; } } int ans1 = first*second*third, ans2 = first*min1*min2; return ans1 > ans2 ? ans1 : ans2; } };
思路
脑袋里想一个只有整数点的坐标系,取第一象限,用y = x y = x y = x 分成两半,看一半,包括y = x y = x y = x 和另一个坐标轴,在这个三角区域里选取的的不会重复
选取点,从0~c 2 \sqrt{\frac{c}{2}} 2 c 中选整数,如果满足c − i 2 \sqrt{c - i^2} c − i 2 为整数,那么就可以
优化,类似二分查找
AC代码
1 2 3 4 5 6 7 8 9 10 11 12 13 class Solution {public : bool judgeSquareSum (int c) { double n = sqrt (c/2.0 ); for (int i = 0 ; i <= n; i++) { double x = sqrt (c - i*i); if (int (x) == x) { return true ; } } return false ; } };
AC代码(优化)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class Solution {public : bool judgeSquareSum (int c) { int a = 0 , b = sqrt (c); while (a <= b) { double sum = (double )a*a + b*b; if (sum == c) { return true ; } else if (sum > c) { b--; } else { a++; } } return false ; } };
思路
改造二叉树的层次遍历 的代码完事儿
AC代码
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 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 class Solution {public : vector<double > averageOfLevels (TreeNode* root) { if (!root) return {}; vector<double > ans; TreeNode *root1 = new TreeNode (0 ), *root2 = new TreeNode (0 ); root2->left = root; root1->left = root2; TreeNode* temp = root1; vector<TreeNode*> m = {root1}; vector<TreeNode*>& father = m; vector<TreeNode*> fatherTemp; while (father.size ()) { fatherTemp.clear (); double sum = 0 , count = 0 ; for (TreeNode* x : father) { if (x->left != NULL ) { fatherTemp.push_back (x->left); if (x->left->left != NULL ) { count++; sum += x->left->left->val; } if (x->left->right != NULL ) { sum += x->left->right->val; count++; } } if (x->right != NULL ) { fatherTemp.push_back (x->right); if (x->right->left != NULL ) { sum += x->right->left->val; count++; } if (x->right->right != NULL ) { sum += x->right->right->val; count++; } } } if (count) ans.push_back (sum/count); father = fatherTemp; } return ans; } };
思路
先算前k个数的和,然后i从k+1个数开始,把尾巴上的数减掉,上i指向的数,跟当前值比大小,储存最大和。
AC代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 class Solution {public : double findMaxAverage (vector<int >& nums, int k) { int len = nums.size (); int sum = 0 ; double maxSum = 0 ; for (int i = 0 ; i < k; i++) { sum += nums[i]; } maxSum = sum; for (int i = k; i < len; i++) { sum -= nums[i - k]; sum += nums[i]; maxSum = maxSum > sum ? maxSum : sum; } return maxSum*1.0 /k; } }; static const int _ = []() { ios::sync_with_stdio (false ); cin.tie (nullptr ); cout.tie (nullptr ); return 0 ; }();
思路
一个vector,初始化为false,一次循环,每出现一个元素,把false变成true,如果已经是true,说明它是重复的元素,同时计算所有元素的和,最后根据等差数列求和公式等一系列计算计算出两个数
AC代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class Solution {public : vector<int > findErrorNums (vector<int >& nums) { int n = 0 ; int sum = 0 , len = nums.size (); vector<bool > m (len, false ) ; for (auto x : nums) { if (!m[x])m[x] = true ; else n = x; sum += x; } int add = len*(len + 1 ) / 2 - sum; return {n, n + add}; } }; static const int _ = []() { ios::sync_with_stdio (false ); cin.tie (nullptr ); cout.tie (nullptr ); return 0 ; }();
AC代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 class Solution {public : bool judgeCircle (string moves) { int u = 0 ,d = 0 ,r = 0 ,l = 0 ; for (auto x : moves) { switch (x) { case 'U' : u++; break ; case 'D' : d++; break ; case 'R' : r++; break ; case 'L' : l++; break ; } } return u == d && l == r; } }; static int desyncio = []() { std::ios::sync_with_stdio (false ); cin.tie (nullptr ); cout.tie (nullptr ); return 0 ; }();
AC代码(优化)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 class Solution {public : bool judgeCircle (string moves) { int movex[26 ] = {0 }, movey[26 ] = {0 }; movey['U' - 'A' ] = 1 ; movey['D' - 'A' ] = -1 ; movex['L' - 'A' ] = -1 ; movex['R' - 'A' ] = 1 ; int x = 0 , y = 0 ; for (auto c : moves) { y += movey[c - 'A' ]; x += movex[c - 'A' ]; } return x == 0 && y == 0 ; } }; static int desyncio = []() { std::ios::sync_with_stdio (false ); cin.tie (nullptr ); cout.tie (nullptr ); return 0 ; }();
思路
暴力干死这破题
AC代码
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 38 39 40 41 42 43 44 45 46 47 48 49 class Solution {public : vector<vector<int >> imageSmoother (vector<vector<int >>& M) { int r = M.size (); int c = M[0 ].size (); if (r <= 1 && c <= 1 ) return M; vector<vector<int >> ans (r, vector <int >(c)); if (c == 1 || r == 1 ) { if (c == 1 ) { ans[0 ][0 ] = (M[0 ][0 ] + M[1 ][0 ])/2 ; ans[r - 1 ][0 ] = (M[r - 1 ][0 ] + M[r - 2 ][0 ])/2 ; for (int i = 1 ; i < r - 1 ; i++) { ans[i][0 ] = (M[i][0 ] + M[i - 1 ][0 ] + M[i + 1 ][0 ])/3 ; } } else { ans[0 ][0 ] = (M[0 ][0 ] + M[0 ][1 ])/2 ; ans[0 ][c - 1 ] = (M[0 ][c - 1 ] + M[0 ][c - 2 ])/2 ; for (int i = 1 ; i < c - 1 ; i++) { ans[0 ][i] = (M[0 ][i] + M[0 ][i - 1 ] + M[0 ][i + 1 ])/3 ; } } return ans; } ans[0 ][0 ] = (M[0 ][0 ] + M[1 ][1 ] + M[1 ][0 ] + M[0 ][1 ])/4 ; ans[0 ][c - 1 ] = (M[0 ][c - 1 ] + M[0 ][c - 2 ] + M[1 ][c - 1 ] + M[1 ][c - 2 ])/4 ; ans[r - 1 ][0 ] = (M[r - 1 ][0 ] + M[r-1 ][1 ] + M[r - 2 ][0 ] + M[r - 2 ][1 ])/4 ; ans[r - 1 ][c - 1 ] = (M[r - 1 ][c - 1 ] + M[r - 1 ][c - 2 ] + M[r - 2 ][c - 1 ] + M[r - 2 ][c - 2 ])/4 ; for (int i = 1 ; i < r - 1 ; i++) { ans[i][0 ] = (M[i][0 ] + M[i - 1 ][0 ] + M[i + 1 ][0 ] + M[i][1 ] + M[i - 1 ][1 ] + M[i + 1 ][1 ])/6 ; ans[i][c - 1 ] = (M[i][c - 1 ] + M[i + 1 ][c - 1 ] + M[i - 1 ][c - 1 ] + M[i][c - 2 ] + M[i + 1 ][c - 2 ] + M[i - 1 ][c - 2 ])/6 ; } for (int i = 1 ; i < c - 1 ; i++) { ans[0 ][i] = (M[0 ][i] + M[0 ][i + 1 ] + M[0 ][i - 1 ] + M[1 ][i] + M[1 ][i + 1 ] + M[1 ][i - 1 ]) / 6 ; ans[r - 1 ][i] = (M[r - 1 ][i] + M[r - 1 ][i + 1 ] + M[r - 1 ][i - 1 ] + M[r - 2 ][i] + M[r - 2 ][i + 1 ] + M[r - 2 ][i - 1 ]) / 6 ; } for (int i = 1 ; i < r - 1 ; i++) { for (int j = 1 ; j < c - 1 ; j++) { ans[i][j] = (M[i][j] + M[i + 1 ][j] + M[i - 1 ][j] + M[i][j + 1 ] + M[i + 1 ][j + 1 ] + M[i - 1 ][j + 1 ] + M[i][j - 1 ] + M[i + 1 ][j - 1 ] + M[i - 1 ][j - 1 ])/9 ; } } return ans; } }; static const int _ = []() { ios::sync_with_stdio (false ); cin.tie (nullptr ); cout.tie (nullptr ); return 0 ; }();