diff --git a/README.md b/README.md index a573662..0d62eef 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,8 @@ ## CS_Notes +### 主页 +[Welcome to my website!](https://github16cp.github.io/) + ### Deep Learning Side Channel Attack [ASCAD](https://github.com/github16cp/ASCAD) @@ -7,14 +10,23 @@ [DPA Contest](http://www.dpacontest.org/home/) -[HDF5 for Python](https://www.h5py.org/) +### C++ + +[剑指Offer题解](https://github.com/github16cp/LearningNotes/blob/master/%E5%88%B7%E9%A2%98/%E5%89%91%E6%8C%87Offer%E9%A2%98%E8%A7%A3.md) + +[牛客网](https://www.nowcoder.com/957917052) + +[LeetCode](https://leetcode.com/) + +### Python +[莫烦python](https://morvanzhou.github.io/) + +### 工具 +[Git](https://github.com/github16cp/LearningNotes/blob/master/Tools/git.md) ### tensorflow [tensorflow](https://github.com/tensorflow/tensorflow) -### keras -[keras](https://github.com/keras-team/keras) - [keras Document](https://keras.io/) [keras中文文档](https://keras-cn.readthedocs.io/en/latest/) @@ -22,25 +34,12 @@ ### Pytorch [pytorch官网](https://pytorch.org/tutorials/beginner/blitz/cifar10_tutorial.html) -### C++ - -[剑指Offer题解](https://www.nowcoder.com/957917052) - -[牛客网](https://www.nowcoder.com/957917052) - -[LeetCode](https://leetcode.com/) - -### Python -[学习笔记](https://github.com/github16cp/Python/tree/master/learningNotes) - ### 博客 [csdn博客](https://blog.csdn.net/anzhou7262) ### 论坛 [stackoverflow](https://stackoverflow.com/questions) -### 写作 -[SCI模板](http://www.phrasebank.manchester.ac.uk/) ### 在线学习课程 @@ -50,3 +49,6 @@ [coursera](https://www.coursera.org/learn/machine-learning/home/welcome) +[复旦大学邱锡鹏](https://nndl.github.io/) + +[吴恩达全民AI](https://www.coursera.org/learn/ai-for-everyone/home/welcome) \ No newline at end of file diff --git a/Tools/git.md b/Tools/git.md index 6533224..3f1307e 100644 --- a/Tools/git.md +++ b/Tools/git.md @@ -27,6 +27,23 @@ Git易于学习,占地面积小,性能极快。它超越了诸如Subversion 9. git rebase 10. git tag +## 常用命令 +1、更新工作树 +``` +git add * +``` +2、提交当前修改 +``` +git commit -m "message" +``` +3、推送到远程服务器 +``` +git push origin master +``` +4、从远程服务器下拉 +``` +git pull +``` [参考](https://git-scm.com/docs/giteveryday) ## Error and Solution **Error 1** @@ -59,10 +76,16 @@ Solution: 原因本机公钥(publickey)未添加至github,所以无法识 git clone @github.com:yourname/Python.git ``` +## git 查询用户名和密码 +1. git config user.name +2. git config user.email ## git bash 提交没有绿格子问题 git bash 中的邮箱地址和github的邮箱地址不一致造成的,在git bash中将邮箱地址更改为github中的邮箱地址 ``` git config --global user.email "xx@xx.com" -``` \ No newline at end of file +``` + +## 搭建个人博客网站 +[Github pages](https://pages.github.com/) \ No newline at end of file diff --git "a/\345\210\267\351\242\230/LeetCode\345\210\206\347\261\273\347\273\203\344\271\240\347\257\207.md" "b/\345\210\267\351\242\230/LeetCode\345\210\206\347\261\273\347\273\203\344\271\240\347\257\207.md" new file mode 100644 index 0000000..8100f7a --- /dev/null +++ "b/\345\210\267\351\242\230/LeetCode\345\210\206\347\261\273\347\273\203\344\271\240\347\257\207.md" @@ -0,0 +1,2624 @@ + +* [1. 数组](#1-数组) +* [2. 哈希表](#2-哈希表) +* [3. 链表](#3-链表) +* [4. Math](#4-Math) +* [5. 对撞指针](#5-对撞指针) +* [6. 字符串](#6-字符串) +* [7. 二分搜索](#7-二分搜索) +* [8. 分治](#8-分治) +* [9. 动态规划](#9-动态规划) +* [10. 回溯](#10-回溯) +* [11. 栈](#11-栈) +* [12. 堆](#12-堆) +* [13. 贪心算法](#13-贪心算法) +* [14. 排序](#14-排序) +* [15. 位操作](#15-位操作) +* [16. 树](#16-树) +* [17. 深度优先搜索](#17-深度优先搜索) +* [18. 广度优先搜索](#18-广度优先搜索) +* [19. 并查集UnionFind](#19-并查集UnionFind) +* [20. 图](#20-图) +* [21. 设计题Design](#21-设计题Design) +* [22. 拓扑排序](#22-拓扑排序) +* [23. 字典树Trie](#23-字典树Trie) +* [24. 树状数组BinaryIndexedTree](#24-树状数组BinaryIndexedTree) +* [25. 线段树SegmentTree](#25-线段树SegmentTree) +* [26. 二叉搜索树](#26-二叉搜索树) +* [27. 递归](#27-递归) +* [28. 脑筋急转弯Brainteaser](#28-脑筋急转弯Brainteaser) +* [29. Memoization](#29-Memoization) +* [30. 队列](#30-队列) +* [31. 极大极小值](#31-极大极小值) +* [32. 蓄水池抽样问题ReservoirSampling](#32-蓄水池抽样问题ReservoirSampling) +* [33. OrderedMap](#33-OrderedMap) +* [34. 几何题Geometry](#34-几何题Geometry) +* [35. Random](#35-Random) +* [36. 拒绝采样RejectionSampling](#36-拒绝采样RejectionSampling) +* [37. 滑动窗口](#37-滑动窗口) +* [38. LineSweep](#38-LineSweep) +* [39. 未分类](#39-未分类) + + +# 1. 数组 +[array类题目](https://leetcode.com/problemset/all/?topicSlugs=array) +## 1013. Partition Array Into Three Parts With Equal Sum +```C++ +//[-1,1,-1,1] +class Solution { +public: + bool canThreePartsEqualSum(vector& A) { + int total = accumulate(A.begin(), A.end(), 0); + if (total % 3 != 0) return false; + int parts = 0; + for (int i = 0, sum = 0; i < A.size() && parts < (total != 0 ? 2 : 3); ++i) { + sum += A[i]; + if (sum == total / 3) ++parts, sum = 0; + } + return parts == (total != 0 ? 2 : 3); + } +}; + +``` +## 888. Fair Candy Swap +```C++ +class Solution { +public: + vector fairCandySwap(vector& A, vector& B) { + int sumA = accumulate(A.begin(), A.end(), 0); + int sumB = accumulate(B.begin(), B.end(), 0); + int total = (sumA + sumB) / 2; + for (auto i : A) { + int item = total - (sumA - i); + for (auto j : B) + if (j == item) return {i,item}; + } + return {}; + } +}; +``` +## 448. Find All Numbers Disappeared in an Array +```C++ +class Solution { +public: + vector findDisappearedNumbers(vector& nums) { + vector res; + for (int i = 0; i < nums.size(); i++) { + int val = abs(nums[i]) - 1; + if (nums[val] > 0) { + nums[val] = -nums[val]; + } + } + + for (int i = 0; i < nums.size(); i++) { + if (nums[i] > 0) { + res.push_back(i + 1); + } + } + + return res; + } +}; +``` +## 717. 1-bit and 2-bit Characters +```C++ +class Solution { +public: + bool isOneBitCharacter(vector& bits) { + int ones = 0; + for (int i = bits.size() - 2; i >= 0 && bits[i] != 0; --i) ones++; + return ones % 2 == 0; + } +}; +``` +## 999. Available Captures for Rook +```C++ +class Solution { +public: + int numRookCaptures(vector>& board) { + for (int i = 0; i < board.size(); i++) + for (int j = 0; j < board[0].size(); j++) + if (board[i][j] == 'R') + return cap(board, i, j, 0, 1) + cap(board, i, j, 0, -1) + cap(board, i, j, 1, 0) + cap(board, i, j, -1, 0); + return 0; + } + + int cap(vector >& board, int x, int y, int dx, int dy) { + while (x >= 0 && x < board.size() && y >= 0 && y < board[x].size() && board[x][y] != 'B') { + if (board[x][y] == 'p') return 1; + x += dx; y += dy; + } + return 0; + } +}; +``` +## 1002. Find Common Characters +```C++ +class Solution { +public: + vector commonChars(vector& A) { + vector res; + vector cnt(26, INT_MAX); + for (auto s : A) { + vector cnt_s(26, 0); + for (auto c : s) ++cnt_s[c - 'a']; + for (int i = 0; i < 26; i++) cnt[i] = min(cnt[i], cnt_s[i]); + } + for (int i = 0; i < 26; i++) + for (int j = 0; j < cnt[i]; j++) res.push_back(string(1, i + 'a')); + return res; + } +}; +``` +## 985. Sum of Even Numbers After Queries +```C++ +class Solution { +public: + vector sumEvenAfterQueries(vector& A, vector>& queries) { + vector answer(queries.size(), 0); + int sum = 0; + for (auto i : A) { + if (i % 2 == 0) + sum += i; + } + //A[index]是偶数,加奇数,减去A[index];A[index]是偶数,加偶数,加上val(减去A[index]) + for (int i = 0; i < queries.size(); i++) { + int val = queries[i][0]; + int index = queries[i][1]; + if (A[index] % 2 == 0) { + sum -= A[index]; + } + A[index] = A[index] + val; + if (A[index] % 2 == 0) { + sum += A[index]; + } + answer[i] = sum; + } + return answer; + } +}; +``` +## 867. Transpose Matrix +```C++ +class Solution { +public: + vector> transpose(vector>& A) { + int m = A.size(); + int n = A[0].size(); + vector> res(n, (vector(m, 0))); + for (int i = 0; i < n; i++) { + for (int j = 0; j < m; j++) { + res[i][j] = A[j][i]; + } + } + return res; + } +}; +``` +## 566. Reshape the Matrix +```C++ +class Solution { +public: + vector> matrixReshape(vector>& nums, int r, int c) { + vector> res(r, (vector(c, 0))); + int m = nums.size(), n = nums[0].size(); + if (r * c != m * n) return nums; + for (int i = 0; i < r*c; i++) { + res[i/c][i%c] = nums[i/n][i%n]; + } + return res; + } +}; +``` +## 766. Toeplitz Matrix +```C++ +class Solution { +public: + bool isToeplitzMatrix(vector>& matrix) { + for (int i = 0; i < matrix.size(); i++) + for (int j = 0; j < matrix[0].size(); j++) + if (matrix[i][j] != matrix[i + 1][j + 1]) return false; + return true; + } +}; +``` +## 283. Move Zeroes +```C++ +class Solution { +public: + void moveZeroes(vector& nums) { + int cnt = 0; + for (vector::iterator it = nums.begin(); it != nums.end();) { + if (*it == 0) { + cnt++; + it = nums.erase(it); + } + else it++; + } + for (int i = 0; i < cnt; i++) + nums.push_back(0); + } +}; +``` +## 896. Monotonic Array +```C++ +class Solution { +public: + bool isMonotonic(vector& A) { + bool inc = true, dec = true; + for (int i = 0; i < A.size() - 1; i++) + inc &= A[i + 1] >= A[i], dec &= A[i + 1] <= A[i]; + return inc || dec; + } +}; +``` +## 485. Max Consecutive Ones +```C++ +class Solution { +public: + int findMaxConsecutiveOnes(vector& nums) { + int maxSum = INT_MIN; + if (!nums.size()) return maxSum; + int curSum = nums[0]; + for (int i = 1; i < nums.size(); i++) { + if (nums[i] == nums[i - 1]) curSum += nums[i]; + else { + if (curSum > maxSum) maxSum = curSum; + curSum = nums[i]; + } + } + if (curSum > maxSum) maxSum = curSum; + return maxSum; + } +}; +``` +## 509. Fibonacci Number +```C++ +class Solution { +public: + int fib(int N) { + if (N == 0 || N == 1) return N; + int first = 0, second = 1, third = 0; + for (int i = 0; i < N - 1; i++) { + third = first + second; + first = second; + second = third; + } + return third; + } +}; +``` +## 922. Sort Array By Parity II +```C++ +class Solution { +public: + vector sortArrayByParityII(vector& A) { + if (!A.size()) return A; + for (int i = 0; i < A.size(); i++) { + if ((i % 2 == 0 && A[i] % 2 == 0) || (i % 2 != 0 && A[i] % 2 != 0)) + continue; + for (int j = i + 1; j < A.size(); j++) { + if ((i % 2 == 0 && A[j] % 2 == 0) || (i % 2 != 0 && A[j] % 2 != 0)) { + int tmp = A[i]; + A[i] = A[j]; + A[j] = tmp; + break; + } + } + } + return A; + } +}; +``` +## 561. Array Partition I +```C++ +class Solution { +public: + int arrayPairSum(vector& nums) { + int sum = 0; + sort(nums.begin(), nums.end()); + for (int i = 0; i < nums.size(); i += 2) { + sum += nums[i]; + } + return sum; + } +}; +``` +## 1051. Height Checker +```C++ +class Solution { +public: + int heightChecker(vector& heights) { + int count = 0; + vector tmp(heights); + sort(tmp.begin(), tmp.end()); + for (int i = 0; i < tmp.size(); i++) { + if (heights[i] != tmp[i]) + count++; + } + return count; + } +}; +``` +## 977. Squares of a Sorted Array +```C++ +class Solution { +public: + vector sortedSquares(vector& A) { + for (int i = 0; i < A.size(); i++) { + A[i] = A[i] * A[i]; + } + sort(A.begin(), A.end()); + return A; + } +}; +``` +## 832. Flipping an Image +```C++ +#include +#include +#include +using namespace std; + +class Solution { +public: + vector> flipAndInvertImage(vector>& A) { + int m = A.size(); + int n = A[0].size(); + if (m == 0) return A; + for (int i = 0; i < m; i++) { + reverse(A[i].begin(), A[i].end()); + } + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + A[i][j] = 1 - A[i][j]; + } + } + return A; + } +}; + +int main() +{ + Solution s; + int m = 4; + vector tmp(m,0); + vector > input; + for (int j = 0; j < m; j++) { + for (int i = 0; i < m; i++) { + cin >> tmp[i]; + } + input.push_back(tmp); + } + /*for (int i = 0; i < m; i++) + for (int j = 0; j < m; j++) + cout << input[i][j] << " ";*/ + + vector > res; + res = s.flipAndInvertImage(input); + for (int i = 0; i < m; i++) { + for (int j = 0; j < m; j++) { + cout << res[i][j] << " "; + } + cout << endl; + } + system("pause"); + return 0; +} +``` +## 15. 3Sum +二分查找,寻找3个数相加为0。 +```C++ +#include +#include +#include +using namespace std; + +//固定i和j,查找t,二分查找lower_bound,O(n^2*log(n)) +class Solution { +public: + vector> threeSum(vector& nums) { + vector> res; + int len = nums.size(); + if (len == 0) return res; + sort(nums.begin(), nums.end()); + for (int i = 0; i < len; i++) { + for (int j = i + 1; j < len; j++) { + vector tmp; + int t = -(nums[i] + nums[j]); + auto it = lower_bound(nums.begin() + j + 1, nums.end(), t);//返回下标 + if (it != nums.end() && *it == t) {//二分查找找到 + tmp.push_back(nums[i]); + tmp.push_back(nums[j]); + tmp.push_back(*it); + res.push_back(tmp); + } + while (j + 1 < len && nums[j + 1] == nums[j]) { + j++; + + } + } + while (i + 1 < len && nums[i + 1] == nums[i]) { + i++; + } + } + return res; + } +}; + +int main() +{ + return 0; +} +``` +## 26. Remove Duplicates from Sorted Array +```C++ +#include +#include +using namespace std; + +class Solution { +public: + int removeDuplicates(vector& nums) { + int len = nums.size(); + if (len == 0) return 0; + if (len == 1) return 1; + + for (vector::iterator it = nums.begin(); (it + 1)!= nums.end(); ) { + if (*it == *(it+1)) + nums.erase(it+1); + else it++; + } + return nums.size(); + } +}; + +int main() +{ + Solution ss; + vector nums = { 0,0,1,1,1,2,2,3,3,4 }; + cout << ss.removeDuplicates(nums) << endl; + system("pause"); + return 0; +} +``` +## 27. Remove Element +```C++ +class Solution { +public: + int removeElement(vector& nums, int val) { + int len = nums.size(); + if (len == 0) return 0; + for (vector::iterator it = nums.begin(); it != nums.end();) { + if (*it == val) + it = nums.erase(it); + else it++; + } + return nums.size(); + } +}; +``` + +## 35. Search Insert Position +```C++ +class Solution { +public: + int searchInsert(vector& nums, int target) { + int len = nums.size(); + if (len == 0) return 0; + if (nums[0] >= target) + return 0; + int i = 0; + for (; i + 1 < len; i++) { + if (nums[i] == target) + return i; + if (nums[i] < target && nums[i + 1] >= target) + return i + 1; + } + return len; + } +}; +``` +## 53. Maximum Subarray +```C++ +class Solution { +public: + int maxSubArray(vector& nums) { + int len = nums.size(); + if (len == 0) return 0; + int cursum = 0;//累加的子数组的和 + int greatsum = 0x80000000;//最大的子数组的和 + for (int i = 0; i < len; i++) { + if (cursum <= 0) + cursum = nums[i]; + else + cursum += nums[i]; + + if (cursum > greatsum) + greatsum = cursum; + } + return greatsum; + } +}; +``` +## 66. Plus One +```C++ +#include +#include +using namespace std; + +class Solution { +public: + vector plusOne(vector& digits) { + if (!digits.size()) return digits; + int carry = 1; + for (int i = digits.size() - 1; i >= 0; --i) { + int tmp = digits[i] + carry; + digits[i] = tmp % 10; + carry = tmp / 10; + } + if (carry) digits.insert(digits.begin(), carry); + return digits; + } +}; + +int main() { + Solution s; + vector vec = { 1,2,3 }; + vector res; + res = s.plusOne(vec); + for (auto i : res) + cout << i << " "; + cout << endl; + system("pause"); + return 0; +} +``` +## 88. Merge Sorted Array +```C++ +class Solution { +public: + void merge(vector& nums1, int m, vector& nums2, int n) { + if (!nums2.size()) return; + if (!nums1.size()) return; + if (nums1.size() < (m + n)) return; + int j = 0; + for (int i = m; i < nums1.size() && j < nums1.size(); ++i) + nums1[i] = nums2[j++]; + sort(nums1.begin(), nums1.end()); + } +}; +``` +## 118. Pascal's Triangle +杨辉三角 +```C++ +class Solution { +public: + vector> generate(int numRows) { + vector > res; + if (numRows == 0) return res; + + vector tmp(1, 1);//第一个 + res.push_back(tmp); + + for (int i = 2; i <= numRows; i++) { + tmp.push_back(0); + vector cur = tmp; + for (int j = 1; j < i; j++) + cur[j] = tmp[j] + tmp[j - 1]; + res.push_back(cur); + tmp = cur; + } + return res; + } +}; +``` +## 119. Pascal's Triangle II +```C++ +class Solution { +public: + vector getRow(int rowIndex) { + vector res; + if (rowIndex < 0) return res; + + vector last(1,1);///rowIndex = 0 + res = last; + for (int i = 2; i < rowIndex + 2; i++) {//rowIndex = 1; + last.push_back(0); + res = last; + for (int j = 1; j < i; j++) + res[j] = last[j] + last[j - 1]; + last = res; + } + return res; + } +}; +``` +## 121. Best Time to Buy and Sell Stock +```C++ +class Solution { +public: + int maxProfit(vector& prices) { + int len = prices.size(); + if (len <= 1) return 0; + int res = prices[1] - prices[0], minprice = prices[0]; + for (int i = 2; i < len; i++) { + minprice = min(minprice, prices[i - 1]); + if (res < prices[i] - minprice) + res = prices[i] - minprice; + } + if (res < 0) return 0; + return res; + } +}; +``` +## 167. Two Sum II - Input array is sorted +```C++ +class Solution { +public: + vector twoSum(vector& numbers, int target) { + if (numbers.size() == 0) return {}; + int begin = 0, end = numbers.size() - 1; + while (begin < end) { + int sum = numbers[begin] + numbers[end]; + if (sum == target) + return { begin + 1,end + 1 }; + else if (sum > target) { + end--; + } + else begin++; + } + return {}; + } +}; +``` +## 217. Contains Duplicate +```C++ +class Solution { +public: + bool containsDuplicate(vector& nums) { + return nums.size() > set(nums.begin(), nums.end()).size(); + } +}; +``` +## 219. Contains Duplicate II +```C++ +//set中保留距离小于等于k的不重复元素,如果元素在s中返回true,否则更新set +class Solution { +public: + bool containsNearbyDuplicate(vector& nums, int k) { + unordered_set s; + if (k <= 0) return false; + if (k >= nums.size()) k = nums.size() - 1; + + for (int i = 0; i < nums.size(); i++) { + if (i > k) s.erase(nums[i - k - 1]); + if (s.find(nums[i]) != s.end()) return true; + s.insert(nums[i]); + } + return false; + } +}; +``` +## 169. Majority Element +```C++ +class Solution { +public: + int majorityElement(vector& nums) { + if (nums.size() == 0) return 0; + int res = nums[0]; + int times = 1; + for (int i = 1; i < nums.size(); i++) { + if (times == 0) { + res = nums[i]; + times = 1; + } + else if (nums[i] == res) times++; + else times--; + } + return res; + } +}; +``` +## 189. Rotate Array +```C++ +class Solution { +public: + void rotate(vector& nums, int k) { + k %= nums.size(); + reverse(nums.begin(), nums.end()); + reverse(nums.begin(), nums.begin() + k); + reverse(nums.begin() + k, nums.end()); + } +}; +``` +## 58. Length of Last Word +```C++ +class Solution { +public: + int lengthOfLastWord(string s) { + int res = 0; + istringstream is(s); + string laststr = ""; + while (is >> laststr) { + res = laststr.length(); + } + return res; + } +}; +``` +## 434. Number of Segments in a String +```C++ +class Solution { +public: + int countSegments(string s) { + int count = 0; + istringstream is(s); + string tmp; + while (is >> tmp) { + count++; + } + return count; + } +}; +``` +## 905. Sort Array By Parity +```C++ +class Solution { +public: + vector sortArrayByParity(vector& A) { + int left = 0, right = A.size() - 1; + while (left < right) { + if (A[left] % 2 != 0 && A[right] % 2 == 0) { + int temp = A[left]; + A[left] = A[right]; + A[right] = temp; + left++; + right--; + } + else if (A[left] % 2 == 0) { + left++; + } + else if (A[right] % 2 != 0) { + right--; + } + } + return A; + } +}; +``` +# 6. 字符串 +[字符串](https://leetcode.com/problemset/all/?topicSlugs=string) +## 557. Reverse Words in a String III +```C++ +class Solution { +public: + string reverseWords(string s) { + string res = ""; + stack str; + for (int i = 0; i < s.length(); i++) { + if (s[i] != ' ') str.push(s[i]); + if (s[i] == ' ') { + while (!str.empty()) { + res += str.top(); + str.pop(); + } + res += ' '; + } + } + while (!str.empty()) { + res += str.top(); + str.pop(); + } + return res; + } +}; +``` + +```C++ +``` + +```C++ +``` +## 344. Reverse String +```C++ +class Solution { +public: + void reverseString(vector& s) { + if (s.size() == 0) return; + int begin = 0, end = s.size() - 1; + while (begin < end) { + char tmp = s[begin]; + s[begin] = s[end]; + s[end] = tmp; + begin++, end--; + } + } +}; +``` +## 151. Reverse Words in a String +用`vector tmp`存,时间复杂度太高 +```C++ +#include +#include +#include +using namespace std; +//" hello world! "; +class Solution { +public: + string reverseWords(string s) { + int nLength = s.length(); + if (nLength == 0) return s; + string res = ""; + int begin, end; + for (int i = nLength - 1; i >= 0;) { + while (i >= 0 && s[i] == ' ') i--; + end = i; + if (i < 0) break; + if (!res.empty()) res.push_back(' '); + while (i >= 0 && s[i] != ' ') i--; + begin = i + 1; + res.append(s.substr(begin, end - begin + 1)); + } + return res; + } +}; + +int main() +{ + string str = " hello world! "; + Solution s; + cout << s.reverseWords(str) << endl; + system("pause"); + return 0; +} + +``` + +## 709. To Lower Case +```C++ +class Solution { +public: + string toLowerCase(string str) { + int len = str.length(); + if (len == 0) return str; + transform(str.begin(), str.end(), str.begin(), ::tolower); + return str; + } +}; +``` + +## 917. Reverse Only Letters +对撞指针 +```C++ +class Solution { +public: + string reverseOnlyLetters(string S) { + int left = 0; + int right = S.size() - 1; + while (left < right) { + if (((S[left] >= 'A' && S[left] <= 'Z') || (S[left] >= 'a' && S[left] <= 'z')) && ((S[right] >= 'A' && S[right] <= 'Z') || (S[right] >= 'a' && S[right] <= 'z'))) { + char tmp = S[left]; + S[left] = S[right]; + S[right] = tmp; + left++; + right--; + } + else if(!((S[left] >= 'A' && S[left] <= 'Z') || (S[left] >= 'a' && S[left] <= 'z'))){ + left++; + } + else { + right--; + } + } + return S; + } +}; +``` + + +## 824. Goat Latin +```C++ +class Solution { +public: + string toGoatLatin(string S) { + vector res; + if (!S.length()) return S; + string tmp = ""; + for (int i = 0; i < S.length(); i++) { + if (S[i] != ' ') tmp += S[i]; + else { + res.push_back(tmp); + tmp = ""; + } + } + res.push_back(tmp); + + int j = 0; + for (auto i : res) + { + if (i[0] == 'a' || i[0] == 'e' || i[0] == 'i' || i[0] == 'o' || i[0] == 'u' || i[0] == 'A' || i[0] == 'E' || i[0] == 'I' || i[0] == 'O' || i[0] == 'U') + i += "ma"; + else { + string temp = ""; + if (i.length() > 1) { + temp = i.substr(1, i.length() - 1); + temp += i[0]; + i = temp; + } + i += "ma"; + } + res[j++] = i; + } + j = 0; + for (auto i : res) + { + int k = 0; + while (k++ < (j + 1)) { + i += "a"; + } + res[j++] = i; + } + string result = ""; + for (auto i : res) { + result += i; + result += " "; + } + S = result.substr(0, result.length() - 1); + return S; + } +}; +``` +## 13. Roman to Integer +```C++ +class Solution { +public: + int romanToInt(string s) { + int res = 0; + unordered_map m{ {'I',1} ,{'V',5} , {'X',10} , {'L',50} , {'C',100} , {'D',500} , {'M',1000} }; + for (int i = 0; i < s.size(); i++) { + int val = m[s[i]]; + if (i == s.size() - 1 || m[s[i + 1]] <= m[s[i]]) res += val; + else res -= val; + } + return res; + } +}; +``` +## 14. Longest Common Prefix +```C++ +bool cmp(const string& s1, const string& s2) { + return s1.size() < s2.size(); +} + +class Solution { +public: + string longestCommonPrefix(vector& strs) { + if (strs.size() == 0) return ""; + string res = ""; + sort(strs.begin(), strs.end(), cmp); + for (int j = 0; j < strs[strs.size() - 1].length(); j++) { + int i = 0; + while (i < (strs.size() - 1) && strs[i][j] == strs[i + 1][j]) i++; + if (i == strs.size() - 1) res += strs[i][j]; + else break; + } + return res; + } +}; +``` +## 20. Valid Parentheses +```C++ +class Solution { +public: + bool isValid(string s) { + if (s.length() == 0) return true; + stack res; + for (int i = 0; i < s.length(); i++) { + if (s[i] == '(') + res.push(')'); + else if (s[i] == '[') + res.push(']'); + else if (s[i] == '{') + res.push('}'); + else if (res.empty() || s[i] != res.top()) + return false; + else res.pop(); + } + return res.empty(); + } +}; +``` +## 415. Add Strings +```C++ +class Solution { +public: + string addStrings(string num1, string num2) { + int c = 0, len1 = num1.size() - 1, len2 = num2.size() - 1; + string res = ""; + while (c > 0 || len1 >= 0 || len2 >= 0) { + c += len1 >= 0 ? num1[len1--] - '0' : 0; + c += len2 >= 0 ? num2[len2--] - '0' : 0; + res = char(c % 10 + '0')+ res; + c /= 10; + } + return res; + } +}; +``` + +## +```C++ +``` + + +# 2. 哈希表 +[哈希表](https://leetcode.com/problemset/all/?topicSlugs=hash-table) +## 136. Single Number +```C++ +class Solution { +public: + int singleNumber(vector& nums) { + if (nums.size() <= 0) return 0; + int tmp = 0; + for (int i = 0; i < nums.size(); i++) { + tmp = tmp ^ nums[i]; + } + return tmp; + } +}; +``` + +# 3. 链表 +[链表](https://leetcode.com/problemset/all/?topicSlugs=linked-list) +## 21. Merge Two Sorted Lists +```C++ +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * ListNode *next; + * ListNode(int x) : val(x), next(NULL) {} + * }; + */ +class Solution { +public: + ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { + if (l1 == nullptr) return l2; + if (l2 == nullptr) return l1; + ListNode* lres = nullptr; + if (l1->val <= l2->val) { + lres = l1; + lres->next = mergeTwoLists(l1->next, l2); + } + else { + lres = l2; + lres->next = mergeTwoLists(l1, l2->next); + } + return lres; + } +}; + +``` +非递归方法 +```C++ +class Solution { +public: + ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { + if (l1 == nullptr) return l2; + if (l2 == nullptr) return l1; + ListNode head(0); + ListNode *lres = &head; + while (l1 != nullptr && l2 != nullptr) { + if (l1->val <= l2->val) { + lres->next = l1; + l1 = l1->next; + } + else { + lres->next = l2; + l2 = l2->next; + } + lres = lres->next; + } + if (l1 != nullptr) { + while (l1 != nullptr) { + lres->next = l1; + lres = lres->next; + l1 = l1->next; + } + } + else { + while (l2 != nullptr) { + lres->next = l2; + lres = lres->next; + l2 = l2->next; + } + } + return head.next; + } +}; +``` +## 83. Remove Duplicates from Sorted List +```C++ +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * ListNode *next; + * ListNode(int x) : val(x), next(NULL) {} + * }; + */ +class Solution { +public: + ListNode* deleteDuplicates(ListNode* head) { + if (head == nullptr || head->next == nullptr) return head; + ListNode* lres = head; + ListNode* tmp = head->next; + while (tmp != nullptr) { + if (lres->val == tmp->val) { + tmp = tmp->next; + } + else { + lres->next = tmp; + lres = tmp; + tmp = tmp->next; + } + } + lres->next = nullptr; + return head; + } +}; +``` +## 141. Linked List Cycle +```C++ +/** + * Definition for singly-linked list. + * struct ListNode { + * int val; + * ListNode *next; + * ListNode(int x) : val(x), next(NULL) {} + * }; + */ +class Solution { +public: + bool hasCycle(ListNode *head) { + if (head == nullptr || head->next == nullptr) return false; + ListNode* slow = head; + ListNode* fast = head; + while (fast && fast->next) { + slow = slow->next; + fast = fast->next->next; + if (slow == fast) return true; + } + return false; + } +}; +``` +## 160. Intersection of Two Linked Lists +```C++ +class Solution { +public: + ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) { + if (headA == nullptr || headB == nullptr) return nullptr; + ListNode *nodeA = headA, *nodeB = headB; + int lenA = 0, lenB = 0; + while (nodeA != nullptr) { + lenA++; + nodeA = nodeA->next; + } + while (nodeB != nullptr) { + lenB++; + nodeB = nodeB->next; + } + if (lenA <= lenB) { + for (int i = 0; i < lenB - lenA; i++) { + headB = headB->next; + } + } + else { + for (int i = 0; i < lenA - lenB; i++) { + headA = headA->next; + } + } + while (headA != headB && headA != nullptr && headB != nullptr) { + headA = headA->next; + headB = headB->next; + } + if (headA != nullptr && headB != nullptr) return headA; + else return nullptr ; + } +}; +``` +## 203. Remove Linked List Elements +```C++ +class Solution { +public: + ListNode* removeElements(ListNode* head, int val) { + if (head == nullptr) return head; + while (head->val == val) { + head = head->next; + if (head == nullptr) return head; + } + ListNode *ptr = head; + while (ptr->next!= nullptr) + { + if (ptr->next->val == val) { + ptr->next = ptr->next->next; + } + else { + ptr = ptr->next; + } + } + return head; + } +}; +``` +## 206. Reverse Linked List +```C++ +class Solution { +public: + ListNode* reverseList(ListNode* head) { + ListNode *res = nullptr; + ListNode *curNode = head; + ListNode *preNode = nullptr; + while (curNode != nullptr) { + ListNode *nextNode = curNode->next; + if (nextNode == nullptr) res = curNode; + curNode->next = preNode; + preNode = curNode; + curNode = nextNode; + } + return res; + } +}; +``` +## 234. Palindrome Linked List +```C++ +#include +#include +#include +using namespace std; + +struct ListNode +{ + int val; + ListNode *next; + ListNode(int x) :val(x), next(NULL) {} +}; + +class Solution { +public: + ListNode* reverse(ListNode *head) { + ListNode *res = nullptr; + ListNode *curNode = head; + ListNode *preNode = nullptr; + while (curNode != nullptr) { + ListNode *nextNode = curNode->next; + curNode->next = preNode; + if (nextNode == nullptr) res = curNode; + preNode = curNode; + curNode = nextNode; + } + return res; + } + bool isPalindrome(ListNode* head) { + if (head == nullptr) return true; + ListNode *ptr = head; + int len = 0; + while (ptr != nullptr) { + ptr = ptr->next; + len++; + } + if (len % 2 == 0) { + len /= 2; + } + else { + len = len / 2 + 1; + } + ptr = head; + while (len > 1) { + ptr = ptr->next; + len--; + } + ListNode *head2 = ptr->next; + ptr->next = nullptr; + head2 = reverse(head2); + while (head2 != nullptr) { + if (head2->val != head->val) return false; + head = head->next; + head2 = head2->next; + } + return true; + } +}; + +//尾插法建立单链表 +ListNode * Creat_LinkList_R() +{ + int x; + ListNode *head, *p, *tail; //tail是尾指针 + head = (ListNode*)malloc(sizeof(ListNode)); + if (head == NULL) + return head; + head->next = NULL; + tail = head; //一开始尾指针指向头指针的位置 + cout << "请输入要录入的数以0结束" << endl; + cin >> x; + head->val = x; + while ((cin >> x) && (x != 0)) + { + p = (ListNode*)malloc(sizeof(ListNode)); + if (p == NULL) + return head; + p->val = x; + tail->next = p; //将p插入到尾节点的后面 + tail = p; //修改尾节点的指向 + tail->next = NULL; //将尾节点的指针域修改为空 + } + return head; +} + +int main() { + Solution s; + ListNode *list1; + list1 = Creat_LinkList_R(); + cout << s.isPalindrome(list1) << endl; + system("pause"); + return 0; +} +``` +## 237. Delete Node in a Linked List +```C++ +class Solution { +public: + void deleteNode(ListNode* node) { + *node = *(node->next); + } +}; +``` + +```C++ +class Solution { +public: + void deleteNode(ListNode* node) { + ListNode *tmp = node->next; + *node = *tmp; + delete tmp; + } +}; +``` + +## 707. Design Linked List +```C++ +class MyLinkedList { +public: + class MyLinkedListNode { + public: + int val; + MyLinkedListNode* next = nullptr; + MyLinkedListNode* prev = nullptr; + MyLinkedListNode() :val{ 0 }, next{ nullptr }, prev{ nullptr } {}; + }; + + MyLinkedListNode* root = nullptr; + /** Initialize your data structure here. */ + MyLinkedList() { + MyLinkedListNode* root{}; + } + + /** Get the value of the index-th node in the linked list. If the index is invalid, return -1. */ + int get(int index) { + if (index < 0) + return -1; + MyLinkedListNode* tmp = root; + if (tmp == nullptr) return -1; + for (int i = 0; i < index; i++) { + if (tmp->next != nullptr) + tmp = tmp->next; + else + return -1; + } + return tmp->val; + } + + /** Add a node of value val before the first element of the linked list. After the insertion, the new node will be the first node of the linked list. */ + void addAtHead(int val) { + MyLinkedListNode* newhead = new MyLinkedListNode(); + newhead->val = val; + newhead->next = root; + if (root != nullptr) + root->prev = newhead; + root = newhead; + } + + /** Append a node of value val to the last element of the linked list. */ + void addAtTail(int val) { + MyLinkedListNode* tail = root; + while (tail != nullptr && tail->next != nullptr) + tail = tail->next; + MyLinkedListNode* newtail = new MyLinkedListNode(); + newtail->val = val; + if (tail != nullptr) + tail->next = newtail; + else + tail = newtail; + newtail->prev = tail; + } + + /** Add a node of value val before the index-th node in the linked list. If index equals to the length of linked list, the node will be appended to the end of linked list. If index is greater than the length, the node will not be inserted. */ + void addAtIndex(int index, int val) { + if (index <= 0) { + addAtHead(val); + return; + } + if (get(index - 1) != -1) { + MyLinkedListNode* previous = root; + MyLinkedListNode* newone = new MyLinkedListNode(); + newone->val = val; + for (int i = 0; i < index - 1; i++) + { + previous = previous->next; + } + newone->prev = previous; + newone->next = previous->next; + if (previous->next != nullptr) + previous->next->prev = newone; + previous->next = newone; + return; + } + else return; + } + + /** Delete the index-th node in the linked list, if the index is valid. */ + void deleteAtIndex(int index) { + if (index < 0) return; + if (get(index) != -1) { + MyLinkedListNode* tmp = root; + for (int i = 0; i < index; i++) { + tmp = tmp->next; + } + if (tmp->prev != nullptr) + tmp->prev->next = tmp->next; + if (tmp->next != nullptr) + tmp->next->prev = tmp->prev; + + if (index == 0) + root = tmp->next; + return; + } + else return; + } +}; + +int main() { + MyLinkedList linkedList; + linkedList.addAtHead(7); + linkedList.addAtHead(2); + linkedList.addAtHead(1); + linkedList.addAtIndex(3, 0); // linked list becomes 1->2->3 + linkedList.deleteAtIndex(2); // now the linked list is 1->3 + linkedList.addAtHead(6); + linkedList.addAtTail(4); + linkedList.get(4); // returns 2 + linkedList.addAtHead(4); + linkedList.addAtIndex(5, 0); // linked list becomes 1->2->3 + linkedList.addAtHead(6); + system("pause"); + return 0; +} +``` + +## 876. Middle of the Linked List +```C++ +#include +#include +#include +using namespace std; + +struct ListNode { + int val; + ListNode* next; + ListNode(int x) :val(x),next(nullptr) {} +}; + +class Solution { +public: + ListNode* middleNode(ListNode* head) { + if (head == nullptr) return head; + ListNode *ptr = head; + int cnt = 0; + while (ptr != nullptr) { + cnt++; + ptr = ptr->next; + } + if (cnt % 2 == 1) { + cnt = cnt / 2 + 1; + } + else { + cnt = cnt / 2 + 1; + } + ptr = head; + while (cnt > 1) { + ptr = ptr->next; + cnt--; + } + return ptr; + } +}; + +//尾插法建立单链表 +ListNode * Creat_LinkList_R() +{ + int x; + ListNode *head, *p, *tail; //tail是尾指针 + head = (ListNode*)malloc(sizeof(ListNode)); + if (head == NULL) + return head; + head->next = NULL; + tail = head; //一开始尾指针指向头指针的位置 + cout << "请输入要录入的数以0结束" << endl; + cin >> x; + head->val = x; + while ((cin >> x) && (x != 0)) + { + p = (ListNode*)malloc(sizeof(ListNode)); + if (p == NULL) + return head; + p->val = x; + tail->next = p; //将p插入到尾节点的后面 + tail = p; //修改尾节点的指向 + tail->next = NULL; //将尾节点的指针域修改为空 + } + return head; +} + +int main() { + Solution s; + ListNode *list1; + list1 = Creat_LinkList_R(); + ListNode *res; + res = s.middleNode(list1); + system("pause"); + return 0; +} +``` + +# 4. Math +[Math](https://leetcode.com/problemset/all/?topicSlugs=math) +## 942. DI String Match +```C +class Solution { +public: + vector diStringMatch(string S) { + int left = count(S.begin(), S.end(), 'D'), right = left; + vector res = { left }; + for (auto &c : S) { + int num = (c == 'I') ? ++right : --left; + res.push_back(num); + } + return res; + } +}; +``` +## 728. Self Dividing Numbers +```C++ +class Solution { +public: + vector selfDividingNumbers(int left, int right) { + vector res; + for (int i = left; i <= right; i++) { + int j = i; + for (; j > 0; j /= 10) { + if ((j % 10 == 0) || (i % (j % 10) != 0)) break; + } + if (j == 0) res.push_back(i); + } + return res; + } +}; +``` +## 67. Add Binary +```C++ +class Solution { +public: + string addBinary(string a, string b) { + string res = ""; + int carry = 0, index_a = a.length() - 1, index_b = b.length() - 1; + while (carry > 0 || index_a >= 0 || index_b >= 0) { + carry += index_a >= 0 ? a[index_a--] - '0' : 0; + carry += index_b >= 0 ? b[index_b--] - '0' : 0; + res = char(carry % 2 + '0') + res; + carry /= 2; + } + return res; + } +}; +``` +## 69. Sqrt(x) +```C++ +class Solution { +public: + int mySqrt(int x) { + long r = x; + while (r*r > x) { + r = (r + x / r) / 2; + } + return r; + } +}; +``` +## 204. Count Primes +```C++ +class Solution { +public: + int countPrimes(int n) { + vector notPrime(n); + int count = 0; + for (int i = 2; i < n; i++) { + if (notPrime[i] == false) { + count++; + for (int j = 2; i*j < n; j++) { + notPrime[i*j] = true; + } + } + } + return count; + } +}; +``` +## 231. Power of Two +```C++ +//位操作,如果一个数是2的幂,其2进制表示位置只有最高位1,则(n&(n - 1)) == 0 +class Solution { +public: + bool isPowerOfTwo(int n) { + if (n <= 0) return false; + return !(n&(n - 1)); + } +}; +``` +# 5. 对撞指针 +[Two Pointers](https://leetcode.com/problemset/all/?topicSlugs=two-pointers) +## 125. Valid Palindrome +```C++ +class Solution { +public: + bool isPalindrome(string s) { + if (s.length() == 0) return true; + int left = 0, right = s.length() - 1; + while (left < right) { + if (s[left] == s[right] || s[left] == tolower(s[right]) || s[left] == toupper(s[right])) { + left++; + right--; + } + else if (!(s[left] >= 'a' && s[left] <= 'z') && !(s[left] >= 'A' && s[left] <= 'Z') && !(s[left] >= '0' && s[left] <= '9')) { + left++; + } + else if (!(s[right] >= 'a' && s[right] <= 'z') && !(s[right] >= 'A' && s[right] <= 'Z') && !(s[right] >= '0' && s[right] <= '9')) { + right--; + } + else return false; + } + return true; + } +}; +``` +## 345. Reverse Vowels of a String +```C++ +class Solution { +public: + string reverseVowels(string s) { + if (s.length() == 0) return ""; + int left = 0, right = s.length() - 1; + while (left < right) { + if ((s[left] == 'a' || s[left] == 'e' || s[left] == 'i' || s[left] == 'o' || s[left] == 'u' || + s[left] == 'A' || s[left] == 'E' || s[left] == 'I' || s[left] == 'O' || s[left] == 'U') + && (s[right] == 'a' || s[right] == 'e' || s[right] == 'i' || s[right] == 'o' || s[right] == 'u' + || s[right] == 'A' || s[right] == 'E' || s[right] == 'I' || s[right] == 'O' || s[right] == 'U')) { + char tmp = s[left]; + s[left] = s[right]; + s[right] = tmp; + left++; + right--; + } + else if (!(s[left] == 'a' || s[left] == 'e' || s[left] == 'i' || s[left] == 'o' || s[left] == 'u' || + s[left] == 'A' || s[left] == 'E' || s[left] == 'I' || s[left] == 'O' || s[left] == 'U')) { + left++; + } + else if (!(s[right] == 'a' || s[right] == 'e' || s[right] == 'i' || s[right] == 'o' || s[right] == 'u' + || s[right] == 'A' || s[right] == 'E' || s[right] == 'I' || s[right] == 'O' || s[right] == 'U')) { + right--; + } + else { + right--; + left++; + } + } + return s; + } +}; +``` + +# 7. 二分搜索 +[二分搜索](https://leetcode.com/problemset/all/?topicSlugs=binary-search) + +## 278. First Bad Version +```C++ +bool isBadVersion(int version); + +class Solution { +public: + int firstBadVersion(int n) { + int start = 0, end = n; + while (end - start > 1) { + int mid = start + (end - start) / 2; + if (isBadVersion(mid)) end = mid; + else start = mid; + } + return end; + } +}; +``` +## 349. Intersection of Two Arrays +```C++ +//将第二个数组排序,二分查找第一个元素是否在第二个中 +class Solution { +public: + vector intersection(vector& nums1, vector& nums2) { + unordered_set res; + sort(nums2.begin(), nums2.end()); + for (auto i : nums1) { + if (binarySearch(nums2, i)) { + res.insert(i); + } + } + return vector(res.begin(), res.end()); + } + bool binarySearch(vector& nums, int target) { + int left = 0, right = nums.size() - 1; + while (left <= right) { + int mid = left + (right - left) / 2; + if (nums[mid] == target) return true; + else if (nums[mid] > target) right = mid - 1; + else left = mid + 1; + } + return false; + } +}; +``` +## 350. Intersection of Two Arrays II +先给两个数组排序,然后用两个指针分别指向两个数组的起始位置,如果两个指针指的数字相等,则存入结果中,两个指针均自增1,如果第一个指针指的数字大,则第二个指针自增1,反之亦然。 +```C++ +class Solution { +public: + vector intersect(vector& nums1, vector& nums2) { + vector res; + if (nums1.size() == 0 || nums2.size() == 0) return res; + sort(nums1.begin(), nums1.end()); + sort(nums2.begin(), nums2.end()); + int i = 0, j = 0; + while (i < nums1.size() && j < nums2.size()) { + if (nums1[i] == nums2[j]) { + res.push_back(nums1[i]); + i++; + j++; + } + else if (nums1[i] < nums2[j]) { + i++; + } + else { + j++; + } + } + return res; + } +}; +``` + +# 8. 分治 +[分治](https://leetcode.com/problemset/all/?topicSlugs=divide-and-conquer) + + +```C++ + +``` +# 9. 动态规划 +[动态规划](https://leetcode.com/problemset/all/?topicSlugs=dynamic-programming) +## 70. Climbing Stairs +```C++ +class Solution { +public: + int climbStairs(int n) { + if (n == 0) return 0; + if (n == 1) return 1; + if (n == 2) return 2; + vector res(n, -1); + res[0] = 1; + res[1] = 2; + int num = dp(res, n - 1); + return num; + } + int dp(vector &res, int n) { + if (res[n] == -1) + res[n] = dp(res, n - 1) + dp(res, n - 2); + return res[n]; + } +}; +``` +## 64. Minimum Path Sum +```C++ +class Solution { +public: + int minPathSum(vector>& grid) { + int m = grid.size(); + int n = grid[0].size(); + vector> sum(m, vector(n, grid[0][0])); + for (int i = 1; i < m; i++) + sum[i][0] = sum[i - 1][0] + grid[i][0]; + for (int j = 1; j < n; j++) + sum[0][j] = sum[0][j - 1] + grid[0][j]; + for (int i = 1; i < m; i++) + for (int j = 1; j < n; j++) + sum[i][j] = min(sum[i][j - 1], sum[i - 1][j]) + grid[i][j]; + return sum[m - 1][n - 1]; + } +}; +``` +[参考](https://leetcode.com/problems/minimum-path-sum/discuss/23457/C%2B%2B-DP) + +# 10. 回溯 +[回溯](https://leetcode.com/problemset/all/?topicSlugs=backtracking) +## 784. Letter Case Permutation +```C++ +class Solution { +public: + vector letterCasePermutation(string S) { + vector res; + trackback(S, 0, res); + return res; + + } + void trackback(string &s, int i, vector &res) { + if (i == s.size()) { + res.push_back(s); + return; + } + char c = s[i]; + s[i] = islower(c) ? toupper(c) : tolower(c); + trackback(s, i + 1, res); + if (isalpha(c)) { + s[i] = c; + trackback(s, i + 1, res); + } + } +}; +``` +# 11. 栈 +[栈](https://leetcode.com/problemset/all/?topicSlugs=stack) +## 1021. Remove Outermost Parentheses +```C++ +class Solution { +public: + string removeOuterParentheses(string S) { + string res = ""; + int opened = 0; + for (auto c : S) { + if (c == '(' && opened++ > 0) res += c; + if (c == ')' && opened-- > 1) res += c; + } + return res; + } +}; +``` +## 1047. Remove All Adjacent Duplicates In String +```C++ +class Solution { +public: + string removeDuplicates(string S) { + if (!S.length()) return S; + string results = ""; + stack res; + res.push(S[0]); + for (int i = 1; i < S.length(); i++) { + if (res.empty()) res.push(S[i]); + else if (S[i] == res.top()) res.pop(); + else res.push(S[i]); + } + while (!res.empty()) { + results += res.top(); + res.pop(); + } + reverse(results.begin(), results.end()); + return results; + } +}; +``` +# 12. 堆 + +# 13. 贪心算法 +[贪心](https://leetcode.com/problemset/all/?topicSlugs=greedy) +## 455. Assign Cookies +```C++ +class Solution { +public: + int findContentChildren(vector& g, vector& s) { + if (!g.size() || !s.size()) return 0; + sort(g.begin(), g.end()); + sort(s.begin(), s.end()); + vector::iterator it = s.begin(); + int res = 0; + int i = 0; + while (i < g.size()) { + if (it == s.end()) break; + if (g[i] <= *it) { + res++; + it = s.erase(it); + i++; + } + else { + it = s.erase(it); + } + } + //for (int i = 0; i < g.size(); i++) { + + /*else { + int sum = *it; + it = s.erase(it); + while (it != s.end() && g[i] > sum) { + sum += *it; + it = s.erase(it); + } + if (g[i] <= sum) res++; + }*/ + //} + return res; + } +}; +``` +# 14. 排序 +[排序](https://leetcode.com/problemset/all/?topicSlugs=sort) +# 15. 位操作 +[位操作](https://leetcode.com/problemset/all/?topicSlugs=bit-manipulation) + +[总结](https://leetcode.com/problems/sum-of-two-integers/discuss/84278/A-summary%3A-how-to-use-bit-manipulation-to-solve-problems-easily-and-efficiently) +## 190. Reverse Bits +```C++ +//运算符&优先级低于<<高于= +class Solution { +public: + uint32_t reverseBits(uint32_t n) { + n = (n << 16) | (n >> 16); + n = (n & 0x00ff00ff) << 8 | (n & 0xff00ff00) >> 8; + n = (n & 0x0f0f0f0f) << 4 | (n & 0xf0f0f0f0) >> 4; + n = (n & 0x33333333) << 2 | (n & 0xcccccccc) >> 2; + n = (n & 0x55555555) << 1 | (n & 0xaaaaaaaa) >> 1; + return n; + } +}; +``` +## 191. Number of 1 Bits +```C++ +class Solution { +public: + int hammingWeight(uint32_t n) { + int count = 0; + while (n) { + count++; + n = n & (n - 1); + } + return count; + } +}; +``` +## 268. Missing Number +```C++ +class Solution { +public: + int missingNumber(vector& nums) { + if (nums.size() == 0) return -1; + sort(nums.begin(), nums.end()); + for (int i = 0; i < nums.size(); i++) { + if (nums[i] != i) return i; + } + return nums.size(); + } +}; +``` +## 389. Find the Difference +```C++ +class Solution { +public: + char findTheDifference(string s, string t) { + sort(s.begin(), s.end()); + sort(t.begin(), t.end()); + for (int i = 0; i < s.size(); i++) { + if (t[i] != s[i]) return t[i]; + } + return t[t.size()-1]; + } +}; +``` +## 461. Hamming Distance +```C++ +class Solution { +public: + int hammingDistance(int x, int y) { + return numberOf1(x^y); + } + int numberOf1(int n) { + int count = 0; + while (n) { + count++; + n = n & (n - 1); + } + return count; + } +}; +``` + +```C++ + +``` +## 338. Counting Bits +```C++ +class Solution { +public: + vector countBits(int num) { + vector res; + for(int i = 0;i <= num; i++){ + res.push_back(NumberOf1(i)); + } + return res; + } + + int NumberOf1(int num){ + int count = 0; + while(num){ + count++; + num = num & (num - 1); + } + return count; + } +}; +``` +## 342. Power of Four +```C++ +//(num & num - 1) == 0只有最高位为1,0x55555555保证只有奇数为1的情况下才能为4的幂,负责可能是2的幂 +class Solution { +public: + bool isPowerOfFour(int num) { + return num > 0 && (num & num-1) == 0 && (num & 0x55555555) != 0; + } +}; + +``` + +```C++ +class Solution { +public: + int getSum(int a, int b) { + if (b == 0) return a; + /*int sum = a; + while (b != 0) { + sum = a ^ b; + b = (a&b) << 1;//进位 + a = sum; + } + return sum;*/ + //return getSum(a^b, (a&b) << 1); + if (b == 0) return a; + return getSum(a^b, ((a & b) & 0xffffffff) << 1);// limited to 32 bits,解决负数溢出问题 + } +}; +``` +# 16. 树 +[树](https://leetcode.com/problemset/all/?topicSlugs=tree) +## 1022. Sum of Root To Leaf Binary Numbers +```C++ +class Solution { +public: + int sumRootToLeaf(TreeNode* root, int val = 0) { + if (root == nullptr) return 0; + val = (val * 2) + root->val; + return root->left == root->right ? val : sumRootToLeaf(root->left, val) + sumRootToLeaf(root->right, val); + } +}; +``` +## 637. Average of Levels in Binary Tree +```C++ +class Solution { +public: + vector averageOfLevels(TreeNode* root) { + vector res; + if (root == nullptr) return res; + queue tree; + tree.push(root); + while (!tree.empty()) { + long temp = 0; + int s = tree.size(); + for (int i = 0; i < s; i++) { + TreeNode* node = tree.front(); + tree.pop(); + if (node->left) tree.push(node->left); + if (node->right) tree.push(node->right); + temp += node->val; + } + res.push_back((double)temp / s); + temp = 0; + } + return res; + } +}; +``` +# 17. 深度优先搜索 +[深度优先搜索](https://leetcode.com/problemset/all/?topicSlugs=depth-first-search) +## 257. Binary Tree Paths +```C++ +class Solution { +public: + vector binaryTreePaths(TreeNode* root) { + vector res; + if (root == nullptr) return res; + stack s; + stack path; + s.push(root); + path.push(to_string(root->val)); + while (!s.empty()) { + TreeNode* node = s.top(); + s.pop(); + string pathtmp = path.top(); + path.pop(); + + if (node->left == nullptr && node->right == nullptr) { + res.push_back(pathtmp); + continue; + } + + if (node->left) { + s.push(node->left); + path.push(pathtmp + "->" + to_string(node->left->val)); + } + + if (node->right) { + s.push(node->right); + path.push(pathtmp + "->" + to_string(node->right->val)); + } + } + } +}; +``` +# 18. 广度优先搜索 +[广度优先搜索](https://leetcode.com/problemset/all/?topicSlugs=breadth-first-search) +## 993. Cousins in Binary Tree +```C++ +class Solution { +public: + bool isCousins(TreeNode* root, int x, int y) { + if (root == nullptr) return false; + queue tree; + tree.push(root); + while (!tree.empty()) { + int size = tree.size(); + bool existX = false; + bool existY = false; + for (int i = 0; i < size; i++) { + TreeNode* node = tree.front(); + tree.pop(); + if (node->val == x) + existX = true; + if (node->val == y) + existY = true; + if (node->left && node->right) { + if (node->left->val == x && node->right->val == y) + return false; + if (node->right->val == x && node->left->val == y) + return false; + } + if (node->left) tree.push(node->left); + if (node->right) tree.push(node->right); + } + if (existX && existY) return true; + } + return false; + } +}; +``` +## 690. Employee Importance +本地测试通过,但是AC不了,不知道原因在哪? +```C++ +class Solution { +public: + int getImportance(vector employees, int id) { + int res = 0; + int size = employees.size(); + if (size == 0) return 0; + sort(employees.begin(), employees.end()); + queue sub; + sub.push(id); + for (auto i : employees) { + int nowid = sub.front(); + if (i->id == nowid) { + res += i->importance; + if (i->subordinates.size()) { + for (auto j : i->subordinates) + sub.push(j); + } + sub.pop(); + } + } + return res; + } +}; +``` +估计方法不对,加了cmp也不对 +```C++ +bool cmp(Employee* a, Employee* b) { + return a->id < b->id; +} + +class Solution { +public: + int getImportance(vector employees, int id) { + int res = 0; + int size = employees.size(); + if (size == 0) return 0; + sort(employees.begin(), employees.end(),cmp); + queue sub; + sub.push(id); + for (auto i : employees) { + int nowid = sub.front(); + if (i->id == nowid) { + res += i->importance; + if (i->subordinates.size()) { + for (auto j : i->subordinates) + sub.push(j); + } + sub.pop(); + } + } + return res; + } +}; +``` +AC版本 +```C++ +class Solution { +public: + int getImportance(vector employees, int id) { + unordered_map employee; + + for (const auto em : employees) { + employee[em->id] = em; + } + return computeImportance(employee, id); + } + int computeImportance(unordered_map& employee, const int id) { + int sum = employee[id]->importance; + for (const auto em : employee[id]->subordinates) { + sum += computeImportance(employee, em); + } + return sum; + } +}; +``` +# 19. 并查集UnionFind +[并查集](https://leetcode.com/problemset/all/?topicSlugs=union-find) +# 20. 图 +[图](https://leetcode.com/problemset/all/?topicSlugs=graph) +# 21. 设计题Design +[Design](https://leetcode.com/problemset/all/?topicSlugs=design) +# 22. 拓扑排序 +[拓扑排序](https://leetcode.com/problemset/all/?topicSlugs=topological-sort) +# 23. 字典树Trie +[字典树](https://leetcode.com/problemset/all/?topicSlugs=trie) +# 24. 树状数组BinaryIndexedTree +[树状数组](https://leetcode.com/problemset/all/?topicSlugs=binary-indexed-tree) +# 25. 线段树SegmentTree +[线段树](https://leetcode.com/problemset/all/?topicSlugs=segment-tree) +# 26. 二叉搜索树 +[二叉搜索树](https://leetcode.com/problemset/all/?topicSlugs=binary-search-tree) +# 27. 递归 +[递归](https://leetcode.com/problemset/all/?topicSlugs=recursion) +# 28. 脑筋急转弯Brainteaser +[Brainteaser](https://leetcode.com/problemset/all/?topicSlugs=brainteaser) +# 29. Memoization +[Memoization](https://leetcode.com/problemset/all/?topicSlugs=memoization) +[参考](https://blog.csdn.net/feeltouch/article/details/45072725) +是一种将`函数返回值缓存起来`的方法,Memoization 原理非常简单,就是把函数的每次执行结果都放入一个键值对或者数组中,在接下来的执行中,在键值对中查找是否已经有相应执行过的值,如果有,直接返回该值,没有执行函数体的求值部分。很明显找值尤其是在键值对中找值,比执行函数快多了。[参考](https://blog.csdn.net/feeltouch/article/details/45072725) + +# 30. 队列 +[队列](https://leetcode.com/problemset/all/?topicSlugs=queue) +# 31. 极大极小值 +[Minimax](https://leetcode.com/problemset/all/?topicSlugs=minimax) +# 32. 蓄水池抽样问题ReservoirSampling +[蓄水池抽样问题](https://leetcode.com/problemset/all/?topicSlugs=reservoir-sampling) +# 33. OrderedMap +[OrderedMap](https://leetcode.com/problemset/all/?topicSlugs=ordered-map) +# 34. 几何题Geometry +[几何](https://leetcode.com/problemset/all/?topicSlugs=geometry) +# 35. Random +[Random](https://leetcode.com/problemset/all/?topicSlugs=random) +# 36. 拒绝采样RejectionSampling +[拒绝采样](https://leetcode.com/problemset/all/?topicSlugs=rejection-sampling) +# 37. 滑动窗口 +[滑动窗口](https://leetcode.com/problemset/all/?topicSlugs=sliding-window) +# 38. LineSweep +[扫描线算法](https://leetcode.com/problemset/all/?topicSlugs=line-sweep) + +# 39. 未分类 +## 771. Jewels and Stones +```C++ +class Solution { +public: + int numJewelsInStones(string J, string S) { + int num = 0; + for (int i = 0; i < J.size(); i++) { + for (int j = 0; j < S.size(); j++) { + if (J[i] == S[j]) num++; + } + } + return num; + } +}; +``` +## 938. Range Sum of BST +```C++ +class Solution { +public: + int rangeSumBST(TreeNode* root, int L, int R) { + if (root == nullptr) return 0; + int sum = 0; + if (root->val > R) { sum += rangeSumBST(root->left, L, R); } + if (root->val < L) { sum += rangeSumBST(root->right, L, R); } + if (root->val >= L && root->val <= R) { sum += root->val + rangeSumBST(root->left, L, R) + rangeSumBST(root->right, L, R); } + return sum; + } +}; +``` + +## 595. Big Countries +```SQL +# Write your MySQL query statement below +SELECT name, population, area +FROM World +WHERE area > 3000000 + +UNION + +SELECT name, population, area +FROM World +WHERE population > 25000000 +``` +## 804. Unique Morse Code Words +```C++ +class Solution { +public: + int uniqueMorseRepresentations(vector& words) { + if (words.size() == 0) return 0; + vector table = { ".-","-...","-.-.","-..",".","..-.", + "--.","....","..",".---","-.-",".-..","--","-.","---",".--.", + "--.-",".-.","...","-","..-","...-",".--","-..-","-.--","--.." }; + for (int j = 0; j < words.size(); j++) { + string s = ""; + for (int i = 0; i < words[j].size(); i++) { + s += table[words[j][i] - 'a']; + } + words[j] = s; + } + sort(words.begin(), words.end()); + int res = 1; + for (int i = 0; i < words.size() - 1; i++) { + if (words[i] != words[i + 1]) res++; + } + return res; + } +}; +``` +## 961. N-Repeated Element in Size 2N Array +```C++ +class Solution { +public: + int repeatedNTimes(vector& A) { + int i = 0, j = 0, n = A.size(); + while (i == j || A[i] != A[j]) + i = rand() % n, j = rand() % n; + return A[i]; + } +}; + +``` +## 657. Robot Return to Origin +```C++ +class Solution { +public: + bool judgeCircle(string moves) { + if (count(moves.begin(), moves.end(), 'L') == count(moves.begin(), moves.end(), 'R') && count(moves.begin(), moves.end(), 'U') == count(moves.begin(), moves.end(), 'D')) + return true; + else + return false; + } +}; +``` +## 1078. Occurrences After Bigram +```C++ +class Solution { +public: + vector findOcurrences(string text, string first, string second) { + vector tmp,res; + string str = ""; + for (int i = 0; i < text.length(); i++) { + if (text[i] != ' ') str += text[i]; + else { + tmp.push_back(str); + str = ""; + } + } + tmp.push_back(str); + for (int i = 0; i < tmp.size() - 2; i++) { + if (tmp[i] == first && tmp[i + 1] == second) res.push_back(tmp[i + 2]); + } + return res; + } +}; +``` +## 852. Peak Index in a Mountain Array +```C++ +class Solution { +public: + int peakIndexInMountainArray(vector& A) { + int i = 0; + for (; i < A.size() - 1; i++) { + if (A[i] > A[i + 1]) break; + } + return i; + } +}; +``` +## 933. Number of Recent Calls +```C++ +class RecentCounter { +public: + queue q; + RecentCounter() { + + } + + int ping(int t) { + q.push(t); + while (q.front() < t - 3000) + q.pop(); + return q.size(); + } +}; +``` +## 944. Delete Columns to Make Sorted +```C++ +class Solution { +public: + int minDeletionSize(vector& A) { + if (A.size() == 0) return 0; + vector inc(A[0].size(), 'a'); + vector flag(A[0].size(), true); + for (auto s : A) { + for (int i = 0; i < s.size(); i++) { + if (s[i] >= inc[i]) inc[i] = s[i]; + else flag[i] = false; + } + } + return count(flag.begin(),flag.end(),false); + } +}; +``` +## 627. Swap Salary +```SQL +# Write your MySQL query statement below +update salary set sex= CHAR(ASCII('f') + ASCII('m') - ASCII(sex)); +``` +## 700. Search in a Binary Search Tree +```C++ +class Solution { +public: + TreeNode* searchBST(TreeNode* root, int val) { + if (root == nullptr) return nullptr; + if (root->val == val) return root; + else if (root->val > val) return searchBST(root->left, val); + else return searchBST(root->right, val); + } +}; + +``` +## 590. N-ary Tree Postorder Traversal +```C++ +class Solution { +public: + vector postorder(Node* root) { + if (root == nullptr) return {}; + vector res; + stack tmp; + tmp.push(root); + while (!tmp.empty()) { + Node* node = tmp.top(); + tmp.pop(); + for (int i = 0; i < node->children.size(); i++) tmp.push(node->children[i]); + res.push_back(node->val); + } + reverse(res.begin(), res.end()); + return res; + } +}; +``` +## 589. N-ary Tree Preorder Traversal +```C++ +class Solution { +public: + vector preorder(Node* root) { + if (root == nullptr) return {}; + vector res; + dfs(root, res); + return res; + } + + void dfs(Node* root, vector& res) { + if (root == nullptr) return; + res.push_back(root->val); + for (auto i : root->children) + dfs(i, res); + } +}; +``` +## 965. Univalued Binary Tree +```C++ +class Solution { +public: + bool isUnivalTree(TreeNode* root) { + if (root == nullptr) return true; + int tmp = root->val; + if (root->right != nullptr && root->left != nullptr) + return (tmp == root->left->val) && (tmp == root->right->val) && isUnivalTree(root->left) && isUnivalTree(root->right); + else if (root->right != nullptr && root->left == nullptr) + return (tmp == root->right->val) && isUnivalTree(root->right); + else if (root->right == nullptr && root->left != nullptr) + return (tmp == root->left->val) && isUnivalTree(root->left); + else return true; + return false; + } +}; +``` +## 559. Maximum Depth of N-ary Tree +```C++ +class Solution { +public: + int maxDepth(Node* root) { + if (root == nullptr) return 0; + int res = 1; + for (auto i : root->children) + res = max(res, maxDepth(i) + 1); + return res; + } +}; + +``` +## 788. Rotated Digits +```C++ +class Solution { +public: + int rotatedDigits(int N) { + int res = 0; + for (int i = 0; i <= N; i++) { + string s = to_string(i); + int j = 0; + string str = s; + for (; j < s.size(); j++) { + if(s[j] == '3' || s[j] == '4' || s[j] == '7') break; + if (s[j] == '2') s[j] = '5'; + else if (s[j] == '5') s[j] = '2'; + else if (s[j] == '6') s[j] = '9'; + else if (s[j] == '9') s[j] = '6'; + else {} + } + if (j == s.size() && str != s) res++; + } + return res; + } +}; +``` \ No newline at end of file diff --git "a/\345\210\267\351\242\230/LeetCode\351\242\230\350\247\243.md" "b/\345\210\267\351\242\230/LeetCode\351\242\230\350\247\243.md" new file mode 100644 index 0000000..9ec5560 --- /dev/null +++ "b/\345\210\267\351\242\230/LeetCode\351\242\230\350\247\243.md" @@ -0,0 +1,699 @@ + +* [1. TwoSum](#1-TwoSum) +* [2. AddTwoNumbers](#2-AddTwoNumbers) +* [3. LongestSubstringWithoutRepeatingCharacters](#3-LongestSubstringWithoutRepeatingCharacters) +* [4. MedianofTwoSortedArrays](#4-MedianofTwoSortedArrays) +* [5. LongestPalindromicSubstring](#5-LongestPalindromicSubstring) +* [6. ZigZagConversion](#6-ZigZagConversion) +* [7. ReverseInteger](#7-ReverseInteger) +* [8. StringtoInteger](#8-StringtoInteger) +* [9. PalindromeNumber](#9-PalindromeNumber) +* [10. RegularExpressionMatching](#10-RegularExpressionMatching) +* [11. ContainerWithMostWater](#11-ContainerWithMostWater) +* [104. MaximumDepthofBinaryTree](#104-MaximumDepthofBinaryTree) +* [110. BalancedBinaryTree](#110-BalancedBinaryTree) +* [112. PathSum](#112-PathSum) +* [437. PathSumIII](#437-PathSumIII) +* [617. MergeTwoBinaryTrees](#617-MergeTwoBinaryTrees) +* [572. SubtreeofAnotherTree](#572-SubtreeofAnotherTree) +* [101. SymmetricTree](#101-SymmetricTree) +* [144. BinaryTreePreorderTraversal](#144-BinaryTreePreorderTraversal) +* [145. BinaryTreePostorderTraversal](#145-BinaryTreePostorderTraversal) +* [94. BinaryTreeInorderTraversal](#94-BinaryTreeInorderTraversal) + + +# 1. TwoSum + +给定一个整数数组,返回两个数之和等于target的数组索引。 + +我的思路:夹逼准则,先排序,然后首位寻找是否等于target的数。但是这样排序改变了原来数组的下标,先找到这两个数,然后返回下标。 + +最简单的方法是穷举搜索,一个是x,另外一个是target-x;复杂度O(n^2) + +优化方法:两次hash表操作,对在一维数组中查找target-x优化。 + +进一步优化:一次hash表操作,边建立hash表边返回。 + +```C++ +#include +#include +#include +using namespace std; + +class Solution { +public: + vector twoSum(vector& nums, int target) { + vector res; + int size = nums.size(); + if (size <= 1) return res; + vector nums_sort(nums); + sort(nums_sort.begin(), nums_sort.end()); + int i = 0, j = size - 1; + while (i <= size - 1 && j >= i) { + if (nums_sort[i] + nums_sort[j] == target) { + break; + } + else if (nums_sort[i] + nums_sort[j] > target) { + j--; + } + else { + i++; + } + } + + for (int k = 0; k < size; k++) { + if (nums[k] == nums_sort[i] || nums[k] == nums_sort[j]) + res.push_back(k); + } + return res; + } +}; +``` + +# 2. AddTwoNumbers +两个非负整数的非空链表,整数数字是逆序存储的,每个节点存有单一的数字,将两个数相加然后将结果返回为一个链表。 + +```C++ +struct ListNode { + int val; + ListNode *next; + ListNode(int x) : val(x), next(NULL) {} +}; + +class Solution { +public: + ListNode * addTwoNumbers(ListNode* l1, ListNode* l2) { + ListNode *res = new ListNode(0); + ListNode *p = l1, *q = l2, *reshead = res; + int carry = 0; + while (p != nullptr || q != nullptr) { + int x = (p != nullptr) ? p->val : 0; + int y = (q != nullptr) ? q->val : 0; + int sum = x + y + carry; + carry = sum / 10; + res->next = new ListNode(sum % 10); + res = res->next; + if (p != nullptr) p = p->next; + if (q != nullptr) q = q->next; + } + if (carry > 0) { + res->next = new ListNode(carry); + } + return reshead->next; + } +}; +``` + +# 3. LongestSubstringWithoutRepeatingCharacters +给定一个字符串,找到无重复字符的最长字串。 + +穷举搜索的方法:定义一个函数,判断字串是否含有重复字符,如果有重复字符`false`,问题更新为返回无重复的字串的最大长度。 + +```C++ +class Solution { +public: + int lengthOfLongestSubstring(string s) { + int res = 0; + int length = s.length(); + for (int i = 0; i < length; i++) + for (int j = i + 1; j <= length; j++) + if (allUnique(s, i, j)) res = max(res, j - i); + return res; + } + + bool allUnique(string s, int start, int end) { + set substr; + for (int i = start; i < end; i++) { + char ch = s[i]; + if (substr.find(ch) != substr.end()) return false; + substr.insert(ch); + } + return true; + } +}; +``` +std::set [用法](https://www.cnblogs.com/zyxStar/p/4542835.html) + +用穷举搜索的方法,时间复杂度较高,不通过。 + +优化方法:滑动窗口,滑动窗口是在数组和字符串中常用的一个抽象概念。 + +```C++ +class Solution { +public: + int lengthOfLongestSubstring(string s) { + vector substr; + int res = 0; + for (int i = 0; i < s.length(); i++) { + auto it = find(substr.begin(), substr.end(), s[i]); + if (it != substr.end()) {//找到了 + if (res < substr.size()) + res = substr.size(); + it++; + substr.erase(substr.begin(), it); + } + substr.push_back(s[i]); + } + + if (res < substr.size()) + res = substr.size(); + + return res; + } +}; +``` + +# 4. MedianofTwoSortedArrays +求两个排序数组的中位数,两个递增数组元素个数分别是m,n,求两个数组合并后的中位数。 + +思路:递归方法,在统计学中,中位数将一个集合分成相同长度的两个部分,其中一部分的数总是大于另外一部分的数。将两个集合进行划分,如果能够保证以下两点: +1. 左右两边的长度相等; +2. 左边的最大的数小于或者等于右边最小的数; +需满足: +1. `i + j = m - i + n - j` or `m - i + n - j + 1`,如果 `n` 大于等于 `m`,则设置 `i = 0 ~ m`, `j = (m + n + 1)/2 - i`; +2. `B[j-1]` 小于等于 `A[i]` && `A[i-1]` 小于等于 `B[j]`。 + +Searching i in [0, m], to find an object i such that: +``` +(j = 0 or i = m or B[j−1] <= A[i] and +(i = 0 or j = n or A[i-1] <= B[j], where j = (m + n + 1)/2 - i +``` +``` +1. (j=0 or i = m or B[j−1] <= A[i]) and +(i = 0 or j = n or A[i-1] <= B[j]) +Means i is perfect, we can stop searching. +2. i< m and B[j−1]>A[i] +Means i is too small, we must increase it. +3. i > 0 and A[i−1]>B[j] +Means i is too big, we must decrease it. +``` +when i is found: +``` +max(A[i−1],B[j−1]), when m + n is odd +(max(A[i−1],B[j−1])+min(A[i],B[j]))/2, when m + n is even +``` + +```C++ +//二分搜索 +class Solution { +public: + double findMedianSortedArrays(vector& nums1, vector& nums2) { + int m = nums1.size(), n = nums2.size(); + if (m > n) { + nums1.swap(nums2); + int tmp; tmp = m; m = n; n = tmp; + } + int imin = 0, imax = m, halflen = (m + n + 1) / 2; + while (imin <= imax) { + int i = (imin + imax) / 2; + int j = halflen - i; + if (i < imax && nums2[j - 1] > nums1[i]) {//i is too small + imin = i + 1; + } + else if (i > imin && nums1[i - 1] > nums2[j]) {//i is too big + imax = i - 1; + } + else { + int maxleft = 0; + if (i == 0) { maxleft = nums2[j - 1]; } + else if (j == 0) { maxleft = nums1[i - 1]; } + else { maxleft = max(nums1[i - 1], nums2[j - 1]); } + if ((m + n) % 2 == 1) { return maxleft; } + + int minright = 0; + if (i == m) { minright = nums2[j]; } + else if (j == n) { minright = nums1[i]; } + else { minright = min(nums1[i], nums2[j]); } + + return (maxleft + minright) / 2.0; + } + } + return 0.0; + } +}; +``` + +# 5. LongestPalindromicSubstring +给定一个字符串s,找到s中的最长回文子串,假定s的最长长度是1000。回文是一个在两个方向上读相同的字符串。 + +如何使用一个已知的回文字符串来计算一个更长的回文字符串;如果已知`aba`是一个回文字符串,那么判断`xabax`和`xabay`是否是回文字符串;如果采用穷举搜索的方法,开始-结束对O(n^2)的时间复杂度。 + +减少时间复杂度主要避免验证回文时的重新计算。 + +动态规划算法: +```C++ +class Solution { +public: + string longestPalindrome(string s) { + if (s.length() < 1) return ""; + int start = 0, end = 0; + for (int i = 0; i < s.length(); i++) { + int len1 = centerDistance(s, i, i); + int len2 = centerDistance(s, i, i + 1); + int len = max(len1, len2); + if (len > end - start + 1) { + start = i - (len - 1) / 2; + end = i + len/ 2; + } + } + return s.substr(start, end - start + 1);//c++substr第二个参数代表的是个数 + } + + int centerDistance(string s, int start, int end) { + while (start >= 0 && end < s.length() && s[start] == s[end]) { + start--; + end++; + } + return end - start - 1; + } +}; +``` + +# 6. ZigZagConversion + +* 假设第0行有k个字符,位于第一行字符的索引`k*(2*rowNumbers - 2)` +* 第rowNumbers - 1行字符的索引`k*(2*rowNumbers - 2) + (rowNumbers - 1)` +* 第i行字符的索引`k*(2*rowNumbers - 2) + i`和`(k + 1)*(2*rowNumbers - 2) - i` + +```C++ +class Solution { +public: + string convert(string s, int numRows) { + int len = s.length(); + if (len == 0) return ""; + if (numRows == 1) return s; + string res; + int cycLen = 2 * numRows - 2; + + for (int i = 0; i < numRows; i++) { + for (int j = 0; i + j < len; j += cycLen) { + res += s[j + i]; + if (i != 0 && i != numRows - 1 && j + cycLen - i < len) { + res += s[j + cycLen - i]; + } + } + } + return res; + + } +}; +``` + +# 7. ReverseInteger +给定32bit的有符号整数,翻转整数的数字。 +```C++ +class Solution { +public: + int reverse(int x) {//考虑溢出问题, + int res = 0; + while (x != 0) { + int pop = x % 10; + x /= 10; + if (res > INT_MAX/10 || (res == INT_MAX / 10 && pop > 7)) return 0; + if (res < INT_MIN/10 || (res == INT_MIN / 10 && pop < -8)) return 0; + res = res * 10 + pop; + } + return res; + } +}; +``` + +# 8. StringtoInteger + +实现从字符串转化为整数的`atoi`功能。 + +函数丢弃空格直到找到第一个非空字符,如果字符串的第一个字符是非有效的整数,或者`str`是空字符串或仅仅包含空格,不执行转换。 + +`INT_MAX(2^31 - 1)` 和 `INT_MIN(-2^31)`。定义`res`为`long long`类型,要不然`res`是最大负数的时候,计算`res * 10`的时候会溢出。 +```C++ +class Solution { +public: + int myAtoi(string str) { + int len = str.length(); + if (str.length() == 0) return 0; + int i = 0; + while (str[i] == ' ') i++; + int flag = 1; + if (str[i] == '+') { + i++; + } + else if (str[i] == '-') { + flag = -1; + i++; + } + long long res = 0;//***longlong + + while (str[i] - '0' >= 0 && str[i] - '0' <= 9) { + res = res * 10 + str[i] - '0'; + if (res > INT_MAX) { + if (flag == 1) return INT_MAX; + else return INT_MIN; + } + i++; + } + + return flag * res; + } +}; +``` + +# 9. PalindromeNumber +回文数 + +确定一个整数是不是回文数,一个数是回文数当且仅当它从前往后读都是一样的。 + +第一个思路是将数转换为字符串,但是需要额外的非常数空间;第二种方式是将数翻转与原来的数进行比较,如果它们两者相同的话,则是回文数,但是这个翻转的数是大于`int.MAX`,整数溢出问题。 + +仅仅翻转数的一半,这个数应该和原来的数的前一半相同。 +```C++ +class Solution { +public: + bool isPalindrome(int x) { + if (x < 0) + return false; + if (x == 0) + return true; + int tmp = x; + int reverse_half_num = 0; + int bitnum = 0; + + while (tmp > 0) { + tmp = tmp / 10; + bitnum++; + } + + for (int i = 0; i < bitnum / 2; i++) { + reverse_half_num = reverse_half_num * 10 + x % 10; + x = x / 10; + } + + if (((reverse_half_num == x) && (bitnum % 2 == 0)) ||( (reverse_half_num == x / 10) && (bitnum % 2 != 0))) + return true; + return false; + } +}; +``` +# 10. RegularExpressionMatching +给定一个输入字符串s和模式p,用`*`和`.`实现正则表达匹配。 + +`.`匹配零个或者多个单个字符;`*`匹配零个或者多个前面的元素。 + +匹配应该覆盖所有的输入字符串而不是部分。 + +注意: 字符串可以为空,并且只包含`a-z`的小写字母;可以为空,并且只包含`a-z`的小写字母,以及像`.`和`*`的字符。 + +首先,拿到这个题目后我第一个感觉是做过,可惜的是做题思路给忘记了。顿时有点小小的忧桑,刚刚看到大佬说,刷到一定的题量后,每天花一点时间保持题感还是很重要的,建议刷之前做过的题目,复习效果比做新题要好。大家都有一样的问题,一个月不刷题,再看到题目就跟智障一样。2019年3月4日 + +现在让我们重新梳理一遍吧。 + +在剑指Offer第52题中做过这个题目。 + +s是正常的字符串,p是包含特殊字符的。匹配的话,从左到右一直进行下去。`.`可以匹配任意字符,`*`的话根据它前面的字符来定。 + +分类如下: +1. 如果s为空的话,p为空,返回为true。 +2. 如果s不为空,但是p为空,返回false。在s为空,p不为空时,还是有可能能够匹配成功的。 +3. p的下一个字符为`*`。如果p的下一个字符不是`*`,那就直接匹配当前的字符,如果匹配成功,直接匹配下一个,如果匹配失败,那么返回false;如果p的下一个字符是`*`的话,那就比较复杂,因为其可以代表0个或者是多个。如果匹配零个字符时,s的当前字符不变,p的字符后移两位,跳过*这个字符。如果匹配的是1个或者多个,str的字符往下移动一个,但是p的字符不变。 + +判断条件需要仔细,递归方法。 +```C++ +class Solution { +public: + bool isMatch(string s, string p) { + if (s.empty() && p.empty()) return true; + if (!s.empty() && p.empty()) return false; + + int i = 0, j = 0; + if (p[j + 1] != '*') { + if (s[i] == p[j] || (s[i] != '\0' && p[j] == '.') ) + return isMatch(s.substr(i + 1, s.length()), p.substr(j + 1, p.length())); + else return false; + } + else { + if (s[i] == p[j] || (s[i] != '\0' && p[j] == '.')) + return isMatch(s, p.substr(j + 2, p.length())) || isMatch(s.substr(i + 1, s.length()), p); + else//s[i] == '\0' + return isMatch(s, p.substr(j + 2, p.length())); + } + + return false; + } +}; +``` + +# 11. ContainerWithMostWater +给定n个非负整数,每一个代表了在坐标(i,ai)上的点。根据输入画一条垂直的线,线的两端分别是(i,ai)和(i,0)。找到两条垂直的线组成的容器,使其能够容纳最大的量。 + +拿到这个题的第一个想法就是使用动态规划。 + +方法1:穷举搜索,计算每两个垂直线对。时间复杂度O(n^2)。 + +方法2:面积是由最短的那个线的高度决定的。这条线越远,就会获取更多的面积。首先,选取两个指针,一个指向开始端,一个指向结束端,组成了线的长度。维持一个`maxarea`存储目前获取到的最大面积。在每一步找到它们之间的面积,更新`maxarea`并且移动指针指向较短的那条线知道移动到另一端。 + +```C++ +class Solution { +public: + int maxArea(vector& height) { + int maxarea = 0; + if (!height.empty()) { + int left = 0, right = height.size() - 1; + while (right >= left) { + maxarea = max(maxarea, (right - left) * min(height[left], height[right])); + if (height[left] < height[right]) left++; + else right--; + } + } + return maxarea; + } +}; +``` +# 104. MaximumDepthofBinaryTree +递归方法求树的高度 +```C++ +class Solution { +public: + int maxDepth(TreeNode* root) { + if (root == NULL) return 0; + return 1 + max(maxDepth(root->left), maxDepth(root->right)); + } +}; +``` + +# 110. BalancedBinaryTree +判断平衡树(平衡树左右子树的高度之差不超过1),递归的方法,用到求解树的高度,在判断的时候需要对每个结点是否平衡进行判断。 +```C++ +class Solution { +public: + bool isBalanced(TreeNode* root) { + if (root == NULL) return true; + if (abs(height(root->right) - height(root->left)) <= 1) return isBalanced(root->right) && isBalanced(root->left); + return false; + } + int height(TreeNode* root) { + if (root == NULL) return 0; + return 1 + max(height(root->right), height(root->left)); + } +}; +``` + +# 112. PathSum +判断是否存在结点的和等于一个树的路径,只需要找到一个路径。 +```C++ +class Solution { +public: + bool hasPathSum(TreeNode* root, int sum) { + if (root == NULL) return false; + if ( root->left == NULL && root->right == NULL && root->val == sum) return true; + return hasPathSum(root->left, sum - root->val) || hasPathSum(root->right, sum - root->val); + } +}; +``` + +# 437. PathSumIII +统计路径和等于一个数的路径数量,划分为:以根结点为起点或者,不以根节点为起点,两种求解结果合在一起。 +```C++ +struct TreeNode { + int val; + TreeNode *left; + TreeNode *right; + TreeNode(int x) : val(x), left(NULL), right(NULL) {} + }; + +//以根结点为起点或者,不以根节点为起点,两个函数 +class Solution { +public: + int pathSum(TreeNode* root, int sum) { + if (root == NULL) return 0; + int ret = rootPathSum(root, sum) + pathSum(root->left, sum) + pathSum(root->right, sum); + return ret; + } + int rootPathSum(TreeNode* root, int sum) {//以根节点为起点 + if (root == NULL) return 0; + int ret = 0; + if (root->val == sum) ret++; + ret += rootPathSum(root->left, sum - root->val) + rootPathSum(root->right, sum - root->val); + return ret; + } +}; +``` +# 617. MergeTwoBinaryTrees +归并两棵树(将两棵树结点上的值加起来),对根节点初始化,对根节点的左右结点进行递归。 +```C++ +class Solution { +public: + TreeNode* mergeTrees(TreeNode* t1, TreeNode* t2) { + if (t1 == NULL && t2 == NULL) return NULL; + if (t1 == NULL) return t2; + if (t2 == NULL) return t1; + TreeNode* root = new TreeNode(t1->val + t2->val); + root->left = mergeTrees(t1->left, t2->left); + root->right = mergeTrees(t1->right, t2->right); + return root; + } +}; +``` + +# 572. SubtreeofAnotherTree +此题判断一个树是不是另外一个树的子树。本题的求解转换为:判断s为根节点的树是否和t相同,或者判断s的两个子树是否存在解。在子树上的求解方法:依旧是递归。 +```C++ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * TreeNode *left; + * TreeNode *right; + * TreeNode(int x) : val(x), left(NULL), right(NULL) {} + * }; + */ +class Solution { +public: + bool isSubtree(TreeNode* s, TreeNode* t) { + if ((s == NULL && t == NULL) || (s != NULL && t == NULL)) return true; + if (s == NULL && t != NULL) return false; + return isRootSubTree(s, t) || isSubtree(s->left, t) || isSubtree(s->right, t); + } + bool isRootSubTree(TreeNode* s, TreeNode* t) { + if (s == NULL && t == NULL) return true; + if ((s == NULL && t != NULL) || (s != NULL && t == NULL)) return false; + if (s->val == t->val) return isRootSubTree(s->left, t->left) && isRootSubTree(s->right, t->right); + else return false; + } +}; +``` + +# 101. SymmetricTree +一棵树是否关于中心对称。判断以根节点为对称中心的两个节点是狗相同,在遍历树的过程中,要同时遍历这两个节点,遍历过程可以使用递归来实现。如果当前判断的两个节点是 t1 和 t2,在进入新的遍历递归函数时,下一层要遍历的应该是 (t1.left, t2.right) 和 (t1.right, t2.left)。 +```C++ +class Solution { +public: + bool isSymmetric(TreeNode* root) { + if (root == NULL) return true; + return isSymmetric(root->left,root->right); + } + bool isSymmetric(TreeNode* t1, TreeNode* t2) { + if (t1 == NULL && t2 == NULL) return true; + if (t1 == NULL || t2 == NULL) return false; + if (t1->val != t2->val) return false; + return isSymmetric(t1->left, t2->right) && isSymmetric(t1->right, t2->left); + } +}; +``` + +# 144. BinaryTreePreorderTraversal +非递归实现树的前序遍历。 + +递归要用到递归栈,实现非递归最简单直接的方式是使用语言自带的栈来模拟递归栈,它和递归栈不在同一个内存空间中,不会出现 StackOverflow 错误。 + +使用栈来存储节点,当从栈中弹出一个节点时,就立即访问这个节点(添加到 vector 中),并且将左右子树根节点都添加到栈中。因为栈具有先进后出的顺序,如果先添加左子树根节点再添加右子树根节点,那么会先弹出右子树根节点,导致先访问右子树。所以要先将右子树根节点添加,再将左子树根节点添加,让左子树根节点先弹出。 +```C++ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * TreeNode *left; + * TreeNode *right; + * TreeNode(int x) : val(x), left(NULL), right(NULL) {} + * }; + */ +class Solution { +public: + vector preorderTraversal(TreeNode* root) { + vector ret; + stack tree; + tree.push(root); + while (!tree.empty()) { + TreeNode* node = tree.top(); + tree.pop(); + if (node == NULL) continue; + ret.push_back(node->val); + tree.push(node->right); + tree.push(node->left); + } + return ret; + } +}; +``` +# 145. BinaryTreePostorderTraversal +非递归实现后序遍历。 + +前序遍历为 root -> left -> right,后序遍历为 left -> right -> root。可以修改前序遍历成为 root -> right -> left,那么这个顺序就和后序遍历正好相反。 +```C++ +/** + * Definition for a binary tree node. + * struct TreeNode { + * int val; + * TreeNode *left; + * TreeNode *right; + * TreeNode(int x) : val(x), left(NULL), right(NULL) {} + * }; + */ +class Solution { +public: + vector postorderTraversal(TreeNode* root) { + vector ret; + stack tree; + tree.push(root); + while (!tree.empty()) { + TreeNode* node = tree.top(); + tree.pop(); + if (node == NULL) continue; + ret.push_back(node->val); + tree.push(node->left); + tree.push(node->right); + } + vector rev; + for (int i = ret.size() - 1; i >= 0; i--) { + rev.push_back(ret[i]); + } + return rev; + } +}; +``` + +# 94. BinaryTreeInorderTraversal +非递归实现树的中序遍历。 + +因为中序遍历需要先访问左子树,只有当左子树为空时,才从栈中弹出节点并且访问该节点,从而保证左子树都被访问过了。 + +```C++ +class Solution { +public: + vector inorderTraversal(TreeNode* root) { + vector ret; + if (root == NULL) return ret; + stack tree; + TreeNode* curnode = root; + while (curnode != NULL || !tree.empty()) { + while (curnode != NULL) { + tree.push(curnode); + curnode = curnode->left; + } + TreeNode* node = tree.top(); + tree.pop(); + ret.push_back(node->val); + curnode = node->right; + } + return ret; + } +}; +``` \ No newline at end of file diff --git "a/\345\210\267\351\242\230/LeetCode\351\242\230\350\247\243/\345\212\233\346\211\243\351\242\230\350\247\243.md" "b/\345\210\267\351\242\230/LeetCode\351\242\230\350\247\243/\345\212\233\346\211\243\351\242\230\350\247\243.md" deleted file mode 100644 index 2494f28..0000000 --- "a/\345\210\267\351\242\230/LeetCode\351\242\230\350\247\243/\345\212\233\346\211\243\351\242\230\350\247\243.md" +++ /dev/null @@ -1,65 +0,0 @@ - -* [1. TwoSum](#1-TwoSum) - - -# 1. TwoSum - -给定一个整数数组,返回两个数之和等于target的数组索引。 - -我的思路:夹逼准则,先排序,然后首位寻找是否等于target的数。但是这样排序改变了原来数组的下标,先找到这两个数,然后返回下标。 - -唉 - -最简单的方法是穷举搜索,一个是x,另外一个是target-x;复杂度O(n^2) - -优化方法:两次hash表操作,对在一维数组中查找target-x优化。 - -进一步优化:一次hash表操作,边建立hash表边返回。 - -```C++ -#include -#include -#include -using namespace std; - -class Solution { -public: - vector twoSum(vector& nums, int target) { - vector res; - int size = nums.size(); - if (size <= 1) return res; - vector nums_sort(nums); - sort(nums_sort.begin(), nums_sort.end()); - int i = 0, j = size - 1; - while (i <= size - 1 && j >= i) { - if (nums_sort[i] + nums_sort[j] == target) { - break; - } - else if (nums_sort[i] + nums_sort[j] > target) { - j--; - } - else { - i++; - } - } - - for (int k = 0; k < size; k++) { - if (nums[k] == nums_sort[i] || nums[k] == nums_sort[j]) - res.push_back(k); - } - return res; - } -}; - -int main() { - Solution s; - vector nums = { 3,3 }; - vector res; - res = s.twoSum(nums, 6); - for (auto i : res) - cout << i << " "; - cout << endl; - system("pause"); - return 0; -} -``` \ No newline at end of file diff --git "a/\345\210\267\351\242\230/images/cpu\346\233\262\347\272\277.PNG" "b/\345\210\267\351\242\230/images/cpu\346\233\262\347\272\277.PNG" new file mode 100644 index 0000000..e317958 Binary files /dev/null and "b/\345\210\267\351\242\230/images/cpu\346\233\262\347\272\277.PNG" differ diff --git "a/\345\210\267\351\242\230/\345\211\221\346\214\207Offer/\351\242\230\350\247\243.md" "b/\345\210\267\351\242\230/\345\211\221\346\214\207Offer\351\242\230\350\247\243.md" similarity index 99% rename from "\345\210\267\351\242\230/\345\211\221\346\214\207Offer/\351\242\230\350\247\243.md" rename to "\345\210\267\351\242\230/\345\211\221\346\214\207Offer\351\242\230\350\247\243.md" index 5cddb47..a1f6274 100644 --- "a/\345\210\267\351\242\230/\345\211\221\346\214\207Offer/\351\242\230\350\247\243.md" +++ "b/\345\210\267\351\242\230/\345\211\221\346\214\207Offer\351\242\230\350\247\243.md" @@ -69,6 +69,7 @@ * [64. 滑动窗口的最大值](#64-滑动窗口的最大值) * [65. 矩阵中的路径](#65-矩阵中的路径) * [66. 机器人的运动范围](#66-机器人的运动范围) +* [67. 剪绳子](#67-剪绳子) # 前言 @@ -4929,4 +4930,41 @@ int main() { system("pause"); return 0; } +``` + +# 67. 剪绳子 + +给你一根长度为n的绳子,请把绳子剪成m段(m、n都是整数,n>1并且m>1),每段绳子的长度记为k[0],k[1],...,k[m]。请问k[0]xk[1]x...xk[m]可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。 + +输入: +`n` + +输出:乘积 + +贪心算法 +----------------------------------------------------- +```C++ +#include +#include +using namespace std; + +int cutRope(int number) { + if (number < 2) return 0; + if (number == 2) return 1; + if (number == 3) return 2; + + int timesof3 = number / 3; + if (number - timesof3*3 == 1) timesof3--; + + int timesof2 = (number - timesof3 * 3) / 2; + + return (int)(pow(2, timesof2))*(int)(pow(3, timesof3)); +} +int main() { + int n; + cin >> n; + cout << cutRope(n) << endl; + system("pause"); + return 0; +} ``` \ No newline at end of file diff --git "a/\345\210\267\351\242\230/\345\215\216\344\270\272.md" "b/\345\210\267\351\242\230/\345\215\216\344\270\272.md" new file mode 100644 index 0000000..6b630b6 --- /dev/null +++ "b/\345\210\267\351\242\230/\345\215\216\344\270\272.md" @@ -0,0 +1,716 @@ +## 模拟试题 +长度为`n`的数组乱序存放着0至n-1,现在只能进行0与其他数的交换,完成以下函数: +```C++ +#include +using namespace std; + +/** + * 交换数组里n和0的位置 + * array: 存储[0-n)的数组 + * len: 数组长度 + * n: 数组里要和0交换的数 + */ +extern void swap_with_zero(int* array, int len, int n); + +class Solution { +public: + /** + * 调用方法swap_with_zero来对array进行排序 + */ + void sort(int* array, int len) { + for (int i = len - 1; i > 0; i--) { + swap_with_zero(array, len, array[i]); + swap_with_zero(array, len, i); + } + } +}; +``` + +## 笔试题 +1. 输入一个字符串,其中包括数字,数字代表了字符串的个数,输出要求,每8个字符为一组,不够8个的后面填充0,输出字符串是有序的。 + + 输入样例 + ``` + 2 abc 123456789 + ``` + 输出样例 + ``` + 12345678 90000000 abc00000 + ``` + 题解:输入N,循环读取每个字符串,对每个字符串进行单独处理,掌握`string`常用函数。 + ```C++ + #include + #include + #include + #include + #include + using namespace std; + + vector output; + + int main() + { + int N; + cin >> N; + if (!N) return 0; + output.clear(); + for (int i = 0; i < N; i++) + { + string temp; + cin >> temp; + int l = temp.length(); + int zu = l / 8; + int rest = l % 8; + if (!l) continue; + for (int j = 0; j < zu; j++) output.push_back(temp.substr(8 * j, 8) + " "); + if (rest) + { + string r = temp.substr(8 * zu); + while (r.length() < 8) r += "0"; + r += " "; + output.push_back(r); + } + } + sort(output.begin(), output.end()); + for (auto i : output) + cout << i; + cout << endl; + system("pause"); + return 0; + } + ``` + +2. 输入字符串,其中字符串中有数字,数字后面带有括号,括号可以嵌套,不包含括号不匹配的问题。 + + 输入样例 + ``` + abc3{A} + ``` + 输出样例 + ``` + AAAcba + ``` + 题解:括号压栈 + ```C++ + #include + #include + #include + #include + #include + using namespace std; + + struct message + { + int position; //数字的第一位数出现的下标 + int num; //重复的次数 + int pos_kuo; //左括号的位置 + }; + + int main() + { + stack kuohao; + string input; + cin >> input; + + int l = input.length(); + if (!l) return 0; + + for (int i = 0; i < input.size(); ) + { + int begin, end; + if (input[i] <= '9' && input[i] >= '0') + { + begin = i; + i++; + while (input[i] != '{' && input[i] != '(' && input[i] != '[') i++; + end = i; + message* temp = new message; + temp->num = stoi(input.substr(begin, end - begin)); + temp->position = begin; + temp->pos_kuo = end; + kuohao.push(temp); + } + if (input[i] == '}' || input[i] == ')' || input[i] == ']') + { + message* temp = kuohao.top(); + string ins = input.substr(temp->pos_kuo + 1, i - temp->pos_kuo - 1); + string inser = ""; + for (int k = 0; k < temp->num; k++) inser += ins; + input = input.replace(temp->position, i - temp->position + 1, inser); + + i = temp->position + inser.length() - 1; + kuohao.pop(); + } + i++; + } + reverse(input.begin(), input.end()); + cout << input << endl; + system("pause"); + return 0; + } + ``` +3. 回溯法。一张N*M的地图上每个点的海拔高度不同;从当前点只能访问上、下、左、右四个点中还没有到达的过的点,且下一步选择的海拔高度必须高于当前点;求从地图中的点A到点B总的路径条数除以10^9的余数。地图上的左上角为(0,0),右下角为(N-1,M-1)。输入N,M,N行,每行M个,最后一行X,Y,Z,W,(X,Y)代表A的坐标,(Z,W)代表B的坐标。 + + 方法一:非AC版,时间超时。 + ```C++ + #include + #include + #include + #include + #include + using namespace std; + + long long dfs(vector > &path, int x, int y, vector> &visit, int tar_x, int tar_y) { + int m = path.size(); + int n = path[0].size(); + + long long res = 0; + if (x == tar_x && y == tar_y) + res++; + visit[x][y] = true; + + if (x - 1 >= 0 && x - 1 < m && y >= 0 && y < n && visit[x - 1][y] == false && path[x - 1][y] > path[x][y]) { + res += dfs(path, x - 1, y, visit, tar_x, tar_y); + } + + if (x + 1 >= 0 && x + 1 < m && y >= 0 && y < n && visit[x + 1][y] == false && path[x + 1][y] > path[x][y]) { + res += dfs(path, x + 1, y, visit, tar_x, tar_y); + } + + if (x >= 0 && x < m && y - 1 >= 0 && y - 1< n && visit[x][y - 1] == false && path[x][y - 1] > path[x][y]) { + res += dfs(path, x, y - 1, visit, tar_x, tar_y); + } + + if (x >= 0 && x < m && y + 1 >= 0 && y + 1 < n && visit[x][y + 1] == false && path[x][y + 1]>path[x][y]) { + res += dfs(path, x, y + 1, visit, tar_x, tar_y); + } + visit[x][y] = false; + return res; + } + + long long getPath(vector > &path, int startx, int starty, int endx, int endy) { + int m = path.size(); + int n = path[0].size(); + + long long res = 0; + vector > visit(m, vector(n, false)); + + res = dfs(path, startx, starty, visit, endx, endy); + return res; + } + + int main() { + int m, n; + int x, y, endx, endy; + cin >> m >> n; + vector> input; + vector tmp; + int temp; + for (int i = 0; i < m; i++) { + tmp.clear(); + for (int j = 0; j < n; j++) { + cin >> temp; + tmp.push_back(temp); + } + input.push_back(tmp); + } + cin >> x >> y >> endx >> endy; + long long res = getPath(input, x, y, endx, endy); + res = res % 1000000000; + cout << res << endl; + + system("pause"); + return 0; + } + ``` + 方法二: + ```C++ + #include + #include + #include + using namespace std; + + struct point { + int height; + int x; + int y; + point(int x, int y, int height) :x(x), y(y), height(height) {} + }; + + struct cmp { + bool operator()(point a, point b) { + return a.height > b.height; + } + }; + int main() { + int N, M; + vector > map; + vector > count; + priority_queue, cmp> pq; + cin >> N >> M; + for (int i = 0; i < N; i++) { + map.push_back(vector()); + count.push_back(vector()); + for (int j = 0; j < M; j++) { + int tmp; + cin >> tmp; + map[i].push_back(tmp); + count[i].push_back(0); + pq.push(point(i, j, tmp)); + } + } + + int sx, sy, ex, ey; + cin >> sx >> sy >> ex >> ey; + count[sx][sy] = 1; + int H = map[sx][sy]; + while (pq.size()) { + point p = pq.top(); + pq.pop(); + if (p.height < H) { + continue; + } + if (p.x == ex && p.y == ey) break; + if (p.x > 0 && map[p.x][p.y] < map[p.x - 1][p.y]) { + count[p.x - 1][p.y] += count[p.x][p.y]; + count[p.x - 1][p.y] %= 1000000000; + } + if (p.y > 0 && map[p.x][p.y] < map[p.x][p.y - 1]) { + count[p.x][p.y - 1] += count[p.x][p.y]; + count[p.x][p.y - 1] %= 1000000000; + } + if (p.x < N - 1 && map[p.x][p.y] < map[p.x + 1][p.y]) { + count[p.x + 1][p.y] += count[p.x][p.y]; + count[p.x + 1][p.y] %= 1000000000; + } + if (p.y < M - 1 && map[p.x][p.y] < map[p.x][p.y + 1]) { + count[p.x][p.y + 1] += count[p.x][p.y]; + count[p.x][p.y + 1] %= 1000000000; + } + } + cout << count[ex][ey] << endl; + system("pause"); + return 0; + } + ``` + +## 附录 +[一个好用的C++常见库和函数的查询网站](http://www.cplusplus.com/reference/) + +------- +## 笔试试题卷2 + +1. 给定一个数组,里面有6个整数,求这个数组能够表示的最大24进制的时间是多少,输出这个时间,无法表示invalid。 + + 输入: + ``` + [0,2,3,0,5,6] + ``` + ``` + 23:56:00 + ``` + + 输入: + ``` + [9,9,9,9,9,9] + ``` + ``` + invalid + ``` + ```C++ + #include + #include + #include + using namespace std; + + int m(int a, int b) + { + return 10 * a + b; + } + + int ma(vector &input, int goal) + { + int result=goal+1; + int s = input.size(); + for(int i=0;i 0 && (goal - temp <= (goal - result)||result==goal+1)) result = temp; + } + } + if (result < goal) + { + int a = result / 10; + int b = result % 10; + input.erase(find(input.begin(), input.end(), a)); + input.erase(find(input.begin(), input.end(), b)); + return result; + } + else return -1; + } + + int main() + { + vector input; + char cc = getchar(); + for (int i = 0; i < 6; i++) + { + int temp; + cin >>temp; + input.push_back(temp); + cc = getchar(); + } + int a = ma(input, 24); + int b = ma(input, 60); + int c = ma(input, 60); + if (a == -1 || b == -1 || c == -1) + { + cout<<"invalid"< + #include + #include + #include + #include + using namespace std; + + bool cmp(pair p1, pair p2) { + return p1.first == p2.first ? p1.first < p2.first : p1.second < p2.second; + } + + int main(){ + string s; + vector v0, v1; + + getline(cin, s); + istringstream is1(s); + int inter; + char ch; + while (is1 >> inter) + { + v0.push_back(inter); + is1 >> ch; + } + + getline(cin, s); + istringstream is2(s); + while (is2 >> inter) + { + v1.push_back(inter); + is2 >> ch; + } + + vector> fruit; + for (int i = 0; i < v0.size(); i++) { + fruit.push_back(make_pair(v0[i], v1[i])); + } + sort(fruit.begin(), fruit.end(), cmp); + + int money; + cin >> money; + for (auto p : fruit) { + if (p.first >= p.second) + continue; + else if (money >= p.first) + money += p.second - p.first; + else + break; + } + cout << money << endl; + return 0; + } + ``` + 输入形式的更改 + ```C++ + #include + #include + #include + using namespace std; + + bool cmp(pair p1, pair p2) { + return p1.first == p2.first ? p1.first < p2.first : p1.second < p2.second; + } + + int main() { + string input; + vector m, n; + + char c = ','; + while (c == ',') + { + int temp; + cin >> temp; + m.push_back(temp); + c = getchar(); + } + + c = ','; + + while (c == ',') + { + int temp; + cin >> temp; + n.push_back(temp); + c = getchar(); + } + + int cost; + cin >> cost; + + vector> res; + + for (int i = 0; i < m.size(); i++) { + res.push_back(make_pair(m[i], n[i])); + } + + sort(res.begin(), res.end(), cmp); + + for (auto i : res) { + if (i.first >= i.second) + continue; + else if (cost >= i.first) + cost += i.second - i.first; + else + break; + } + + cout << cost << endl; + system("pause"); + return 0; + } + ``` +3. 某多处理器多道批处理系统一次允许将所有作业调入内存,且能并行执行,其并行数等于处理器个数。该系统采用SJF的调度方式(最短作业有限,系统在时间调度时,总是优先调度执行处理时间最短的作业)。现给定处理器个数`m`,作业数`n`,每个作业的处理时间分别为`t1`,`t2`...`tn`。当`n>m`时,首先处理时间短的`m`个作业进入处理器处理,其他的进入等待,当某个作业处理完成时,依次从等待队列中取处理时间最短的作业进入处理。求系统处理完所有作业的耗时为多少?注:不考虑作业切换的消耗。 + + 输入描述: + + 输入两行,第一行为2个整数,空行分隔,分别表示处理器个数和作业数;第二行输入n个整数,表示每个作业处理时长。 + + 输入示例: + ``` + 3 5 + 8 4 3 1 10 + ``` + 输出 + ``` + 13 + ``` + 说明: + + 首先时长为1,3,4的作业4(cpu1)、作业3(cpu2)、作业2(cpu3)进去处理。 + + 1个时间单元后,作业4执行结束,作业进入处理(cpu1), + + 3个时间单元后,作业3执行结束,作业5进入处理(cpu2), + + 4个单元后,作业2执行结束, + + 9个时间单元后,作业1执行结束, + + 13个时间单元后,作业5执行结束, + + 则,总时长为13。 + ```C++ + #include + #include + #include + #include + using namespace std; + + int main() + { + int m, n;//m处理器个数,n作业数 + cin >> m >> n; + if (m == 0 || n == 0) return 0; + vector input; + for (int i = 0; i < n; ++i) { + int temp; + cin >> temp; + input.push_back(temp); + } + + sort(input.begin(), input.end()); + + if (m >= n) + cout << input[n - 1] << endl; + multiset output; + for (int i = 0; i < m; ++i) + output.insert(input[i]); + for (int i = m; i < n; ++i) { + multiset::iterator it = output.begin(); + int tmp = *it; + output.erase(it); + output.insert(tmp + input[i]); + } + cout << *(output.rbegin()) << endl; + system("pause"); + return 0; + } + ``` + + +## 笔试试题卷3 +1. 求解矩阵中为1的子矩阵的最大面积。 + + ```C++ + #include + #include + #include + #include + using namespace std; + + int maxSquare(vector >& matrix) { + // write your code here + + int m = matrix.size(); //行大小 + int n = matrix[0].size(); //列大小 + + //一个与matrix相同大小的辅助数组 + vector> tmp(m, vector(n, matrix[0][0])); + + + //将matrix的第一行和第一列元素直接存放到 + for (int i = 0; i < m; i++) { + tmp[i][0] = matrix[i][0]; + } + for (int i = 0; i < n; i++) { + tmp[0][i] = matrix[0][i]; + } + + for (int i = 1; i < m; i++) { + for (int j = 1; j < n; j++) { + if (matrix[i][j] == 1) { + tmp[i][j] = + min(min(tmp[i - 1][j], tmp[i][j - 1]), tmp[i - 1][j - 1]) + 1; + } + if (matrix[i][j] == 0) { + tmp[i][j] = 0; + } + + } + } + + int max = 0; //记录tmp中最大元素的值(tmp中元素值表示正方形的边长) + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + if (tmp[i][j] > max) { + max = tmp[i][j]; + } + } + } + + return max * max; + } + + + int main() { + int n; + cin >> n; + vector > matrix; + for (int i = 0; i < n; i++) { + string temp; + cin >> temp; + vector tmp; + for (int i = 0; i < temp.size(); i++) { + tmp.push_back(temp[i] - '0'); + } + matrix.push_back(tmp); + } + cout << maxSquare(matrix) << endl; + system("pause"); + return 0; + } + ``` + +2. 判断2个ip地址是否处于同一个网段。 + ```C++ + #include + #include + using namespace std; + + vector getIP(vector& ip1, vector& ip2) { + vector res(4, 0); + for (int i = 0; i < 3; i++) + res[i] = ip1[i] & ip2[i]; + return res; + } + + int main() + { + vector ip1(4, 0), ip2(4, 0), mask(4, 0); + vector res1, res2; + + cin >> ip1[0]; + getchar(); + cin >> ip1[1]; + getchar(); + cin >> ip1[2]; + getchar(); + cin >> ip1[3]; + + cin >> ip2[0]; + getchar(); + cin >> ip2[1]; + getchar(); + cin >> ip2[2]; + getchar(); + cin >> ip2[3]; + + cin >> mask[0]; + getchar(); + cin >> mask[1]; + getchar(); + cin >> mask[2]; + getchar(); + cin >> mask[3]; + + res1 = getIP(ip1, mask); + res2 = getIP(ip2, mask); + if (res1 == res2) + cout << 1; + else cout << 0; + + cout << ' ' << res1[0] << '.' << res1[1] << '.' << res1[2] << '.' << res1[3] << endl; + } + ``` + diff --git a/emmm.txt "b/\345\210\267\351\242\230/\345\244\264\346\235\241.md" similarity index 100% rename from emmm.txt rename to "\345\210\267\351\242\230/\345\244\264\346\235\241.md" diff --git "a/\345\210\267\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225\346\200\273\347\273\223.md" "b/\345\210\267\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225\346\200\273\347\273\223.md" new file mode 100644 index 0000000..ad566c2 --- /dev/null +++ "b/\345\210\267\351\242\230/\346\216\222\345\272\217\347\256\227\346\263\225\346\200\273\347\273\223.md" @@ -0,0 +1,153 @@ + +* [选择排序](#选择排序) +* [冒泡排序](#冒泡排序) +* [快速排序](#快速排序) +* [插入排序](#插入排序) + + +# 选择排序 +第一轮,从数组中选择最小的元素,与数组第一个元素交换位置;第二轮,从除第一个元素之外的数组中选择最小的元素,与数组的第二个元素交换位置。以此类推,直至数据有序。 + +选择排序需要n^2/2次比较和n次交换,它的运行时间与输入无关,即使输入的是一个已经排好序的数组也需要这么多的比较和交换操作。 + +```C++ +#include +#include +using namespace std; + +void swap(int &a, int &b) { + int tmp = a; + a = b; + b = tmp; +} + +vector sort(vector& input) { + int len = input.size(); + if (!len) return input; + + for (int i = 0; i < len; i++) { + int temp = i; + for (int j = i; j < len; j++) { + if (input[j] < input[temp]) + temp = j; + } + swap(input[i], input[temp]); + } + + return input; +} + +int main() +{ + vector input; + + int n; + cin >> n; + + for (int i = 0; i < n; ++i) { + int tmp; + cin >> tmp; + input.push_back(tmp); + } + + sort(input); + + for (auto i : input) + cout << i << " "; + cout << endl; + + system("pause"); + return 0; +} +``` + +# 冒泡排序 +从左到右不断交换相邻逆序元素,在一轮循环之后,可以让未排序的最大元素上浮到右侧。 + +在一轮循环中,如果没有发生交换,说明数组是有序的,此时可以直接退出。 + +```C++ +#include +#include +using namespace std; + +void swap(int &a, int &b) { + int tmp = a; + a = b; + b = tmp; +} + +vector buble(vector& input) { + int len = input.size(); + if (!len) return input; + + for (int i = 1; i < len; i++) {//比较len-1轮 + for (int j = 0; j < len - i; j++) { + if (input[j] > input[j + 1]) + swap(input[j], input[j + 1]); + } + } + return input; +} + +int main() +{ + vector input; + + int n; + cin >> n; + + for (int i = 0; i < n; ++i) { + int tmp; + cin >> tmp; + input.push_back(tmp); + } + + buble(input); + + for (auto i : input) + cout << i << " "; + cout << endl; + + system("pause"); + return 0; +} +``` + +# 快速排序 +快速排序首先选取一个基准,一般选取第一个作为基准。然后选择两个哨兵`i`和`j`,对比大小,调整位置,使得左边的是小于基准的,右边的是大于基准的,然后将这两块分别递归处理。 +```C++ +``` + +# 插入排序 +把当前节点看作已排序好的节点,当前节点的索引为`j`,记录下一个节点的值为key,对下一个节点和当前节点的每一个进行比较,如果小于当前节点,和`j-1`节点进行比较,直至遇见小于或者到达`j==0`,插入到`j+1`的位置。 +```C++ +#include +#include +using namespace std; + +vector insert_sort(vector& num) { + int size = num.size(); + if (size == 0) return num; + + for (int j = 0; j < size - 1; j++) { + int key = num[j + 1]; + while (j >= 0 && num[j] > key) { + num[j + 1] = num[j]; + j--; + } + num[j + 1] = key; + } + return num; +} + +int main() { + vector num = { 6, 2, 1, 8, 2, 5, 0, 3, 4 }; + num = insert_sort(num); + for (auto i : num) + cout << i << " "; + cout << endl; + system("pause"); + return 0; +} +``` \ No newline at end of file diff --git "a/\345\210\267\351\242\230/\346\265\267\345\272\267\351\235\242\350\257\225\346\200\273\347\273\223.md" "b/\345\210\267\351\242\230/\346\265\267\345\272\267\351\235\242\350\257\225\346\200\273\347\273\223.md" new file mode 100644 index 0000000..e39a950 --- /dev/null +++ "b/\345\210\267\351\242\230/\346\265\267\345\272\267\351\235\242\350\257\225\346\200\273\347\273\223.md" @@ -0,0 +1,193 @@ +## 一面 +1. 给定 `n*n` 矩阵,计算一个新的 `n*n` 矩阵,使得新矩阵的 `(i,j)`位置 是以老矩阵 `(i,j)` 位置为中心的 `m*m` 小矩阵的平均值。`m`是奇数。 +2. 请用堆排序的方法求n维数组的 `TopK` 。 +3. 实现单机版 `KMeans`算法,如果有`MapReduce`经验,可以再扩展一下,如何用MapReduce写分布式`KMeans`。 + +### 第一题:暴力搜索,O(n^2*m^2)。 +需要考虑边界条件,问面试官。代码是工具,思考解决问题的方式不正确。手生了。 +```C++ +#include +#include +using namespace std; + +//边界单独处理,非边界的话 +class Solution { +public: + vector> avgMatirx(vector> data, int m) { + vector> res; + int rows = data.size(); + int cols = data[0].size(); + + float tmp = 0.0; + vector avg; + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { + //限制小m矩阵处理的范围 + int top = (i - m / 2) >= 0 ? (i - m / 2) : 0; + int btm = (i + m / 2) < cols ? (i + m / 2) : (cols - 1); + int left = (j - m / 2) >= 0 ? (j - m / 2) : 0; + int right = (j + m / 2) < rows ? (j + m / 2) : (rows - 1); + + for (int k = top; k <= btm; k++) + for (int t = left; t <= right; t++) + tmp = tmp + data[k][t]; + avg.push_back(tmp / (m*m));//这个究竟是(right - left + 1)*(btm - top + 1) + tmp = 0; + } + res.push_back(avg); + avg.clear(); + } + return res; + } +}; + +int main() { + Solution s; + vector > array = { {1,2,3,4},{3,4,5,6},{5,6,7,8},{7,8,9,10}}; + for (int i = 0; i < array.size(); i++) + { + for (int j = 0; j < array[0].size(); j++) + { + cout << array[i][j] << " "; + } + cout << endl; + } + vector > res = s.avgMatirx(array,3); + for (int i = 0; i < res.size(); i++) + { + for (int j = 0; j < res[0].size(); j++) + { + cout << res[i][j] << " "; + } + cout << endl; + } + system("pause"); + return 0; +} +``` +果然写的代码太少,`vector`常用函数不熟悉,`resize`。 + +leetcode661:滑动窗口原题 + +刚开始出现内存限制错误,引用对原址进行操作,尽量使用引用。 +```C++ +class Solution { +public: + vector> imageSmoother(vector>& M) { + vector> res; + int rows = M.size(); + int cols = M[0].size(); + + res.resize(rows); + for(int i = 0; i < rows; i++){ + res[i].resize(cols); + } + + for (int i = 0; i < rows; i++) { + for (int j = 0; j < cols; j++) { + res[i][j] = smooth(M, i, j); + } + + } + return res; + } + + int smooth(vector> &M, int x, int y){ + int rows = M.size(); + int cols = M[0].size(); + + int sum = 0; + int count = 0; + + for(int i = -1; i <= 1; i++){ + for(int j = -1; j <= 1;j++){ + if(x + i < 0 || x + i >= rows || y + j < 0 || y + j >= cols){//边界条件判断 + continue; + } + count++; + sum += M[x+i][y+j]; + + } + } + return sum/count; + } +}; +``` + +### 第二题:堆排序求TopK数。 + +堆:一种数据结构。堆排序的时间复杂度为O(nlogn),具有空间原址性,任何时候都只需要常数个额外的元素空间存储临时数据。算法导论85-92页。 + +1. maxHeapify:维护最大堆的性质。 +2. buildMaxHeap:从无序的输入数据数组中构造一个最大堆。 +3. heapSort:对数组进行原址排序。 + +```C++ +#include +#include +using namespace std; + +//维护堆的性质,保证最大的放在堆顶 +void maxHeapify(vector &heap, int i) { + int left = 2 * i + 1; + //left = left >= heap.size() ? i : left; + int right = 2 * i + 2; + //right = right >= heap.size() ? i : right; + int largeindex = i; + if (left < heap.size() && heap[left] > heap[largeindex]) { + largeindex = left; + } + else { + largeindex = i; + } + if (right < heap.size() && heap[right] > heap[largeindex]) { + largeindex = right; + } + + if (largeindex != i) { + int temp = heap[i]; + heap[i] = heap[largeindex]; + heap[largeindex] = temp; + maxHeapify(heap, largeindex); + } +} + +void buildMaxHeap(vector &heap) { + for (int i = heap.size() / 2 - 1; i >= 0; i--) + { + maxHeapify(heap, i); + } +} + +vector heapSort(vector &heap, int k) { + vector top_k; + for (int i = 0; i < k; i++) { + top_k.push_back(heap[0]); + heap[0] = heap.back(); + heap.pop_back(); + maxHeapify(heap, 0); + } + return top_k; +} + +int main() +{ + vector heap = { 4,3,2,1,8,7,6,5}; + buildMaxHeap(heap); + for (int i : heap) { + cout << i << ' '; + } + cout << endl; + vector top_k = heapSort(heap, 5); + for (int i : top_k) { + cout << i << ' '; + } + cout << endl; + system("pause"); + return 0; +} + +``` +### 第三题:实现K-means。 +```Python +``` \ No newline at end of file diff --git "a/\345\210\267\351\242\230/\347\247\213\346\213\233\347\254\224\350\257\225.md" "b/\345\210\267\351\242\230/\347\247\213\346\213\233\347\254\224\350\257\225.md" new file mode 100644 index 0000000..0e0d1ff --- /dev/null +++ "b/\345\210\267\351\242\230/\347\247\213\346\213\233\347\254\224\350\257\225.md" @@ -0,0 +1,264 @@ +## lambda函数 +```C++ +#include +#include +#include +#include +using namespace std; + +int greater1(int firstVal, int secondVal) { + return firstVal > secondVal ? true : false; +} //greater是保留字 + +void findSpecificValue(const std::vector& vec, int specificValue) { + auto iter = vec.begin(); + iter = find_if(iter, vec.end(), std::bind(greater1, std::placeholders::_1, specificValue)); + if (iter != vec.end()) { + cout << "greater than" << specificValue << ":" << *iter << endl; + } +} + +int main() { + vector vec{ 1,2,3,4,5,6,7,8,9,10 }; + findSpecificValue(vec, 8); + system("pause"); + return 0; +} + + +``` +修改为`lambda`形式,只能输出`9` +```C++ +#include +#include +#include +#include +using namespace std; + +bool greater(int firstVal, int secondVal) { + return firstVal > secondVal ? true : false; +} + +void findSpecificValue(const std::vector& vec, int specificValue) { + auto iter = vec.begin(); + while (iter != vec.end()) { + iter = find_if(iter, vec.end(), [specificValue](const int &a) {return a > specificValue; }); + if (iter != vec.end()) { + cout << "greater than" << specificValue << ":" << *iter << endl; + } + iter++; + } +} + +int main() { + vector vec{ 1,2,3,4,5,6,7,8,9,10 }; + findSpecificValue(vec, 8); + system("pause"); + return 0; +} +``` + +## String构造函数 +```C++ + +``` + +## 翻转字串 + +假定我们都知道非常高效的算法来检查一个单词是否为其他字符串的子串。请将这个算法编写成一个函数,给定两个字符串`s1`和`s2`,请编写代码检查`s2`是否为`s1`旋转而成,要求只能调用一次检查子串的函数。 + +给定两个字符串`s1`,`s2`,请返回`bool`值代表`s2`是否由`s1`旋转而成。字符串中字符为英文字母和空格,区分大小写,字符串长度小于等于1000。 + +```C++ +//考点:str.find(substr) +class ReverseEqual { +public: + bool checkReverseEqual(string s1, string s2) { + // write code here + int len1 = s1.size(), len2 = s2.size(); + if (len1 != len2) return false; + if (len1 == 0 || len2 == 0) return false; + string str = s1 + s1; + if (str.find(s2) == -1) return false; + else return true; + } +}; +``` + +## 二叉树平衡检查 +二叉树平衡的定义:空树且左右子树的高度不超过1,并且左右子树的子树也是平衡二叉树。 + +```C++ +#include +#include +#include +#include +using namespace std; + +struct TreeNode { + int val; + struct TreeNode *left; + struct TreeNode *right; + TreeNode(int x) : + val(x), left(NULL), right(NULL) {} +}; + +class Balance { +public: + int calhigh(TreeNode* root) { + if (root == nullptr) return 0; + return 1 + max(calhigh(root->right), calhigh(root->left)); + } + bool isBalance(TreeNode* root) { + // write code here + if (root == nullptr) return true; + int left = calhigh(root->left); + int right = calhigh(root->right); + bool flag = (abs(left - right) <= 1); + return flag && isBalance(root->left) && isBalance(root->right); + } +}; +``` + +## 整数转化 +编写一个函数,确定需要改变几位,才能将整数A转变为整数B,给定两个整数int A,int B,请返回需要改变数位的位数 + + 思路: + 1)这两个整数都需要转换为2进制表示,旨在求出这两个整数bit数不同的位数,考虑其中一个按位操作不同的数,异或操作之后1的个数。 + 2)怎么求解异或操作之后1的个数,异或之后的结果依旧放在int里吗?计算一个数的1的个数,采用 n = n & (n-1) 的方式; + + +```C++ +class Transform { +public: + int calcCost(int A, int B) { + // write code here + int res = A ^ B; + int count = 0; + while (res) { + count++; + res = res & (res - 1); + } + return count; + } +}; +``` + +## 奇偶位交换 +```C++ +class Exchange { +public: + int exchangeOddEven(int x) { + // write code here + return ((x & 0x55555555) << 1) | ((x & 0xaaaaaaaa) >> 1); + } +}; +``` + +## 上楼梯 +有个小孩正在上楼梯,楼梯有n阶台阶,小孩一次可以上1阶、2阶、3阶。请实现一个方法,计算小孩有多少种上楼的方式。为了防止溢出,请将结果Mod 1000000007 + +给定一个正整数int n,请返回一个数,代表上楼的方式数。保证n小于等于100000。 +```C++ +class GoUpstairs { +public: + int countWays(int n) { + // write code here + vector res(n + 1, 0); + res[0] = 0; + res[1] = 1; + res[2] = 2; + res[3] = 4; + for (int i = 4; i < n + 1; i++) { + res[i] = (res[i - 1] + (res[i - 2] + res[i - 3]) % 1000000007) % 1000000007; + } + return res[n]; + } +}; +``` +## 确定字符互异 +```C++ +class Different { +public: + bool checkDifferent(string iniString) { + // write code here + sort(iniString.begin(),iniString.end()); + if(unique(iniString.begin(),iniString.end()) == iniString.end())return true; + return false; + } +}; +``` +## 确定两串乱序同构 +```C++ +class Same { +public: + bool checkSam(string stringA, string stringB) { + // write code here + if (stringA.size() == 0 || stringB.size() == 0) return false; + int hashTableA[256] = { 0 }, hashTableB[256] = { 0 }; + for (int i = 0; i < stringA.size(); i++) { + hashTableA[stringA[i]]++; + } + for (int i = 0; i < stringB.size(); i++) { + hashTableB[stringB[i]]++; + } + for (int i = 0; i < 256; i++) { + if (hashTableA[i] != hashTableB[i]) + return false; + } + return true; + } +}; +``` + +## 回文链表 +```C++ +/* +struct ListNode { + int val; + struct ListNode *next; + ListNode(int x) : val(x), next(NULL) {} +};*/ +class Palindrome { +public: + bool isPalindrome(ListNode* pHead) { + // write code here + int num = 0; + ListNode* tmp = pHead; + while (tmp != nullptr) { + num++; + tmp = tmp->next; + } + stack stackNode; + ListNode* node = pHead; + int cnt = num / 2; + while (cnt) { + stackNode.push(node); + node = node->next; + cnt--; + } + if (num % 2 == 0) {//偶数 + while (node != nullptr && !stackNode.empty() && node->val == stackNode.top()->val) { + stackNode.pop(); + node = node->next; + } + if (node == nullptr && stackNode.empty()) { + return true; + } + else return false; + } + else { + node = node->next; + while (node != nullptr && !stackNode.empty() && node->val == stackNode.top()->val) { + stackNode.pop(); + node = node->next; + } + if (node == nullptr && stackNode.empty()) { + return true; + } + else return false; + } + return false; + } +}; +``` \ No newline at end of file diff --git "a/\345\210\267\351\242\230/\347\254\224\350\257\225\351\242\230.md" "b/\345\210\267\351\242\230/\347\254\224\350\257\225\351\242\230.md" new file mode 100644 index 0000000..b42bb69 --- /dev/null +++ "b/\345\210\267\351\242\230/\347\254\224\350\257\225\351\242\230.md" @@ -0,0 +1,110 @@ +`VScode调试技巧` + +[官方参考文档](https://docs.microsoft.com/zh-cn/visualstudio/debugger/using-breakpoints?view=vs-2017) + +## 讯飞笔试题 + +### 1. 手链问题,判断一个字符串是否是回文 + +题目描述:散散有一个特别好看的手链,这个手链一开始只有若干个珠子,用大写字母表示,例如:AB,我们可以让珠子沿着手链两个方向复制翻转,变成ABBA或者BAAB,再复制一次变成ABBAABBA或者BAABBAAB,现在散散想知道需要至少多少珠子,经过翻转复制后形成现在的手链。例如:ABC,至少需要ABC这3个珠子。 + +输入 + +```ABBAABBA``` + +输出 + +```2``` + +```C++ +#include +#include +#include +#include +using namespace std; + +bool isPalindrome(string& s) { + string tmp = s; + reverse(tmp.begin(), tmp.end()); + if (tmp == s) return true; + else return false; +} +int getRes(string& s) { + int len = s.length(); + if (len == 0) return 0; + if (len % 2 == 1) return len; + + bool flag = isPalindrome(s); + while (flag) { + s = s.substr(0, len / 2); + if (s.length() % 2 == 1) return s.length(); + flag = isPalindrome(s); + len = s.length(); + } + + return s.length(); +} +int main() { + string str; + cin >> str; + cout << getRes(str) << endl; + system("pause"); + return 0; +} + +``` +### 2. 对数组元素进行轮换 +题目描述:黄警司和阿仁又在天台见面了,最近韩琛在查内鬼,所以他们俩今天来是要更换新的情报传输密码。加密方式:情报长度为n,有一个长度为n的数组p,里面的数字各不相同(1<=i<=n,1<=p[i]<=n),然后对情报进行m次轮换。每次轮换是将情报中的第i个字符换到p[i]上面去。输入情报的长度不会超过n,如果长度没有到n就在后面补上空格到n。 +输入: +``` +2 //n +2 1 //数组p +1 AB // m 和 情报 +2 CD // m 和 情报 +0 // m=0结束加密 +``` +输出 +``` +BA +CD +``` + +```C++ +#include +#include +#include +using namespace std; + +int main() { + int n; + cin >> n; + int tmp; + vector p; + for (int i = 0; i < n; i++) { + cin >> tmp; + p.push_back(tmp-1); + } + int m; + cin >> m; + vector output; + while (m) { + string str; + cin >> str; + while (str.length() < n) str += " "; + string res = str; + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + res[p[j]] = str[j]; + } + str = res; + } + output.push_back(str); + cin >> m; + } + for (auto i : output) + cout << i << endl; + system("pause"); + return 0; +} +``` + diff --git "a/\345\210\267\351\242\230/\347\274\226\347\250\213\344\271\213\347\276\216.md" "b/\345\210\267\351\242\230/\347\274\226\347\250\213\344\271\213\347\276\216.md" new file mode 100644 index 0000000..f07d083 --- /dev/null +++ "b/\345\210\267\351\242\230/\347\274\226\347\250\213\344\271\213\347\276\216.md" @@ -0,0 +1,22 @@ + +* [1. CPU占用率曲线](#1-CPU占用率曲线) + + +# 1. CPU占用率曲线 +```C++ +#include +#include +using namespace std; + +int main() { + for (;;) { + for (int i = 0; i < 96000000; i++); + Sleep(10); + } + system("pause"); + return 0; +} +``` +这大概也能算一条直线吧,n值还没调。 +
+

\ No newline at end of file diff --git "a/\345\210\267\351\242\230/\351\230\277\351\207\214.md" "b/\345\210\267\351\242\230/\351\230\277\351\207\214.md" new file mode 100644 index 0000000..e69de29 diff --git "a/\350\256\272\346\226\207/Redis.md" "b/\350\256\272\346\226\207/Redis.md" new file mode 100644 index 0000000..a92385b --- /dev/null +++ "b/\350\256\272\346\226\207/Redis.md" @@ -0,0 +1,102 @@ +## Redis数据库 + +## 在window上使用celery4.2.1配置redis +``` +conda env list +activate emma +pip install celery +pip install redis +``` +在当前目录下编写tasks.py +```Python +from celery import Celery +broker = "redis://127.0.0.1:6379/0" +backend = "redis://127.0.0.1:6379/0" +app = Celery("tasks", broker=broker, backend=backend) +@app.task +def add(x, y): +return x+y +``` +`celery -A tasks worker --loglevel=info`启动Celery Worker开始监听并执行任务 +其中`-A`表示的是Celery APP的名称,指的是tasks.py,tasks是APP的名称,worker是一个执行任务角色,loglevel=info记录日志类型默认是info,这个命令启动了一个worker,用来执行程序中add这个加法任务 +``` +[2019-02-18 21:54:53,370: INFO/MainProcess] mingle: all alone +[2019-02-18 21:54:53,380: INFO/MainProcess] celery@xx ready. +``` +可以看到Celery正常工作在名称为xx的主机上,当前APP是tasks,运输工具是在程序中设置的中间人redis://127.0.0.1:6379/0,此时重新打开一个终端,执行Python,进入Python交互界面,用delay()方法调用任务 + +调用任务 +```Python +from tasks import add +add.delay(6, 6) +``` +结果 +``` +[2019-02-18 22:03:27,252: INFO/MainProcess] Received task: tasks.add[211c316c-d9ea-4301-81e9-a21212a3992e] +[2019-02-18 22:03:27,256: ERROR/MainProcess] Task handler raised error: ValueError('not enough values to unpack (expected 3, got 0)',) +Traceback (most recent call last): + File "c:\users\lab\anaconda3\envs\emma\lib\site-packages\billiard\pool.py", line 358, in workloop + result = (True, prepare_result(fun(*args, **kwargs))) + File "c:\users\lab\anaconda3\envs\emma\lib\site-packages\celery\app\trace.py", line 537, in _fast_trace_task + tasks, accept, hostname = _loc +ValueError: not enough values to unpack (expected 3, got 0) +``` +第一行表明worker收到一个任务:tasks.add,这个时候出现一个错误`ValueError: not enough values to unpack (expected 3, got 0)` + +解决方法 +在两个命令行终端输入: +``` +set FORKED_BY_MULTIPROCESSING = 1 +``` +如下: +``` +(emma) E:\emma>set FORKED_BY_MULTIPROCESSING=1 + +(emma) E:\emma>celery -A tasks worker --loglevel=info + + -------------- celery@xx v4.2.1 (windowlicker) +---- **** ----- +--- * *** * -- Windows-10-10.0.17134-SP0 2019-02-19 14:57:37 +-- * - **** --- +- ** ---------- [config] +- ** ---------- .> app: tasks:0x20a4efdfcf8 +- ** ---------- .> transport: redis://127.0.0.1:6379/0 +- ** ---------- .> results: redis://127.0.0.1:6379/0 +- *** --- * --- .> concurrency: 8 (prefork) +-- ******* ---- .> task events: OFF (enable -E to monitor tasks in this worker) +--- ***** ----- + -------------- [queues] + .> celery exchange=celery(direct) key=celery + + +[tasks] + . tasks.add + +[2019-02-19 14:57:37,234: INFO/MainProcess] Connected to redis://127.0.0.1:6379/0 +[2019-02-19 14:57:37,268: INFO/MainProcess] mingle: searching for neighbors +[2019-02-19 14:57:38,115: INFO/SpawnPoolWorker-3] child process 7124 calling self.run() +[2019-02-19 14:57:38,115: INFO/SpawnPoolWorker-1] child process 15932 calling self.run() +[2019-02-19 14:57:38,115: INFO/SpawnPoolWorker-4] child process 18320 calling self.run() +[2019-02-19 14:57:38,115: INFO/SpawnPoolWorker-6] child process 17664 calling self.run() +[2019-02-19 14:57:38,131: INFO/SpawnPoolWorker-5] child process 4384 calling self.run() +[2019-02-19 14:57:38,134: INFO/SpawnPoolWorker-8] child process 14528 calling self.run() +[2019-02-19 14:57:38,134: INFO/SpawnPoolWorker-7] child process 7600 calling self.run() +[2019-02-19 14:57:38,134: INFO/SpawnPoolWorker-2] child process 13768 calling self.run() +[2019-02-19 14:57:38,316: INFO/MainProcess] mingle: all alone +[2019-02-19 14:57:38,338: INFO/MainProcess] celery@DESKTOP-P278GU7 ready. +[2019-02-19 14:58:08,367: INFO/MainProcess] Received task: tasks.add[eedda814-3404-4c16-8e9f-5a97c9ff4bd0] +[2019-02-19 14:58:08,378: INFO/SpawnPoolWorker-3] Task tasks.add[eedda814-3404-4c16-8e9f-5a97c9ff4bd0] succeeded in 0.015000000013969839s: 4 +``` +另一个终端: +``` +(emma) E:\emma>set FORKED_BY_MULTIPROCESSING=1 + +(emma) E:\emma>python +Python 3.6.2 |Continuum Analytics, Inc.| (default, Jul 20 2017, 12:30:02) [MSC v.1900 64 bit (AMD64)] on win32 +Type "help", "copyright", "credits" or "license" for more information. +>>> from tasks import add +>>> add.delay(2,2) + +>>> +``` +或者新建环境变量`FORKED_BY_MULTIPROCESSING`,将其值设置为1. diff --git "a/\350\256\272\346\226\207/Redis/\351\205\215\347\275\256Redis.md.pdf" "b/\350\256\272\346\226\207/Redis/\351\205\215\347\275\256Redis.md.pdf" new file mode 100644 index 0000000..11613a8 Binary files /dev/null and "b/\350\256\272\346\226\207/Redis/\351\205\215\347\275\256Redis.md.pdf" differ