├── .gitignore ├── LICENSE ├── README.md ├── code4interview └── c++ │ ├── 面试题03. 数组中重复的数字.cpp │ ├── 面试题04. 二维数组中的查找.cpp │ ├── 面试题05. 替换空格.cpp │ ├── 面试题06. 从尾到头打印链表.cpp │ ├── 面试题07. 重建二叉树.cpp │ ├── 面试题09. 用两个栈实现队列.cpp │ ├── 面试题10- I. 斐波那契数列.cpp │ ├── 面试题10- II. 青蛙跳台阶问题.cpp │ ├── 面试题11. 旋转数组的最小数字.cpp │ ├── 面试题12. 矩阵中的路径.cpp │ ├── 面试题13. 机器人的运动范围.cpp │ ├── 面试题14- I. 剪绳子.cpp │ ├── 面试题15. 二进制中1的个数.cpp │ ├── 面试题16. 数值的整数次方.cpp │ ├── 面试题18. 删除链表的节点.cpp │ ├── 面试题21. 调整数组顺序使奇数位于偶数前面.cpp │ ├── 面试题22. 链表中倒数第k个节点.cpp │ ├── 面试题24. 反转链表.cpp │ ├── 面试题25. 合并两个排序的链表.cpp │ ├── 面试题26. 树的子结构.cpp │ ├── 面试题27. 二叉树的镜像.cpp │ ├── 面试题28. 对称的二叉树.cpp │ ├── 面试题29. 顺时针打印矩阵.cpp │ ├── 面试题30. 包含min函数的栈.cpp │ ├── 面试题32 - I. 从上到下打印二叉树.cpp │ ├── 面试题32 - II. 从上到下打印二叉树 II.cpp │ ├── 面试题32 - III. 从上到下打印二叉树 III.cpp │ ├── 面试题33. 二叉搜索树的后序遍历序列.cpp │ ├── 面试题34. 二叉树中和为某一值的路径.cpp │ ├── 面试题35. 复杂链表的复制.cpp │ ├── 面试题36. 二叉搜索树与双向链表.cpp │ ├── 面试题37. 序列化二叉树.cpp │ ├── 面试题38. 字符串的排列.cpp │ ├── 面试题39. 数组中出现次数超过一半的数字.cpp │ ├── 面试题40. 最小的k个数.cpp │ ├── 面试题42. 连续子数组的最大和.cpp │ ├── 面试题47. 礼物的最大价值.cpp │ ├── 面试题50. 第一个只出现一次的字符.cpp │ ├── 面试题51. 数组中的逆序对.cpp │ ├── 面试题52. 两个链表的第一个公共节点.cpp │ ├── 面试题53 - I. 在排序数组中查找数字 I.cpp │ ├── 面试题53 - II. 0~n-1中缺失的数字.cpp │ ├── 面试题54. 二叉搜索树的第k大节点.cpp │ ├── 面试题55 - I. 二叉树的深度.cpp │ ├── 面试题55 - II. 平衡二叉树.cpp │ ├── 面试题56 - I. 数组中数字出现的次数.cpp │ ├── 面试题56 - II. 数组中数字出现的次数 II.cpp │ ├── 面试题57 - II. 和为s的连续正数序列.cpp │ ├── 面试题57. 和为s的两个数字.cpp │ ├── 面试题58 - I. 翻转单词顺序.cpp │ ├── 面试题58 - II. 左旋转字符串.cpp │ ├── 面试题59 - I. 滑动窗口的最大值.cpp │ ├── 面试题62. 圆圈中最后剩下的数字.cpp │ ├── 面试题63. 股票的最大利润.cpp │ ├── 面试题64. 求1+2+…+n.cpp │ ├── 面试题65. 不用加减乘除做加法.cpp │ ├── 面试题66. 构建乘积数组.cpp │ ├── 面试题68 - I. 二叉搜索树的最近公共祖先.cpp │ └── 面试题68 - II. 二叉树的最近公共祖先.cpp ├── leetcode-algorithms ├── 001. Two Sum │ ├── Solution.java │ ├── solution.cpp │ ├── twoSum.js │ └── two_sum.py ├── 002. Add Two Numbers │ ├── AddTwoNumbers.js │ └── solution.py ├── 003. Longest Substring Without Repeating Characters │ └── solution.py ├── 004. Median of Two Sorted Arrays │ ├── findMedianOfTwoArray.js │ └── solution.py ├── 005. Longest Palindromic Substring │ └── solution.py ├── 006. ZigZag Conversion │ └── solution.py ├── 007. Reverse Integer │ ├── reverse.js │ └── solution.py ├── 009. Palindrome Number │ └── solution.py ├── 011. Container With Most Water │ └── watercontainer.js ├── 012. Integer to Roman │ └── solution.py ├── 013. Roman to Integer │ ├── romanToInt.js │ └── solution.py ├── 014. Longest Common Prefix │ ├── longestPre.js │ └── solution.py ├── 015. 3Sum │ ├── 3Sum.js │ └── 3sum.py ├── 016. 3Sum Closest │ └── 3sumClosest.js ├── 017. Letter Combinations of a Phone Number │ └── solution.py ├── 018. 4Sum │ └── 4sum.js ├── 020. Valid Parentheses │ ├── isValid.js │ └── solution.py ├── 021. Merge Two Sorted Lists │ └── MergeTwoSortedLists.js ├── 026. Remove Duplicates from Sorted Array │ └── removeDuplicates.js ├── 027. Remove Element │ └── removeElement.js ├── 028. Implement strStr() │ └── strStr.js ├── 031. Next Permutation │ └── nextPermutation.js ├── 033. Search in Rotated Sorted Array │ └── search.js ├── 034. Search for a Range │ └── searchForARange.js ├── 035. Search Insert Position │ └── searchInsert.js ├── 038. Count and Say │ └── solution.py ├── 039. Combination Sum │ └── combinationSum.js ├── 040. Combination Sum II │ └── combinationSumTwo.js ├── 041. First Missing Positive │ └── firstMissingPositive.js ├── 043. Multiply Strings │ └── solution.py ├── 048. Rotate Image │ ├── rotate.js │ └── solution.py ├── 050. Pow(x, n) │ └── myPow.js ├── 053. Maximum Subarray │ └── maxSubArray.js ├── 054. Spiral Matrix │ └── spiralOrder.js ├── 055. Jump Game │ └── canjmp.js ├── 058. Length of Last Word │ └── solution.py ├── 059. Spiral Matrix II │ └── generateMatrix.js ├── 066. Plus One │ └── plusOne.js ├── 067. Add Binary │ └── addBinary.js ├── 069. Sqrt(x) │ └── mySqt.js ├── 070. Climbing Stairs │ └── solution.py ├── 083. Remove Duplicates from Sorted List │ └── deleteDuplicates.js ├── 084. Largest Rectangle in Histogram │ └── largestRectangleArea.js ├── 088. Merge Sorted Array │ └── mergeSortedArray.js ├── 092. Reverse Linked List II │ └── solution.py ├── 100. Same Tree │ └── isSameTree.js ├── 101. Symmetric Tree │ └── isSymmetric.js ├── 102. Binary Tree Level Order Traversal │ └── solution.py ├── 104. Maximum Depth of Binary Tree │ └── solution.py ├── 107. Binary Tree Level Order Traversal II │ └── solution.py ├── 108. Convert Sorted Array to Binary Search Tree │ └── solution.py ├── 110. Balanced Binary Tree │ └── solution.py ├── 111. Minimum Depth of Binary Tree │ └── solution.py ├── 112. Path Sum │ └── solution.py ├── 118. Pascal's Triangle │ └── solution.py ├── 119. Pascal's Triangle II │ └── solution.py ├── 121. Best Time to Buy and Sell Stock │ └── maxProfit.js ├── 122. Best Time to Buy and Sell Stock II │ └── maxProfit.js ├── 123. Best Time to Buy and Sell Stock III │ └── maxProfit.js ├── 125. Valid Palindrome │ └── solution.py ├── 136. Single Number │ └── singleNumber.js ├── 137. Single Number II │ └── singleNumber2.js ├── 141. Linked List Cycle │ └── solution.py ├── 155. Min Stack │ └── solution.py ├── 160. Intersection of Two Linked Lists │ └── solution.py ├── 167. Two Sum II - Input array is sorted │ └── twoSum.js ├── 168. Excel Sheet Column Title │ └── solution.py ├── 169. Majority Element │ └── majorityElement.js ├── 171. Excel Sheet Column Number │ └── solution.py ├── 172. Factorial Trailing Zeroes │ └── solution.py ├── 189. Rotate Array │ └── rotate.js ├── 204. Count Primes │ └── solution.py ├── 205. Isomorphic Strings │ └── solution.py ├── 206. Reverse Linked List │ └── solution.py ├── 215. Kth Largest Element in an Array │ └── kthLagestElement.js ├── 217. Contains Duplicate │ └── containDumplicated.js ├── 219. Contains Duplicate II │ └── containsNearbyDumplicate.js ├── 220. Contains Duplicate III │ └── containsNearbyAlmostDuplicate.js ├── 221. Maximal Square │ └── solution.py ├── 226. Invert Binary Tree │ └── solution.py ├── 234. Palindrome Linked List │ └── solution.py ├── 268. Missing Number │ └── missingNumber.js ├── 278. First Bad Version │ └── firstBadVersion.js ├── 283. Move Zeroes │ └── moveZeroes.js ├── 287. Find the Duplicate Number │ └── findDuplicateNumber.js ├── 349. Intersection of Two Arrays │ └── intersection.js ├── 350. Intersection of Two Arrays II │ └── intersect.js ├── 367. Valid Perfect Square │ └── isPerfectSquare.js ├── 374. Guess Number Higher or Lower │ └── guessNumber.py ├── 414. Third Maximum Number │ └── thirdMax.js ├── 415. Add Strings │ └── solution.py ├── 442. Find All Duplicates in an Array │ └── findDuplicates.js ├── 448. Find All Numbers Disappeared in an Array │ └── findDisappearedNumbers.js ├── 453. Minimum Moves to Equal Array Elements │ └── solution.py ├── 462. Minimum Moves to Equal Array Elements II │ └── solution.py ├── 485. Max Consecutive Ones │ └── consectiveOnes.js ├── 609. Find Duplicate File in System │ └── solution.py ├── 637. Average of Levels in Binary Tree │ └── solution.py └── 725. Split Linked List in Parts │ └── solution.py └── scripts ├── 1.png ├── 2.png ├── 3.png ├── readme.md └── readme.py /.gitignore: -------------------------------------------------------------------------------- 1 | data 2 | 3 | # Byte-compiled / optimized / DLL files 4 | __pycache__/ 5 | *.py[cod] 6 | *$py.class 7 | 8 | # Editor directories and files 9 | .idea 10 | .vscode 11 | 12 | # C extensions 13 | *.so 14 | 15 | # Distribution / packaging 16 | .Python 17 | build/ 18 | develop-eggs/ 19 | dist/ 20 | downloads/ 21 | eggs/ 22 | .eggs/ 23 | lib/ 24 | lib64/ 25 | parts/ 26 | sdist/ 27 | var/ 28 | wheels/ 29 | *.egg-info/ 30 | .installed.cfg 31 | *.egg 32 | MANIFEST 33 | 34 | # PyInstaller 35 | # Usually these files are written by a python script from a template 36 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 37 | *.manifest 38 | *.spec 39 | 40 | # Installer logs 41 | pip-log.txt 42 | pip-delete-this-directory.txt 43 | 44 | # Unit test / coverage reports 45 | htmlcov/ 46 | .tox/ 47 | .coverage 48 | .coverage.* 49 | .cache 50 | nosetests.xml 51 | coverage.xml 52 | *.cover 53 | .hypothesis/ 54 | 55 | # Translations 56 | *.mo 57 | *.pot 58 | 59 | # Django stuff: 60 | *.log 61 | .static_storage/ 62 | .media/ 63 | local_settings.py 64 | 65 | # Flask stuff: 66 | instance/ 67 | .webassets-cache 68 | 69 | # Scrapy stuff: 70 | .scrapy 71 | 72 | # Sphinx documentation 73 | docs/_build/ 74 | 75 | # PyBuilder 76 | target/ 77 | 78 | # Jupyter Notebook 79 | .ipynb_checkpoints 80 | 81 | # pyenv 82 | .python-version 83 | 84 | # celery beat schedule file 85 | celerybeat-schedule 86 | 87 | # SageMath parsed files 88 | *.sage.py 89 | 90 | # Environments 91 | .env 92 | .venv 93 | env/ 94 | venv/ 95 | ENV/ 96 | env.bak/ 97 | venv.bak/ 98 | 99 | # Spyder project settings 100 | .spyderproject 101 | .spyproject 102 | 103 | # Rope project settings 104 | .ropeproject 105 | 106 | # mkdocs documentation 107 | /site 108 | 109 | # mypy 110 | .mypy_cache/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 BBruceyuan 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /code4interview/c++/面试题03. 数组中重复的数字.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | using namespace std; 6 | 7 | // 每次都可以先自己定义一个 MyException 8 | class MyException: public exception { 9 | public: 10 | std::string s; 11 | explicit MyException(std::string str): s(std::move(str)) {}; 12 | const char* what() const noexcept override {return s.c_str();}; 13 | }; 14 | 15 | 16 | 17 | class Solution { 18 | public: 19 | int findRepeatNumber(vector& nums) { 20 | for (std::size_t i = 0; i < nums.size(); i++) { 21 | while (nums[i] != i) { 22 | if (nums[nums[i]] != nums[i]) 23 | std::swap(nums[i], nums[nums[i]]); 24 | else 25 | return nums[i]; 26 | } 27 | } 28 | // 如果满足题目要求,这里不会到达 29 | // throw MyException("不能运行到这里"); 30 | return -1; 31 | } 32 | 33 | int findRepeatNumber2(vector& nums) { 34 | // 可以直接使用 hash map 35 | unordered_map m; 36 | for (auto i: nums) { 37 | if (m.find(i) == m.end()) { 38 | m[i] = true; 39 | } else 40 | return i; 41 | } 42 | throw MyException("不可能到达这里"); 43 | } 44 | }; 45 | 46 | int main() { 47 | vector nums {0, 2, 2}; 48 | cout << Solution::findRepeatNumber(nums) << endl; 49 | cout << Solution::findRepeatNumber2(nums) << endl; 50 | return 0; 51 | } -------------------------------------------------------------------------------- /code4interview/c++/面试题04. 二维数组中的查找.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | 6 | class Solution { 7 | public: 8 | bool findNumberIn2DArray(vector>& matrix, int target) { 9 | // 直接暴力遍历每一个数字 10 | bool flag = false; 11 | for (const auto& v: matrix) { 12 | // v 是一个 arr 13 | for (const auto& i: v) { 14 | if (i == target) { 15 | flag = true; 16 | } 17 | } 18 | } 19 | return flag; 20 | 21 | } 22 | bool findNumberIn2DArray2(vector> &matrix, int target) { 23 | // 这这个使用 数组规律做题 24 | if (matrix.empty()) return false; 25 | int colIdx = 0, rowIdx = int(matrix.size()) - 1; 26 | while (colIdx < matrix[0].size() && rowIdx >= 0) { 27 | if (matrix[rowIdx][colIdx] == target) { 28 | return true; 29 | } else if (matrix[rowIdx][colIdx] > target) { 30 | rowIdx--; 31 | } else { 32 | colIdx++; 33 | } 34 | } 35 | return false; 36 | } 37 | 38 | int findNumberIn2DArray3(vector> &matrix, int target) { 39 | // 还可以使用二分法做题 40 | // 这种方法其实并不建议 41 | // TODO: 需要 Debug 42 | 43 | if (matrix.empty() or matrix[0].empty()) 44 | return false; 45 | 46 | int low = 0, high = int(matrix.size()) -1; 47 | int mid; 48 | while (low < high) { 49 | mid = low + (high - low + 1) / 2; 50 | if (matrix[mid][0] > target) 51 | high = mid -1; 52 | else 53 | low = mid; 54 | } 55 | int rowIdx = low; 56 | int left = 0, right = (int)matrix[0].size() -1; 57 | while (left < right) { 58 | mid = left + (right - left + 1) / 2; 59 | if (matrix[rowIdx][mid] > target) { 60 | right = mid -1; 61 | } else 62 | left = mid; 63 | } 64 | // 这个时候 left 一定等于 right 65 | return matrix[rowIdx][left] == target; 66 | } 67 | }; 68 | 69 | int main() { 70 | Solution solution; 71 | vector> nums { 72 | {1, 4, 7, 11, 15}, 73 | {2, 5, 8, 12, 19}, 74 | {3, 6, 9, 16, 22}, 75 | {10, 13, 14, 17, 24}, 76 | {18, 21, 23, 26, 30}}; 77 | 78 | // vector> nums; 79 | // cout << solution.findNumberIn2DArray(nums, 9) << endl; 80 | // cout << solution.findNumberIn2DArray2(nums, 3) << endl; 81 | cout << solution.findNumberIn2DArray3(nums, 5) << endl; 82 | return 0; 83 | } -------------------------------------------------------------------------------- /code4interview/c++/面试题05. 替换空格.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | 6 | class Solution { 7 | public: 8 | string replaceSpace(string s) { 9 | string::size_type pos(0); 10 | while (true) { 11 | if((pos=s.find(' ', pos))!=string::npos) { 12 | s.replace(pos,1,"%20");//替换 13 | pos += 3; 14 | } 15 | else break; 16 | } 17 | return s; 18 | } 19 | 20 | string replaceSpace2(string s) { 21 | if (s.empty()) return s; 22 | int spaceCount = 0; 23 | for (const auto & i: s) { 24 | if (i == ' ')spaceCount++; 25 | } 26 | std::size_t oldLen = s.size(); 27 | 28 | std::size_t newLen = s.size() + spaceCount * 2; 29 | s.resize(newLen); 30 | while (oldLen != newLen) { 31 | --oldLen; 32 | if (s[oldLen] == ' ') { 33 | s[--newLen] = '0'; 34 | s[--newLen] = '2'; 35 | s[--newLen] = '%'; 36 | } else 37 | s[--newLen] = s[oldLen]; 38 | } 39 | return s; 40 | } 41 | }; 42 | 43 | int main() { 44 | Solution solution; 45 | string s = "hello world"; 46 | 47 | cout << solution.replaceSpace2( 48 | "We are happy.") << endl; 49 | return 0; 50 | } 51 | -------------------------------------------------------------------------------- /code4interview/c++/面试题06. 从尾到头打印链表.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | /** 9 | * Definition for singly-linked list. 10 | * struct ListNode { 11 | * int val; 12 | * ListNode *next; 13 | * ListNode(int x) : val(x), next(NULL) {} 14 | * }; 15 | */ 16 | 17 | 18 | struct ListNode { 19 | int val; 20 | ListNode *next; 21 | explicit ListNode(int x) : val(x), next(nullptr) {} 22 | }; 23 | 24 | /** 25 | * Definition for singly-linked list. 26 | * struct ListNode { 27 | * int val; 28 | * ListNode *next; 29 | * ListNode(int x) : val(x), next(NULL) {} 30 | * }; 31 | */ 32 | class Solution { 33 | public: 34 | vector reversePrint(ListNode* head) { 35 | vector res; 36 | stack s; 37 | while(head) { 38 | s.push(head->val); 39 | head = head->next; 40 | } 41 | while (!s.empty()) { 42 | res.push_back(s.top()); 43 | s.pop(); 44 | } 45 | 46 | return res; 47 | } 48 | 49 | vector reversePrint2(ListNode *head) { 50 | vector res; 51 | reversePrintRecursive(head, res); 52 | return res; 53 | } 54 | 55 | void reversePrintRecursive(ListNode *head, vector &res) { 56 | // 这是一个辅助函数 57 | if (head == nullptr) return; 58 | reversePrintRecursive(head->next, res); 59 | res.push_back(head->val); 60 | } 61 | }; 62 | 63 | int main() { 64 | Solution solution; 65 | auto *head = new ListNode(0); 66 | auto cur = head; 67 | for (int i = 0; i < 5; i++) { 68 | cur->next = new ListNode(i); 69 | cur = cur->next; 70 | } 71 | cur->next = nullptr; 72 | vector res = solution.reversePrint2(head->next); 73 | for (auto i: res) { 74 | cout << i << endl; 75 | } 76 | return 0; 77 | } -------------------------------------------------------------------------------- /code4interview/c++/面试题07. 重建二叉树.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | 9 | /** 10 | * Definition for a binary tree node. 11 | * struct TreeNode { 12 | * int val; 13 | * TreeNode *left; 14 | * TreeNode *right; 15 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 16 | * }; 17 | */ 18 | 19 | struct TreeNode { 20 | int val; 21 | TreeNode *left; 22 | TreeNode *right; 23 | explicit TreeNode(int x): val(x), left(nullptr), right(nullptr) {} 24 | }; 25 | 26 | 27 | class Solution { 28 | public: 29 | TreeNode* buildTree(vector& preorder, vector& inorder) { 30 | // 找到中止条件 31 | if (preorder.empty()) return nullptr; 32 | 33 | // 首先简历树的根节点 34 | auto root = new TreeNode(preorder[0]); 35 | // 下一步是获取 左子树的 preorder 和 inorder 36 | auto it = std::find(inorder.begin(), inorder.end(), preorder[0]); 37 | 38 | vector leftInOrder(inorder.begin(), it); 39 | // 不能包括第一个数字 40 | vector rightInOrder(it + 1, inorder.end()); 41 | 42 | vector leftPreOrder(preorder.begin() + 1, preorder.begin() + 1 + leftInOrder.size()); 43 | vector rightPreOrder(preorder.begin() + 1 + leftInOrder.size(), preorder.end()); 44 | 45 | root->left = buildTree(leftPreOrder, leftInOrder); 46 | root->right = buildTree(rightPreOrder, rightInOrder); 47 | return root; 48 | } 49 | 50 | TreeNode* buildTreeNoRecursive(vector& preorder, vector& inorder) { 51 | if (preorder.empty()) return nullptr; 52 | stack roots; 53 | std::size_t pre = 0, in = 0; 54 | 55 | auto root = new TreeNode(preorder[pre]); 56 | auto returnRoot = root; 57 | roots.push(root); 58 | pre++; 59 | 60 | while (pre < preorder.size()) { 61 | if (root->val == inorder[in]) { 62 | while (!roots.empty() && roots.top()->val == inorder[in]) { 63 | root = roots.top(); 64 | roots.pop(); 65 | in++; 66 | } 67 | root->right = new TreeNode(preorder[pre]); 68 | root = root->right; 69 | roots.push(root); 70 | pre++; 71 | } else { 72 | root->left = new TreeNode(preorder[pre]); 73 | root = root->left; 74 | roots.push(root); 75 | pre++; 76 | } 77 | } 78 | return returnRoot; 79 | } 80 | 81 | }; 82 | 83 | int main() { 84 | Solution solution; 85 | vector preorder{3,5, 9,10, 20,15,7}, inorder{9,5, 10, 3,15,20,7}; 86 | solution.buildTreeNoRecursive(preorder, inorder); 87 | return 0; 88 | } -------------------------------------------------------------------------------- /code4interview/c++/面试题09. 用两个栈实现队列.cpp: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | using namespace std; 4 | 5 | 6 | class CQueue { 7 | public: 8 | stack s1; 9 | stack s2; 10 | int res; 11 | CQueue() { 12 | 13 | } 14 | 15 | void appendTail(int value) { 16 | s1.push(value); 17 | } 18 | 19 | int deleteHead() { 20 | if (!s2.empty()) { 21 | res = s2.top(); 22 | s2.pop(); 23 | return res; 24 | } else { 25 | // 如果 s2 为空 26 | if (s1.empty()) return -1; 27 | else { 28 | // 那么把 s1 的元素压入 s2 中 29 | while (!s1.empty()) { 30 | s2.push(s1.top()); 31 | s1.pop(); 32 | } 33 | res = s2.top(); 34 | s2.pop(); 35 | return res; 36 | } 37 | } 38 | } 39 | 40 | }; 41 | 42 | /** 43 | * Your CQueue object will be instantiated and called as such: 44 | * CQueue* obj = new CQueue(); 45 | * obj->appendTail(value); 46 | * int param_2 = obj->deleteHead(); 47 | */ 48 | -------------------------------------------------------------------------------- /code4interview/c++/面试题10- I. 斐波那契数列.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | 4 | 5 | class Solution { 6 | public: 7 | int fib (int n) { 8 | // 这个其实可以看成是一个优化过后的 dp 问题。 9 | int a = 0, b = 1; 10 | int tmp; 11 | for (std::size_t i = 0; i < n; i++) { 12 | tmp = a + b; 13 | a = b; 14 | b = tmp; 15 | } 16 | a = a % 1000000007; 17 | return a; 18 | } 19 | int fibRecursive(int n) { 20 | // 用来学习递归,会超时 21 | if (n <= 1) { 22 | return n; 23 | } 24 | return fibRecursive(n - 1) + fibRecursive(n-2); 25 | } 26 | }; 27 | 28 | 29 | bool isTrue(int n) { 30 | Solution s; 31 | 32 | return s.fib(n) == s.fibRecursive(n); 33 | } 34 | 35 | 36 | int main () { 37 | Solution solution; 38 | for (int i = 0; i < 15; i++) { 39 | cout << isTrue(i) << endl; 40 | } 41 | // cout << solution.fibRecursive(5) << endl; 42 | return 0; 43 | } -------------------------------------------------------------------------------- /code4interview/c++/面试题10- II. 青蛙跳台阶问题.cpp: -------------------------------------------------------------------------------- 1 | // 这里和 斐波那契数列 可以算作同一个题 2 | // 因此 在这里使用 矩阵快速幂来求解 3 | -------------------------------------------------------------------------------- /code4interview/c++/面试题11. 旋转数组的最小数字.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | 6 | class Solution { 7 | public: 8 | int minArray(vector& numbers) { 9 | // 假设 数组为 5 4 1 2 3 10 | if (numbers.empty()) return 0; 11 | if (numbers.size() == 1) return numbers[0]; 12 | int left = 0, right = numbers.size() -1; 13 | int mid; 14 | while (left < right) { 15 | mid = left + (right - left) / 2; 16 | if (numbers[mid] > numbers[right]) { 17 | left = mid + 1; 18 | } else if (numbers[mid] < numbers[right]) { 19 | right = mid; 20 | } else { 21 | right = right - 1; 22 | } 23 | } 24 | return numbers[left]; 25 | } 26 | 27 | int minArray2(vector &nums) { 28 | if (nums.empty()) return 0; 29 | return minArrayRecursive(nums, 0, nums.size() -1); 30 | } 31 | 32 | int minArrayRecursive(vector &nums, int left, int right) { 33 | if (left == right) return nums[left]; 34 | int mid = left + (right - left) / 2; 35 | if (nums[mid] > nums[right]) { 36 | return minArrayRecursive(nums, mid + 1, right); 37 | } else if (nums[mid] == nums[right]) { 38 | return minArrayRecursive(nums, left, right -1); 39 | } else { 40 | return minArrayRecursive(nums, left, mid); 41 | } 42 | } 43 | }; 44 | 45 | 46 | int main () { 47 | Solution solution; 48 | vector nums {3, 1, 3}; 49 | 50 | cout << solution.minArray2(nums) << endl; 51 | return 0; 52 | } -------------------------------------------------------------------------------- /code4interview/c++/面试题12. 矩阵中的路径.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | class Solution { 7 | public: 8 | bool exist(vector>& board, string word) { 9 | for (std::size_t i = 0; i < board.size(); i++) { 10 | for (std::size_t j = 0; j < board[0].size(); j++) { 11 | if (dfs(board, i, j, word, 0)) return true; 12 | } 13 | } 14 | return false; 15 | } 16 | 17 | bool dfs (vector> &board, size_t i, size_t j, const string& word, size_t idx) { 18 | if (i < 0 || j < 0 || i >= board.size() || j >= board[0].size() || word[idx] != board[i][j]) { 19 | return false; 20 | } 21 | if (idx == word.size() -1) { 22 | return true; 23 | } 24 | 25 | char tmp = board[i][j]; 26 | board[i][j] = '$'; 27 | 28 | bool res = dfs (board, i +1, j, word, idx+1) || dfs(board, i-1, j, word, idx+1) || 29 | dfs (board, i, j -1, word, idx +1) || dfs(board, i, j+1, word, idx+1); 30 | board[i][j] = tmp; 31 | return res; 32 | } 33 | }; 34 | 35 | int main () { 36 | Solution solution; 37 | // vector> b{{'A','B','C','E'},{'S','F','C','S'},{'A','D','E','E'}}; 38 | vector> b{{'A'}}; 39 | std::string s = "Ab"; 40 | 41 | cout << solution.exist(b, s) << endl; 42 | return 0; 43 | } -------------------------------------------------------------------------------- /code4interview/c++/面试题13. 机器人的运动范围.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | using namespace std; 5 | 6 | class Solution { 7 | public: 8 | int movingCount(int m, int n, int k) { 9 | vector> visit(m, vector(n, false)); 10 | int count = 0; 11 | 12 | // 使用 bfs 来做 13 | m = 0, n = 0; 14 | dfs(m, n, k, visit, count); 15 | 16 | return count; 17 | } 18 | 19 | void dfs(int m, int n, int k, 20 | vector> &visit, 21 | int &count) { 22 | 23 | std::pair p(m, n); 24 | if (m < 0 || n < 0 || m > visit.size() -1 || n > visit[0].size() -1 || visit[m][n] || sum(p) > k ) { 25 | // 递归中止条件 26 | return; 27 | } 28 | count += 1; 29 | visit[m][n] = true; 30 | 31 | dfs(m +1, n, k, visit, count); 32 | // bfs(m -1, n, k, visit, count); 33 | dfs(m, n + 1, k, visit, count); 34 | // bfs(m, n - 1, k, visit, count); 35 | } 36 | 37 | int sum(std::pair p) { 38 | int res = 0; 39 | while (p.first) { 40 | res = res + p.first % 10; 41 | p.first /= 10; 42 | } 43 | while (p.second) { 44 | res = res + p.second % 10; 45 | p.second /= 10; 46 | } 47 | return res; 48 | } 49 | 50 | int movingCountBfs(int m, int n, int k) { 51 | vector> visit(m, vector(n, false)); 52 | std::queue> nodes; 53 | std::pair p(0, 0); 54 | int count = 0; 55 | nodes.push(p); 56 | visit[p.first][p.second] = true; 57 | bfs(m, n, k, count, visit, nodes); 58 | return count; 59 | } 60 | 61 | void bfs(int m, int n, int k, int &count, vector> &visit, std::queue> &nodes) { 62 | std::pair p, tmp; 63 | 64 | while (!nodes.empty()) { 65 | p = nodes.front(); 66 | nodes.pop(); 67 | if (sum(p) <= k) { 68 | count++; 69 | } else { 70 | break; 71 | } 72 | tmp = std::make_pair(p.first + 1, p.second); 73 | 74 | if (p.first + 1 >= 0 && p.first + 1 < visit.size() && p.second >= 0 75 | && p.second < visit[0].size() && !visit[p.first + 1][p.second] 76 | && sum(tmp) <= k 77 | ) { 78 | // 把纵向增加 79 | visit[p.first + 1][p.second] = true; 80 | nodes.push(tmp); 81 | } 82 | tmp = std::make_pair(p.first, p.second + 1); 83 | if (p.first >= 0 && p.first < visit.size() && p.second + 1>= 0 84 | && p.second + 1< visit[0].size() && !visit[p.first][p.second + 1] 85 | && sum(tmp) <= k 86 | ) { 87 | // 把纵向增加 88 | visit[p.first][p.second + 1] = true; 89 | nodes.push(tmp); 90 | } 91 | 92 | } 93 | } 94 | 95 | }; 96 | 97 | int main () { 98 | Solution solution; 99 | 100 | cout << solution.movingCount(16, 8, 4) << endl; 101 | cout << solution.movingCountBfs(16, 8, 4) << endl; 102 | return 0; 103 | } 104 | -------------------------------------------------------------------------------- /code4interview/c++/面试题14- I. 剪绳子.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | using namespace std; 11 | 12 | 13 | class Solution { 14 | public: 15 | int cuttingRope(int n) { 16 | // 动态规划,不想使用 数学的那种推到 17 | vector dp(n + 1, 0); 18 | dp[2] = 1; 19 | int tmp; 20 | for (std::size_t i = 3; i <= n; i++) { 21 | for (std::size_t j = 0; j < i; j++) { 22 | // 从 j 出 23 | tmp = std::max((i - j) * j, j * dp[i - j]); 24 | dp[i] = std::max(dp[i], tmp); 25 | } 26 | } 27 | return dp[n]; 28 | } 29 | }; 30 | 31 | 32 | 33 | int main() { 34 | // string s = "[1,2,3,null,null,4,5]"; 35 | string s = "[5,2,3,null,null,2,4,3,1]"; 36 | 37 | 38 | 39 | // string str = "hello world"; 40 | // cout << s.find_last_not_of("world"); 41 | 42 | return 0; 43 | } -------------------------------------------------------------------------------- /code4interview/c++/面试题15. 二进制中1的个数.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | class Solution { 6 | public: 7 | int hammingWeight(uint32_t n) { 8 | int count(0); 9 | 10 | unsigned int flag = 1; 11 | while (flag) { 12 | if (n & flag) 13 | count++; 14 | flag = flag << 1; 15 | } 16 | 17 | return count; 18 | } 19 | 20 | int hammingWeight2(uint32_t n) { 21 | int count(0); 22 | 23 | while (n) { 24 | count++; 25 | n = (n -1) & n; 26 | } 27 | return count; 28 | } 29 | 30 | }; 31 | 32 | int main () { 33 | Solution solution; 34 | int a{2}; 35 | // 其实要无符号整数才可以这么做 36 | int c = a & 1; 37 | cout << c << endl; 38 | 39 | // cout << solution.hammingWeight(a) << endl; 40 | return 0; 41 | } -------------------------------------------------------------------------------- /code4interview/c++/面试题16. 数值的整数次方.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | using namespace std; 11 | 12 | class Solution { 13 | public: 14 | double myPow(double x, int n) { 15 | double res = 1.0; 16 | int i = n; 17 | while (i) { 18 | if (i & 1) res = res * x; 19 | x = x * x; 20 | i /= 2; 21 | } 22 | return n > 0 ? res : 1 /res; 23 | } 24 | }; 25 | 26 | 27 | int main() { 28 | // string s = "[1,2,3,null,null,4,5]"; 29 | 30 | 31 | 32 | // string str = "hello world"; 33 | // cout << s.find_last_not_of("world"); 34 | 35 | return 0; 36 | } -------------------------------------------------------------------------------- /code4interview/c++/面试题18. 删除链表的节点.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | /** 6 | * Definition for singly-linked list. 7 | * struct ListNode { 8 | * int val; 9 | * ListNode *next; 10 | * ListNode(int x) : val(x), next(NULL) {} 11 | * }; 12 | */ 13 | 14 | struct ListNode { 15 | int val; 16 | ListNode *next; 17 | explicit ListNode (int x): val(x), next(nullptr) {}; 18 | }; 19 | 20 | 21 | class Solution { 22 | public: 23 | ListNode *deleteNode (ListNode *head, int val) { 24 | auto dummy = new ListNode(0); 25 | dummy->next = head; 26 | auto pre = dummy; 27 | 28 | while (head) { 29 | if (head->val == val) { 30 | pre->next = head->next; 31 | break; 32 | } else { 33 | pre = head; 34 | head = head->next; 35 | } 36 | } 37 | return dummy->next; 38 | 39 | } 40 | 41 | ListNode* deleteNodeRecursive(ListNode* head, int val) { 42 | if (head->val == val) 43 | return head->next; 44 | head->next = deleteNodeRecursive(head->next, val); 45 | return head; 46 | } 47 | 48 | }; 49 | 50 | int main () { 51 | 52 | return 0; 53 | } -------------------------------------------------------------------------------- /code4interview/c++/面试题21. 调整数组顺序使奇数位于偶数前面.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | 6 | class Solution { 7 | public: 8 | vector exchange(vector& nums) { 9 | if (nums.empty()) return {}; 10 | // 注意的是如果使用了size_t 那么就需要考虑一下溢出问题 11 | // 第一种方法就可以使用双指针的方式 12 | std::size_t left = 0, right = nums.size() -1; 13 | 14 | while (left < right) { 15 | while (left < right && nums[right] %2 ==0) { 16 | right--; 17 | } 18 | while (left < right && nums[left] % 2 == 1) { 19 | left++; 20 | } 21 | std::swap(nums[left], nums[right]); 22 | } 23 | 24 | return nums; 25 | } 26 | 27 | vector pivot(vector &nums) { 28 | // 使用快速排序那种思想去做. 这种 partion 的方法叫做 29 | int left = -1; 30 | 31 | for (std::size_t i = 0; i < nums.size(); i++) { 32 | if (nums[i] % 2 != 0) { 33 | left++; 34 | std::swap(nums[left], nums[i]); 35 | } 36 | } 37 | return nums; 38 | } 39 | }; 40 | 41 | 42 | template 43 | void print(const vector &nums) { 44 | for (const auto & item: nums) { 45 | cout << item << '\t'; 46 | } 47 | cout << endl; 48 | } 49 | 50 | int main () { 51 | vector nums = {2,1, 3, 4, 5}; 52 | Solution s; 53 | // nums = s.exchange(nums); 54 | nums = s.pivot(nums); 55 | print(nums); 56 | return 0; 57 | } -------------------------------------------------------------------------------- /code4interview/c++/面试题22. 链表中倒数第k个节点.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | /** 6 | * Definition for singly-linked list. 7 | * struct ListNode { 8 | * int val; 9 | * ListNode *next; 10 | * ListNode(int x) : val(x), next(NULL) {} 11 | * }; 12 | */ 13 | 14 | struct ListNode { 15 | int val; 16 | ListNode *next; 17 | explicit ListNode (int x): val(x), next(nullptr) {}; 18 | }; 19 | 20 | 21 | class Solution { 22 | public: 23 | ListNode* getKthFromEnd(ListNode* head, int k) { 24 | // 典型使用双指针 25 | auto fast = head; 26 | while (fast && k) { 27 | fast = fast->next; 28 | k--; 29 | } 30 | 31 | while (fast) { 32 | fast = fast->next; 33 | head = head->next; 34 | } 35 | return head; 36 | } 37 | /* 38 | * 或者再两次遍历,或者用数组存储,然后直接定位 39 | * 倒是看到有人用递归,实际上不如 直接用数组 (这点需要注意) 40 | */ 41 | }; 42 | 43 | int main () { 44 | 45 | return 0; 46 | } -------------------------------------------------------------------------------- /code4interview/c++/面试题24. 反转链表.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | /** 6 | * Definition for singly-linked list. 7 | * struct ListNode { 8 | * int val; 9 | * ListNode *next; 10 | * ListNode(int x) : val(x), next(NULL) {} 11 | * }; 12 | */ 13 | 14 | struct ListNode { 15 | int val; 16 | ListNode *next; 17 | explicit ListNode (int x): val(x), next(nullptr) {}; 18 | }; 19 | 20 | 21 | class Solution { 22 | public: 23 | ListNode* reverseList(ListNode *head) { 24 | // 非递归 25 | ListNode* pre = nullptr, *cur = head; 26 | ListNode* nxt; 27 | 28 | while (cur) { 29 | nxt = cur->next; 30 | cur->next = pre; 31 | pre = cur; 32 | cur = nxt; 33 | } 34 | return pre; 35 | } 36 | 37 | ListNode* reverseListRecursive(ListNode* head) { 38 | // 使用递归的方法来做 39 | if (head == nullptr || head->next == nullptr) return head; 40 | auto result = reverseListRecursive(head->next); 41 | head->next->next = head; 42 | head->next = nullptr; 43 | return result; 44 | } 45 | }; 46 | 47 | 48 | int main () { 49 | 50 | return 0; 51 | } -------------------------------------------------------------------------------- /code4interview/c++/面试题25. 合并两个排序的链表.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | 5 | /** 6 | * Definition for singly-linked list. 7 | * struct ListNode { 8 | * int val; 9 | * ListNode *next; 10 | * ListNode(int x) : val(x), next(NULL) {} 11 | * }; 12 | */ 13 | 14 | struct ListNode { 15 | int val; 16 | ListNode *next; 17 | explicit ListNode (int x): val(x), next(nullptr) {}; 18 | }; 19 | 20 | 21 | class Solution { 22 | public: 23 | ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { 24 | auto dummy = new ListNode(0); 25 | auto cur = dummy; 26 | while (l1 && l2) { 27 | if (l1->val < l2->val) { 28 | cur->next = l1; 29 | l1 = l1->next; 30 | } else { 31 | cur->next = l2; 32 | l2 = l2->next; 33 | } 34 | cur = cur->next; 35 | } 36 | if (l1) { 37 | cur->next = l1; 38 | } 39 | if (l2) { 40 | cur->next = l2; 41 | } 42 | return dummy->next; 43 | } 44 | 45 | ListNode *mergeTwoListRecursive(ListNode *l1, ListNode *l2) { 46 | if (l2 == nullptr && l1 == nullptr) return nullptr; 47 | if (l1 == nullptr) return l2; 48 | if (l2 == nullptr) return l1; 49 | 50 | auto dummy = new ListNode(0); 51 | if (l1->val < l2->val) { 52 | dummy->next = l1; 53 | dummy->next->next = mergeTwoListRecursive(l1->next, l2); 54 | } else { 55 | dummy->next = l2; 56 | dummy->next->next = mergeTwoListRecursive(l1, l2->next); 57 | } 58 | 59 | return dummy->next; 60 | } 61 | }; 62 | 63 | 64 | int main () { 65 | 66 | return 0; 67 | } -------------------------------------------------------------------------------- /code4interview/c++/面试题26. 树的子结构.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | 9 | /** 10 | * Definition for a binary tree node. 11 | * struct TreeNode { 12 | * int val; 13 | * TreeNode *left; 14 | * TreeNode *right; 15 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 16 | * }; 17 | */ 18 | 19 | struct TreeNode { 20 | int val; 21 | TreeNode *left; 22 | TreeNode *right; 23 | explicit TreeNode(int x): val(x), left(nullptr), right(nullptr) {} 24 | }; 25 | 26 | 27 | class Solution { 28 | public: 29 | bool isSubStructure(TreeNode* A, TreeNode* B) { 30 | // 首先用 递归来判断 31 | if (!A && !B) return true; 32 | if (!A || !B) return false; 33 | // 否者说明两个节点都不是空 34 | bool res; 35 | if (A->val == B->val) { 36 | // 这里面的判断 1 2 是 1 2 3 的子结构,所一应该单独考虑考虑什么是中止条件 37 | res = haveSubStructure(A, B); 38 | return res; 39 | } 40 | res = isSubStructure(A->left, B) || isSubStructure(A->right, B); 41 | 42 | return res; 43 | } 44 | 45 | bool haveSubStructure (TreeNode *A, TreeNode *B) { 46 | if (!B) return true; 47 | if (!A) return false; 48 | if (A->val != B->val) return false; 49 | 50 | bool res = false; 51 | res = haveSubStructure(A->left, B->left) && haveSubStructure(A->right, B->right); 52 | return res; 53 | } 54 | }; 55 | 56 | int main() { 57 | Solution solution; 58 | return 0; 59 | } -------------------------------------------------------------------------------- /code4interview/c++/面试题27. 二叉树的镜像.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * struct TreeNode { 4 | * int val; 5 | * TreeNode *left; 6 | * TreeNode *right; 7 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 8 | * }; 9 | */ 10 | class Solution { 11 | public: 12 | TreeNode* mirrorTree(TreeNode* root) { 13 | // 简单的递归版本 14 | if (root == nullptr) return root; 15 | auto tmp = root->left; 16 | root->left = mirrorTree(root->right); 17 | root->right = mirrorTree(tmp); 18 | return root; 19 | } 20 | }; -------------------------------------------------------------------------------- /code4interview/c++/面试题28. 对称的二叉树.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | 9 | /** 10 | * Definition for a binary tree node. 11 | * struct TreeNode { 12 | * int val; 13 | * TreeNode *left; 14 | * TreeNode *right; 15 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 16 | * }; 17 | */ 18 | 19 | struct TreeNode { 20 | int val; 21 | TreeNode *left; 22 | TreeNode *right; 23 | explicit TreeNode(int x): val(x), left(nullptr), right(nullptr) {} 24 | }; 25 | 26 | 27 | class Solution { 28 | public: 29 | bool isSymmetric(TreeNode* root) { 30 | if (root == nullptr) return true; 31 | return helpSymmetric(root->left, root->right); 32 | } 33 | 34 | bool helpSymmetric(TreeNode *p, TreeNode *q) { 35 | if (p == nullptr && q == nullptr) return true; 36 | if (p == nullptr || q == nullptr) return false; 37 | if (q->val == p->val) { 38 | return helpSymmetric(q->left, p->right) && helpSymmetric(q->right, p->left); 39 | } else { 40 | return false; 41 | } 42 | } 43 | 44 | }; 45 | 46 | int main() { 47 | Solution solution; 48 | return 0; 49 | } -------------------------------------------------------------------------------- /code4interview/c++/面试题29. 顺时针打印矩阵.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | 9 | class Solution { 10 | public: 11 | vector spiralOrder(vector>& matrix) { 12 | int rowLow = 0, rowHigh= matrix.size() -1, colLeft = 0, colRight = matrix[0].size() -1; 13 | int i; 14 | std::vector res; 15 | 16 | while (rowLow <= rowHigh && colLeft <= colRight) { 17 | // 从左往右 18 | for (i = colLeft; i <= colRight; i++) { 19 | res.push_back(matrix[rowLow][i]); 20 | } 21 | rowLow++; 22 | // 从上往下 23 | for (i = rowLow; i <= rowHigh; i++) { 24 | res.push_back(matrix[i][colRight]); 25 | } 26 | colRight--; 27 | 28 | // 从右往左 29 | for (i = colRight; i >= colLeft && rowLow <= rowHigh; i--) { 30 | res.push_back(matrix[rowHigh][i]); 31 | } 32 | rowHigh--; 33 | 34 | // 从下往上 35 | for (i = rowHigh; i >= rowLow && colLeft <= colRight; i--) { 36 | res.push_back(matrix[i][colLeft]); 37 | } 38 | colLeft++; 39 | } 40 | return res; 41 | } 42 | }; 43 | 44 | 45 | template 46 | void print(const vector &nums) { 47 | for (const auto & i: nums) { 48 | cout << i << ' '; 49 | } 50 | cout << endl; 51 | } 52 | 53 | 54 | int main() { 55 | Solution solution; 56 | vector> nums {{1, 2, 3, 4}, {5, 6, 7, 8},{9, 10, 11, 12}}; 57 | 58 | auto a = solution.spiralOrder(nums); 59 | print(a); 60 | 61 | return 0; 62 | } -------------------------------------------------------------------------------- /code4interview/c++/面试题30. 包含min函数的栈.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | class MinStack { 9 | public: 10 | /** initialize your data structure here. */ 11 | MinStack() { 12 | 13 | } 14 | 15 | void push(int x) { 16 | st.push(x); 17 | if (miniStack.empty() || x <= miniStack.top() ) { 18 | miniStack.push(x); 19 | } 20 | } 21 | 22 | void pop() { 23 | int top = st.top(); 24 | st.pop(); 25 | if (top == miniStack.top()) { 26 | miniStack.pop(); 27 | } 28 | } 29 | 30 | int top() { 31 | return st.top(); 32 | } 33 | 34 | int min() { 35 | return miniStack.top(); 36 | } 37 | 38 | private: 39 | stack st; 40 | stack miniStack; 41 | }; 42 | 43 | 44 | int main() { 45 | MinStack s; 46 | // stack s2; 47 | // 48 | // cout << s.top() << endl; 49 | // return 0; 50 | 51 | s.push(-2); 52 | s.push(0); 53 | s.push(-3); 54 | 55 | cout << s.min() << endl; 56 | s.pop(); 57 | cout << s.top() << endl; 58 | 59 | 60 | return 0; 61 | } -------------------------------------------------------------------------------- /code4interview/c++/面试题32 - I. 从上到下打印二叉树.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | 10 | /** 11 | * Definition for a binary tree node. 12 | * struct TreeNode { 13 | * int val; 14 | * TreeNode *left; 15 | * TreeNode *right; 16 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 17 | * }; 18 | */ 19 | 20 | struct TreeNode { 21 | int val; 22 | TreeNode *left; 23 | TreeNode *right; 24 | explicit TreeNode(int x): val(x), left(nullptr), right(nullptr) {} 25 | }; 26 | 27 | 28 | class Solution { 29 | public: 30 | vector levelOrder(TreeNode* root) { 31 | if (root == nullptr) return {}; 32 | std::queue nodes; 33 | std::vector res; 34 | 35 | nodes.push(root); 36 | TreeNode* cur; 37 | while (!nodes.empty()) { 38 | cur = nodes.front(); 39 | nodes.pop(); 40 | 41 | // 42 | res.push_back(cur->val); 43 | if (cur->left) { 44 | nodes.push(cur->left); 45 | } 46 | if (cur->right) { 47 | nodes.push(cur->right); 48 | } 49 | } 50 | return res; 51 | } 52 | 53 | }; 54 | 55 | int main() { 56 | Solution solution; 57 | return 0; 58 | } -------------------------------------------------------------------------------- /code4interview/c++/面试题32 - II. 从上到下打印二叉树 II.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | 10 | /** 11 | * Definition for a binary tree node. 12 | * struct TreeNode { 13 | * int val; 14 | * TreeNode *left; 15 | * TreeNode *right; 16 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 17 | * }; 18 | */ 19 | 20 | struct TreeNode { 21 | int val; 22 | TreeNode *left; 23 | TreeNode *right; 24 | explicit TreeNode(int x): val(x), left(nullptr), right(nullptr) {} 25 | }; 26 | 27 | 28 | class Solution { 29 | public: 30 | vector> levelOrder(TreeNode* root) { 31 | if (root == nullptr) return {}; 32 | vector> res; 33 | int level(1); 34 | // 试试 decltype 的用法,以下和 queue 是一样的 35 | std::queue> nodes; 36 | nodes.push(std::make_pair(level, root)); 37 | std::pair p; 38 | while (!nodes.empty()) { 39 | p = nodes.front(); 40 | nodes.pop(); 41 | if (res.size() < p.first) { 42 | // TODO: 这个用法待学习,只是根据ide 提示修改的 43 | // 这里等同于 res.push_back({}); 44 | res.emplace_back(); 45 | } 46 | res[p.first -1].push_back(p.second->val); 47 | 48 | if (p.second->left) { 49 | nodes.push(std::make_pair(p.first + 1, p.second->left)); 50 | } 51 | if (p.second->right) { 52 | nodes.push(std::make_pair(p.first + 1, p.second->right)); 53 | } 54 | } 55 | return res; 56 | } 57 | 58 | }; 59 | 60 | int main() { 61 | Solution solution; 62 | 63 | vector> matrix; 64 | cout << matrix.size() << endl; 65 | matrix.push_back({}); 66 | cout << matrix.size() << endl; 67 | cout << matrix[0].size() << endl; 68 | return 0; 69 | } -------------------------------------------------------------------------------- /code4interview/c++/面试题32 - III. 从上到下打印二叉树 III.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | 10 | /** 11 | * Definition for a binary tree node. 12 | * struct TreeNode { 13 | * int val; 14 | * TreeNode *left; 15 | * TreeNode *right; 16 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 17 | * }; 18 | */ 19 | 20 | struct TreeNode { 21 | int val; 22 | TreeNode *left; 23 | TreeNode *right; 24 | explicit TreeNode(int x): val(x), left(nullptr), right(nullptr) {} 25 | }; 26 | 27 | 28 | class Solution { 29 | public: 30 | vector> levelOrder (TreeNode *root) { 31 | // 使用双端队列 32 | if (root == nullptr) return {}; 33 | vector> res; 34 | bool flag = true; 35 | 36 | std::deque nodes; 37 | nodes.push_back(root); 38 | TreeNode *cur; 39 | while (!nodes.empty()) { 40 | vector tmpRes; 41 | 42 | std::size_t n = nodes.size(); 43 | 44 | while (n > 0) { 45 | if (flag) { 46 | // 从前面取 47 | cur = nodes.front(); 48 | nodes.pop_front(); 49 | 50 | if (cur->left) 51 | nodes.push_back(cur->left); 52 | if (cur->right) 53 | nodes.push_back(cur->right); 54 | } else { 55 | cur = nodes.back(); 56 | nodes.pop_back(); 57 | if (cur->right) 58 | nodes.push_front(cur->right); 59 | 60 | if (cur->left) 61 | nodes.push_front(cur->left); 62 | } 63 | n--; 64 | tmpRes.push_back(cur->val); 65 | } 66 | flag = !flag; 67 | res.push_back(tmpRes); 68 | } 69 | return res; 70 | } 71 | 72 | vector> levelOrder2(TreeNode* root) { 73 | // 这里可以用两个栈来实现 74 | if (root == nullptr) return {}; 75 | vector> res; 76 | int level(1); 77 | // 试试 decltype 的用法,以下和 queue 是一样的 78 | std::stack> nodesStack1; 79 | std::stack> nodesStack2; 80 | nodesStack1.push(std::make_pair(level, root)); 81 | 82 | std::pair p; 83 | 84 | while (!nodesStack1.empty() || !nodesStack2.empty()) { 85 | while (!nodesStack1.empty()) { 86 | p = nodesStack1.top(); 87 | nodesStack1.pop(); 88 | if (res.size() < p.first) { 89 | // TODO: 这个用法待学习,只是根据ide 提示修改的 90 | // 这里等同于 res.push_back({}); 91 | res.emplace_back(); 92 | } 93 | res[p.first -1].push_back(p.second->val); 94 | 95 | if (p.second->left) { 96 | nodesStack2.push(std::make_pair(p.first + 1, p.second->left)); 97 | } 98 | if (p.second->right) { 99 | nodesStack2.push(std::make_pair(p.first + 1, p.second->right)); 100 | } 101 | } 102 | while (!nodesStack2.empty()) { 103 | p = nodesStack2.top(); 104 | nodesStack2.pop(); 105 | if (res.size() < p.first) { 106 | // TODO: 这个用法待学习,只是根据ide 提示修改的 107 | // 这里等同于 res.push_back({}); 108 | res.emplace_back(); 109 | } 110 | res[p.first -1].push_back(p.second->val); 111 | if (p.second->right) { 112 | nodesStack1.push(std::make_pair(p.first + 1, p.second->right)); 113 | } 114 | if (p.second->left) { 115 | nodesStack1.push(std::make_pair(p.first + 1, p.second->left)); 116 | } 117 | 118 | } 119 | } 120 | return res; 121 | } 122 | 123 | }; 124 | 125 | int main() { 126 | Solution solution; 127 | 128 | vector> matrix; 129 | cout << matrix.size() << endl; 130 | matrix.push_back({}); 131 | cout << matrix.size() << endl; 132 | cout << matrix[0].size() << endl; 133 | return 0; 134 | } -------------------------------------------------------------------------------- /code4interview/c++/面试题33. 二叉搜索树的后序遍历序列.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | 9 | /** 10 | * Definition for a binary tree node. 11 | * struct TreeNode { 12 | * int val; 13 | * TreeNode *left; 14 | * TreeNode *right; 15 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 16 | * }; 17 | */ 18 | 19 | struct TreeNode { 20 | int val; 21 | TreeNode *left; 22 | TreeNode *right; 23 | explicit TreeNode(int x): val(x), left(nullptr), right(nullptr) {} 24 | }; 25 | 26 | 27 | class Solution { 28 | public: 29 | bool verifyPostorder(vector& postorder) { 30 | if (postorder.size() < 2) return true; 31 | // 思想,如果是二叉搜索树,那么 最后一个节点一定是 32 | int leftPartLen = 0; 33 | for (const auto &item: postorder) { 34 | if (item < postorder.back()) 35 | leftPartLen += 1; 36 | else 37 | break; 38 | } 39 | vector leftArr(postorder.begin(), postorder.begin() + leftPartLen); 40 | vector rightArr(postorder.begin() + leftPartLen, postorder.end() - 1); 41 | 42 | for (const auto &item: rightArr) { 43 | if (item < postorder.back()) { 44 | return false; 45 | } 46 | } 47 | auto leftFlag = verifyPostorder(leftArr); 48 | auto rightFlag = verifyPostorder(rightArr); 49 | 50 | return leftFlag && rightFlag; 51 | } 52 | }; 53 | 54 | int main() { 55 | Solution solution; 56 | vector a{6,5}; 57 | cout << solution.verifyPostorder(a) << endl; 58 | // vector c(a.begin() + 3, a.end() -1); 59 | // for (auto i: c) { 60 | // cout << i << '\t'; 61 | // } 62 | return 0; 63 | } -------------------------------------------------------------------------------- /code4interview/c++/面试题34. 二叉树中和为某一值的路径.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | struct TreeNode { 9 | int val; 10 | TreeNode *left; 11 | TreeNode *right; 12 | explicit TreeNode(int x): val(x), left(nullptr), right(nullptr) {} 13 | }; 14 | 15 | 16 | class Solution { 17 | public: 18 | vector> pathSum(TreeNode* root, int sum) { 19 | if (!root) return {}; 20 | // 这题应该使用的是典型的 回溯法 21 | vector> res; 22 | int tmp = 0; 23 | vector tmpRes; 24 | 25 | back(root, sum, res, tmp, tmpRes); 26 | return res; 27 | } 28 | 29 | void back (TreeNode *root, const int &sum, vector> &res, int &tmp, vector tmpRes) { 30 | tmp += root->val; 31 | tmpRes.push_back(root->val); 32 | 33 | if (tmp == sum && root->left == nullptr && root->right == nullptr) { 34 | // 要求是和一样,且是子节点 35 | res.push_back(tmpRes); 36 | 37 | // 下面这三行可以有,也可以没有。 38 | // tmp -= root->val; 39 | // tmpRes.pop_back(); 40 | // return; 41 | } 42 | 43 | if (root->left) 44 | back(root->left, sum, res, tmp, tmpRes); 45 | if (root->right) 46 | back(root->right, sum, res, tmp, tmpRes); 47 | 48 | tmp -= root->val; 49 | tmpRes.pop_back(); 50 | } 51 | }; 52 | 53 | 54 | int main() { 55 | Solution solution; 56 | vector a{6,5}; 57 | // vector c(a.begin() + 3, a.end() -1); 58 | // for (auto i: c) { 59 | // cout << i << '\t'; 60 | // } 61 | return 0; 62 | } -------------------------------------------------------------------------------- /code4interview/c++/面试题35. 复杂链表的复制.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | using namespace std; 11 | 12 | struct TreeNode { 13 | int val; 14 | TreeNode *left; 15 | TreeNode *right; 16 | explicit TreeNode(int x): val(x), left(nullptr), right(nullptr) {} 17 | }; 18 | 19 | 20 | class Node { 21 | public: 22 | int val; 23 | Node* next; 24 | Node* random; 25 | 26 | explicit Node (int _val) { 27 | val = _val; 28 | next = nullptr; 29 | random = nullptr; 30 | } 31 | }; 32 | 33 | 34 | class Solution { 35 | public: 36 | Node* copyRandomList(Node* head) { 37 | std::unordered_map mp; 38 | auto root = head, cur = head; 39 | while (cur) { 40 | mp[cur] = new Node(cur->val); 41 | cur = cur->next; 42 | } 43 | cur = head; 44 | // 从新遍历一遍 45 | while (cur) { 46 | if (cur->next) 47 | mp[cur]->next = mp[cur->next]; 48 | if (cur->random) 49 | mp[cur]->random = mp[cur->random]; 50 | cur = cur->next; 51 | } 52 | return mp[head]; 53 | 54 | } 55 | }; 56 | 57 | 58 | int main() { 59 | // string s = "[1,2,3,null,null,4,5]"; 60 | string s = "[5,2,3,null,null,2,4,3,1]"; 61 | 62 | 63 | 64 | // string str = "hello world"; 65 | // cout << s.find_last_not_of("world"); 66 | 67 | return 0; 68 | } -------------------------------------------------------------------------------- /code4interview/c++/面试题36. 二叉搜索树与双向链表.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | 9 | /** 10 | * Definition for a binary tree node. 11 | * struct TreeNode { 12 | * int val; 13 | * TreeNode *left; 14 | * TreeNode *right; 15 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 16 | * }; 17 | */ 18 | 19 | // Definition for a Node. 20 | class Node { 21 | public: 22 | int val; 23 | Node* left; 24 | Node* right; 25 | 26 | Node() {} 27 | 28 | explicit Node(int _val) { 29 | val = _val; 30 | left = nullptr; 31 | right = nullptr; 32 | } 33 | 34 | Node(int _val, Node* _left, Node* _right) { 35 | val = _val; 36 | left = _left; 37 | right = _right; 38 | } 39 | }; 40 | 41 | 42 | class Solution { 43 | public: 44 | Node* treeToDoublyList(Node* root) { 45 | if (!root) return root; 46 | 47 | Node *head = nullptr, *pre = nullptr; 48 | 49 | helper (root, head, pre); 50 | head->left = pre; 51 | pre->right = head; 52 | return head; 53 | } 54 | 55 | void helper (Node *root, Node *&head, Node *&pre) { 56 | if (!root) return; 57 | 58 | helper(root->left, head, pre); 59 | if (!head) { 60 | head = root; 61 | pre = root; 62 | } else { 63 | pre->right = root; 64 | root->left = pre; 65 | pre = root; 66 | } 67 | helper(root->right, head, pre); 68 | } 69 | }; 70 | 71 | 72 | int main() { 73 | Solution solution; 74 | 75 | return 0; 76 | } -------------------------------------------------------------------------------- /code4interview/c++/面试题37. 序列化二叉树.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace std; 10 | 11 | struct TreeNode { 12 | int val; 13 | TreeNode *left; 14 | TreeNode *right; 15 | explicit TreeNode(int x): val(x), left(nullptr), right(nullptr) {} 16 | }; 17 | 18 | 19 | class Codec { 20 | public: 21 | 22 | // Encodes a tree to a single string. 23 | string serialize(TreeNode* root) { 24 | if (!root) return "[null]"; 25 | std::queue s; 26 | s.push(root); 27 | string ans = "["; 28 | 29 | TreeNode *cur; 30 | while (!s.empty()) { 31 | cur = s.front(); 32 | s.pop(); 33 | if (cur) { 34 | ans += std::to_string(cur->val); 35 | ans += ","; 36 | } else 37 | ans += "null,"; 38 | 39 | if (cur) { 40 | s.push(cur->left); 41 | s.push(cur->right); 42 | } 43 | } 44 | 45 | ans.pop_back(); 46 | ans += "]"; 47 | return ans; 48 | } 49 | 50 | // Decodes your encoded data to tree. 51 | TreeNode* deserialize(string data) { 52 | string valString = data.substr(1, data.length() - 2); 53 | 54 | auto tmpRes = split(valString, ','); 55 | if (tmpRes[0] == "null") { 56 | return nullptr; 57 | } 58 | auto root = new TreeNode(std::stoi(tmpRes[0])); 59 | std::size_t idx = 0, leftIdx, rightIdx; 60 | // 进行反序列化 61 | std::queue s; 62 | 63 | s.push(root); 64 | while (!s.empty() && idx < tmpRes.size()) { 65 | auto cur = s.front(); 66 | s.pop(); 67 | if (cur== nullptr) continue; 68 | leftIdx = idx + 1; 69 | rightIdx = idx + 2; 70 | 71 | if (leftIdx < tmpRes.size() && tmpRes[leftIdx] != "null") 72 | cur->left = new TreeNode(std::stoi(tmpRes[leftIdx])); 73 | else 74 | cur->left = nullptr; 75 | s.push(cur->left); 76 | 77 | if (rightIdx < tmpRes.size() && tmpRes[rightIdx] != "null") 78 | cur->right = new TreeNode(std::stoi(tmpRes[rightIdx])); 79 | else 80 | cur->right = nullptr; 81 | s.push(cur->right); 82 | idx = rightIdx; 83 | } 84 | return root; 85 | } 86 | 87 | std::vector split(const std::string& s, char delimiter) 88 | { 89 | std::vector tokens; 90 | std::string token; 91 | // 需要 import sstream 92 | std::istringstream tokenStream(s); 93 | while (std::getline(tokenStream, token, delimiter)) 94 | { 95 | tokens.push_back(token); 96 | } 97 | return tokens; 98 | } 99 | }; 100 | 101 | 102 | 103 | int main() { 104 | // string s = "[1,2,3,null,null,4,5]"; 105 | string s = "[5,2,3,null,null,2,4,3,1]"; 106 | 107 | Codec tree; 108 | 109 | auto root = tree.deserialize(s); 110 | auto res = tree.serialize(root); 111 | cout << res << endl; 112 | 113 | // string str = "hello world"; 114 | // cout << s.find_last_not_of("world"); 115 | 116 | return 0; 117 | } -------------------------------------------------------------------------------- /code4interview/c++/面试题38. 字符串的排列.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | using namespace std; 11 | 12 | 13 | 14 | class Solution { 15 | public: 16 | vector permutation (string s) { 17 | // 使用回溯 进行剪枝 18 | vector res; 19 | permutationRecursive(s, res, 0); 20 | return res; 21 | } 22 | 23 | void permutationRecursive(string &s, vector &res, std::size_t idx) { 24 | if (idx == s.size() -1) { 25 | res.push_back(s); 26 | return; 27 | } 28 | for (std::size_t i = idx; i < s.size(); i++) { 29 | // 用当前的字符和后面所有的字符做交换 30 | if (!isSwap(s, idx, i)) continue; 31 | std::swap(s[idx], s[i]); 32 | permutationRecursive(s, res, idx + 1); 33 | std::swap(s[idx], s[i]); 34 | } 35 | } 36 | 37 | bool isSwap(string str,int start,int end) 38 | { 39 | for(;start < end; start++) 40 | { 41 | if(str[start] == str[end]) 42 | return false; 43 | } 44 | return true; 45 | } 46 | 47 | vector combination (const string &s) { 48 | // 使用回溯,但是没有考虑字符重复的情况 49 | vector res; 50 | for (int i = 0; i <= s.size(); i++) { 51 | // i 表示有 排列几个 字符 52 | string tmp; 53 | combinationRecursive(res, s, 0, i, tmp); 54 | } 55 | return res; 56 | } 57 | 58 | void combinationRecursive (vector &res, const string &s, int start, int k, string &tmp) { 59 | // 这种行为比较好理解一点 60 | if (tmp.size() == k) { 61 | res.push_back(tmp); 62 | return; 63 | } 64 | for (int i = start; i < s.size(); i++) { 65 | tmp.push_back(s[i]); 66 | combinationRecursive(res, s, i+1, k, tmp); 67 | tmp.pop_back(); 68 | } 69 | } 70 | 71 | void combinationRecursive2 (vector &res, const string &s, int start, int k, string &tmp) { 72 | // 如果 k == 0 73 | if (k == 0) { 74 | res.push_back(tmp); 75 | return; 76 | } 77 | for (int i = start; i < s.size() - k + 1; i++) { 78 | tmp.push_back(s[i]); 79 | combinationRecursive(res, s, i+1, k -1, tmp); 80 | tmp.pop_back(); 81 | } 82 | } 83 | 84 | 85 | vector permutation2(string s) { 86 | // 使用 Set 进行去重 87 | std::set res; 88 | vector visited(s.size(), false); 89 | string tmp; 90 | permutationBack(s, tmp, res, visited); 91 | return vector(res.begin(), res.end()); 92 | } 93 | 94 | void permutationBack (string &s, string &tmp, std::set &res, vector &visited) { 95 | // 递归中止条件 96 | if (tmp.size() == s.size()) { 97 | res.insert(tmp); 98 | return; 99 | } 100 | for (std::size_t i = 0; i < s.size(); i++) { 101 | if (visited[i] == true ) continue; 102 | tmp.push_back(s[i]); 103 | visited[i] = true; 104 | permutationBack (s, tmp, res, visited); 105 | tmp.pop_back(); 106 | visited[i] = false; 107 | } 108 | } 109 | }; 110 | 111 | 112 | int main() { 113 | // [8,9,2,3,7,0,5,4,6,1] 114 | // [6,8,2,1,3,9,0,7,4,5] 115 | // vector a {8,9,2,3,7,0,5,4,6,1}, b {6,8,2,1,3,9,0,7,4,5}; 116 | std::string s {"aab"}; 117 | Solution solution; 118 | auto res = solution.combination(s); 119 | for (auto item: res) { 120 | cout << item << endl; 121 | } 122 | return 0; 123 | } -------------------------------------------------------------------------------- /code4interview/c++/面试题39. 数组中出现次数超过一半的数字.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | 10 | /** 11 | * Definition for a binary tree node. 12 | * struct TreeNode { 13 | * int val; 14 | * TreeNode *left; 15 | * TreeNode *right; 16 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 17 | * }; 18 | */ 19 | 20 | class Solution { 21 | public: 22 | int majorityElement(vector& nums) { 23 | // 高级解法 24 | int count(1); 25 | int tmp = nums[0]; 26 | for (std::size_t i = 1; i < nums.size(); i++) { 27 | if (tmp == nums[i]) 28 | count++; 29 | else 30 | count--; 31 | if (count == 0) { 32 | tmp = nums[i]; 33 | count += 1; 34 | } 35 | } 36 | return tmp; 37 | 38 | } 39 | int majorityElement2(vector& nums) { 40 | // 使用 hash map 41 | unordered_map m; 42 | for (const auto & item: nums) { 43 | cout << m[item] << endl; 44 | m[item]++; 45 | if (m[item] > nums.size() / 2) return item; 46 | } 47 | return 0; 48 | 49 | } 50 | int majorityElement3(vector& nums) { 51 | // 使用 排序 52 | std::sort(nums.begin(),nums.end()); 53 | return nums[nums.size()/2]; 54 | } 55 | }; 56 | 57 | 58 | 59 | int main() { 60 | Solution solution; 61 | vector nums{1, 2, 3}; 62 | solution.majorityElement2(nums); 63 | return 0; 64 | } -------------------------------------------------------------------------------- /code4interview/c++/面试题40. 最小的k个数.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | 10 | class Solution { 11 | public: 12 | vector getLeastNumbers(vector& arr, int k) { 13 | int left = 0, right = (int)arr.size() -1; 14 | int pivotIdx; 15 | vector res; 16 | while (left <= right) { 17 | pivotIdx = pivot(arr, left, right); 18 | 19 | if (pivotIdx == k -1) { 20 | res = std::vector(arr.begin(), arr.begin() + k); 21 | break; 22 | } else if (pivotIdx > k -1) { 23 | // 说明结果应该在 左边 24 | right = pivotIdx -1; 25 | } else { 26 | left = pivotIdx + 1; 27 | } 28 | } 29 | return res; 30 | } 31 | 32 | int pivot (vector &arr, int left, int right) { 33 | int pivotValue = arr[right]; 34 | auto pivotIdx = left -1; 35 | for (std::size_t i = left; i < right; i++) { 36 | if (arr[i] < pivotValue) { 37 | pivotIdx++; 38 | std::swap(arr[pivotIdx], arr[i]); 39 | } 40 | } 41 | // 下一个需要 42 | std::swap(arr[pivotIdx+ 1], arr[right]); 43 | return pivotIdx + 1; 44 | } 45 | }; 46 | 47 | 48 | template 49 | void print(const vector &nums) { 50 | for (const auto & i: nums) { 51 | cout << i << ' '; 52 | } 53 | cout << endl; 54 | } 55 | 56 | 57 | int main() { 58 | Solution solution; 59 | vector nums{0,1,1,2,4,4,1,3,3,2}; 60 | auto res = solution.getLeastNumbers(nums, 6); 61 | // auto res = solution.pivot(nums, 0, 4); 62 | // cout << res << endl; 63 | 64 | print(res); 65 | return 0; 66 | } -------------------------------------------------------------------------------- /code4interview/c++/面试题42. 连续子数组的最大和.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | using namespace std; 11 | 12 | class Solution { 13 | public: 14 | int maxSubArray(vector& nums) { 15 | // 连续数组最大和 16 | vector dp(nums.size(), 0); 17 | dp[0] = nums[0]; 18 | for (std::size_t i = 1; i < nums.size(); i++) { 19 | if (dp[i -1] > 0) { 20 | dp[i] = dp[i -1] + nums[i]; 21 | } else 22 | dp[i] = nums[i]; 23 | } 24 | return *std::max_element(dp.begin(), dp.end()); 25 | } 26 | }; 27 | 28 | 29 | 30 | int main() { 31 | // string s = "[1,2,3,null,null,4,5]"; 32 | string s = "[5,2,3,null,null,2,4,3,1]"; 33 | 34 | 35 | 36 | // string str = "hello world"; 37 | // cout << s.find_last_not_of("world"); 38 | 39 | return 0; 40 | } -------------------------------------------------------------------------------- /code4interview/c++/面试题47. 礼物的最大价值.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | 9 | class Solution { 10 | public: 11 | int maxValue(vector>& grid) { 12 | // 使用动态规划,那么算法很简单,用一个二维数组 13 | 14 | int rowIdx= int(grid.size()), colIdx = int(grid[0].size()); 15 | 16 | vector> dp(rowIdx, vector(colIdx, 0)); 17 | 18 | dp[0][0] = grid[0][0]; 19 | // 初始化第一行,相当于假设只有一行 20 | // 只能往右遍历 21 | for (std::size_t i = 1; i < colIdx; i++) 22 | dp[0][i] = dp[0][i-1] + grid[0][i]; 23 | // 只能往 下遍历 24 | for (std::size_t i = 1; i < rowIdx; i++) 25 | dp[i][0] += dp[i -1][0] + grid[i][0]; 26 | for (std::size_t i = 1; i < rowIdx; i++) { 27 | for (std::size_t j = 1; j < colIdx; j++) { 28 | dp[i][j] = std::max(dp[i-1][j], dp[i][j-1]) + grid[i][j]; 29 | } 30 | } 31 | return dp[rowIdx -1][colIdx -1]; 32 | } 33 | }; 34 | 35 | 36 | int main() { 37 | Solution solution; 38 | vector a{6,5}; 39 | // vector c(a.begin() + 3, a.end() -1); 40 | // for (auto i: c) { 41 | // cout << i << '\t'; 42 | // } 43 | return 0; 44 | } -------------------------------------------------------------------------------- /code4interview/c++/面试题50. 第一个只出现一次的字符.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | 10 | class Solution { 11 | public: 12 | char firstUniqChar(string s) { 13 | unordered_map mp; 14 | for(auto c:s) mp[c]++; 15 | for(auto c:s){ 16 | if(mp[c]==1) return c; 17 | } 18 | return ' '; 19 | } 20 | 21 | }; 22 | 23 | 24 | int main() { 25 | Solution solution; 26 | return 0; 27 | } -------------------------------------------------------------------------------- /code4interview/c++/面试题51. 数组中的逆序对.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | using namespace std; 12 | 13 | class Solution { 14 | public: 15 | int reversePairs(vector& nums) { 16 | int count{0}; 17 | 18 | merge_merge(nums, 0, nums.size() -1, count); 19 | for (auto item: nums) { 20 | cout << item << '\t'; 21 | } 22 | return count; 23 | } 24 | 25 | void merge_merge(vector &a, int left, int right, int & count) { 26 | if (left >= right) 27 | return; 28 | int mid = left + (right - left ) /2; 29 | 30 | merge_merge(a, left, mid, count); 31 | merge_merge(a, mid +1, right, count); 32 | merge(a, left, mid, mid +1, right, count); 33 | } 34 | 35 | void merge(vector &a, int l1, int r1, int l2, int r2, int &count) { 36 | vector tmp; 37 | int l1_tmp = l1, l2_tmp = l2; 38 | while (l1 <= r1 && l2 <= r2) { 39 | if (a[l1] > a[l2]) { 40 | tmp.push_back(a[l2]); 41 | count += (r1 - l1 + 1); 42 | l2++; 43 | } else { 44 | tmp.push_back(a[l1]); 45 | l1++; 46 | } 47 | } 48 | while (l2 <= r2) { 49 | tmp.push_back(a[l2]); 50 | l2++; 51 | } 52 | 53 | while (l1 <= r1) { 54 | tmp.push_back(a[l1]); 55 | l1++; 56 | } 57 | 58 | 59 | for (std::size_t i = l1_tmp, idx=0; i <= r2; i++){ 60 | a[i] = tmp[idx++]; 61 | 62 | } 63 | } 64 | 65 | 66 | }; 67 | 68 | 69 | class Solution2 { 70 | public: 71 | int global_count = 0; 72 | int reversePairs(vector& nums) { 73 | vector copyarr(nums.size(), 0); 74 | merge_sort(nums, copyarr, 0, nums.size()-1); 75 | return global_count; 76 | } 77 | 78 | void merge_sort(vector& nums, vector& copyarr, int left, int right) { 79 | if (left >= right) return; 80 | int mid = (left+right) / 2; 81 | merge_sort(nums, copyarr, left, mid); 82 | merge_sort(nums, copyarr, mid+1, right); 83 | int i = left, j = mid+1, k = left; 84 | while (i <= mid && j <= right) { 85 | if (nums[j] < nums[i]) { 86 | copyarr[k++] = nums[j++]; 87 | global_count += (mid-i+1); // 关键点,也是归并排序添加的唯一一行代码。 88 | } else { 89 | copyarr[k++] = nums[i++]; 90 | } 91 | } 92 | if (i <= mid) copy(nums.begin()+i, nums.begin()+mid+1, copyarr.begin()+k); 93 | if (j <= right) copy(nums.begin()+j, nums.begin()+right+1, copyarr.begin()+k); 94 | copy(copyarr.begin()+left, copyarr.begin()+right+1, nums.begin()+left); 95 | } 96 | }; 97 | 98 | 99 | int main() { 100 | vector a {7,5,8,6,4}; 101 | vector b {7,5,8,6,4}; 102 | Solution s; 103 | Solution2 solution; 104 | auto ss = s.reversePairs(a); 105 | cout << endl << ss << endl; 106 | cout << solution.reversePairs(b); 107 | return 0; 108 | } -------------------------------------------------------------------------------- /code4interview/c++/面试题52. 两个链表的第一个公共节点.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | 11 | /** 12 | * Definition for singly-linked list. 13 | * struct ListNode { 14 | * int val; 15 | * ListNode *next; 16 | * ListNode(int x) : val(x), next(NULL) {} 17 | * }; 18 | */ 19 | 20 | struct ListNode { 21 | int val; 22 | ListNode *next; 23 | explicit ListNode (int x): val(x), next(nullptr) {}; 24 | }; 25 | 26 | 27 | class Solution { 28 | public: 29 | ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) { 30 | int lenA = 0, lenB = 0; 31 | auto cur = headA; 32 | while (cur) { 33 | lenA++; 34 | cur = cur->next; 35 | } 36 | 37 | cur = headB; 38 | while (cur) { 39 | lenB++; 40 | cur = cur->next; 41 | } 42 | 43 | int lenGap; 44 | if (lenA > lenB) { 45 | lenGap = lenA - lenB; 46 | while (lenGap) { 47 | headA = headA->next; 48 | lenGap--; 49 | } 50 | } else { 51 | lenGap = lenB - lenA; 52 | while (lenGap) { 53 | headB = headB->next; 54 | lenGap--; 55 | ; } 56 | } 57 | 58 | while (true) { 59 | if (headA == headB) { 60 | break; 61 | } else { 62 | headA = headA->next; 63 | headB = headB->next; 64 | } 65 | } 66 | return headA; 67 | 68 | } 69 | }; 70 | 71 | 72 | int main() { 73 | Solution solution; 74 | return 0; 75 | } -------------------------------------------------------------------------------- /code4interview/c++/面试题53 - I. 在排序数组中查找数字 I.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | class Solution { 10 | public: 11 | int search(vector& nums, int target) { 12 | if (nums.empty()) return 0; 13 | int left = 0, right = int(nums.size() -1); 14 | int firstK = findFirstK(nums, target, 0, right); 15 | int secondK = findLastK(nums, target, 0, right); 16 | 17 | cout << firstK << '\t' << secondK << endl; 18 | 19 | int res = 0; 20 | if (firstK != -1 && secondK != -1) { 21 | res = secondK - firstK + 1; 22 | } 23 | return res; 24 | } 25 | 26 | int findFirstK (const vector &nums, int target, int left, int right) { 27 | int mid, res=-1; 28 | while (left <= right) { 29 | mid = left + (right - left) / 2; 30 | if (nums[mid] > target) { 31 | right = mid - 1; 32 | } else if (nums[mid] < target) { 33 | left = mid + 1; 34 | } else if (nums[mid] == target) { 35 | // 如果左边不是 target, 那么返回自己 36 | if ((mid > 0 && nums[mid -1] != target) || mid == 0) { 37 | res = mid; 38 | break; 39 | } 40 | else 41 | right = mid -1; 42 | } 43 | } 44 | 45 | return res; 46 | } 47 | 48 | int findLastK (const vector& nums, int target, int left, int right) { 49 | int mid, res = -1; 50 | auto tmp = right; 51 | 52 | while (left <= right) { 53 | mid = left + (right - left) / 2; 54 | if (nums[mid] > target) { 55 | right = mid -1; 56 | } else if (nums[mid] < target) { 57 | left = mid + 1; 58 | } else { 59 | if (mid == tmp || (mid < tmp && nums[mid + 1] != target)) { 60 | res = mid; 61 | break; 62 | } else { 63 | left = mid + 1; 64 | } 65 | } 66 | } 67 | return res; 68 | } 69 | }; 70 | 71 | 72 | int main() { 73 | Solution solution; 74 | vector arr {5,7,7,8,8,10}; 75 | auto res = solution.search(arr, 8); 76 | 77 | cout << res << endl; 78 | 79 | return 0; 80 | } -------------------------------------------------------------------------------- /code4interview/c++/面试题53 - II. 0~n-1中缺失的数字.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | 10 | class Solution { 11 | public: 12 | int missingNumber(vector &nums) { 13 | // 题目,排序,应该使用二分 14 | int left = 0, right = nums.size() -1; 15 | int mid, res = 0; 16 | while (left <= right) { 17 | // 如果 18 | mid = left + (right - left) / 2; 19 | if (nums[mid] == mid) { 20 | left = mid + 1; 21 | } else { 22 | right = mid -1; 23 | } 24 | } 25 | if (left >= nums.size()) return left; 26 | if (nums[left] != left) 27 | res = left; 28 | return res; 29 | } 30 | 31 | 32 | int missingNumber2(vector& nums) { 33 | // 可以使用最傻比的方法,一次遍历 34 | int res = nums.size(); 35 | for (int i = 0; i < nums.size(); i++) { 36 | if (nums[i] != i) { 37 | res = i; 38 | break; 39 | } 40 | } 41 | return res; 42 | } 43 | }; 44 | int main() { 45 | Solution solution; 46 | 47 | return 0; 48 | } -------------------------------------------------------------------------------- /code4interview/c++/面试题54. 二叉搜索树的第k大节点.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | 11 | struct TreeNode { 12 | int val; 13 | TreeNode *left; 14 | TreeNode *right; 15 | explicit TreeNode(int x): val(x), left(nullptr), right(nullptr) {} 16 | }; 17 | 18 | 19 | class Solution { 20 | public: 21 | int kthLargest(TreeNode* root, int k) { 22 | if (root == nullptr) return 0; 23 | int count = 0; 24 | auto res(0); 25 | inOrder(root, count, k, res); 26 | return res; 27 | } 28 | 29 | void inOrder(TreeNode* root, int &count, const int & k, int & res) { 30 | if (root == nullptr) return ; 31 | if (root->right) 32 | inOrder(root->right, count, k, res); 33 | count += 1; 34 | if (count == k) { 35 | res = root->val; 36 | return ; 37 | } 38 | if (root->left) 39 | inOrder(root->left, count, k, res); 40 | } 41 | 42 | int kthLargest2(TreeNode* root, int k) { 43 | // 使用 中序遍历非递归 44 | if (root == nullptr) return 0; 45 | int count = 0; 46 | auto res(0); 47 | 48 | std::stack nodes; 49 | auto cur = root; 50 | while (!nodes.empty() || cur) { 51 | while (cur) { 52 | nodes.push(cur); 53 | cur = cur->right; 54 | } 55 | cur = nodes.top(); 56 | nodes.pop(); 57 | 58 | count += 1; 59 | if (count == k) { 60 | res = cur->val; 61 | break; 62 | } 63 | cur = cur->left; 64 | } 65 | 66 | return res; 67 | } 68 | 69 | 70 | 71 | }; 72 | 73 | int main() { 74 | Solution solution; 75 | return 0; 76 | } -------------------------------------------------------------------------------- /code4interview/c++/面试题55 - I. 二叉树的深度.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | 11 | struct TreeNode { 12 | int val; 13 | TreeNode *left; 14 | TreeNode *right; 15 | explicit TreeNode(int x): val(x), left(nullptr), right(nullptr) {} 16 | }; 17 | 18 | 19 | class Solution { 20 | public: 21 | int maxDepth(TreeNode* root) { 22 | if (root == nullptr) return 0; 23 | int res(1); 24 | 25 | helper(root, res, 1); 26 | return res; 27 | } 28 | 29 | void helper(TreeNode* cur, int& res, int level) { 30 | // 和中序遍历算法一样,就不写非递归了。写了很多遍了。 31 | // 如果有要求再说吧 32 | if (cur == nullptr) return; 33 | if (level > res) res = level; 34 | if (cur->left) helper(cur->left, res, level + 1); 35 | if (cur->right) helper(cur->right, res, level + 1); 36 | } 37 | }; 38 | 39 | 40 | int main() { 41 | Solution solution; 42 | return 0; 43 | } -------------------------------------------------------------------------------- /code4interview/c++/面试题55 - II. 平衡二叉树.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | 11 | struct TreeNode { 12 | int val; 13 | TreeNode *left; 14 | TreeNode *right; 15 | explicit TreeNode(int x): val(x), left(nullptr), right(nullptr) {} 16 | }; 17 | 18 | 19 | class Solution { 20 | public: 21 | bool isBalanced(TreeNode* root) { 22 | if (root == nullptr) return true; 23 | // 看一下左子树和由子树的 高度 24 | int flag = calculate(root); 25 | return flag == -1; 26 | } 27 | 28 | int calculate(TreeNode *root) { 29 | if (root == nullptr) return 0; 30 | int left = calculate(root->left); 31 | if (left == -1) return -1; 32 | int right = calculate(root->right); 33 | if (right == -1) return -1; 34 | // 这是一个后序遍历 35 | int res; 36 | if (std::abs(right - left) > 1) 37 | res = -1; 38 | else 39 | res = std::max(right, left) + 1; 40 | return res; 41 | } 42 | 43 | bool isBalancedRecursive (TreeNode *root) { 44 | if (root == nullptr) return true; 45 | 46 | if (std::abs(calculateHeight(root->left) - calculateHeight(root->right)) > 1) return false; 47 | return isBalancedRecursive(root->right) && isBalancedRecursive(root->left); 48 | } 49 | 50 | int calculateHeight(TreeNode *root) { 51 | if (root == nullptr) return 0; 52 | int a = std::max(calculateHeight(root->left), calculateHeight(root->right)); 53 | return a+1; 54 | } 55 | }; 56 | 57 | int main() { 58 | Solution solution; 59 | return 0; 60 | } -------------------------------------------------------------------------------- /code4interview/c++/面试题56 - I. 数组中数字出现的次数.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | class Solution { 10 | public: 11 | vector singleNumbers(vector& nums) { 12 | // 通过 某一位数是不是1 讲数字分成两个数组 13 | int tmp = nums[0]; 14 | for (std::size_t i = 1; i < nums.size(); i++) { 15 | tmp = tmp ^ nums[i]; 16 | } 17 | // 得到 单独出现的两个数字的 异或的值 18 | // 按照 第 N 未为 1 讲数组分成两部分 19 | vector arr1, arr2; 20 | 21 | unsigned int flag = 1; 22 | while (true) { 23 | if (flag & tmp) break; 24 | flag = flag << 1; 25 | } 26 | 27 | for (auto &item: nums) { 28 | if (flag & item) 29 | arr1.push_back(item); 30 | else 31 | arr2.push_back(item); 32 | } 33 | 34 | vector res; 35 | res.push_back(findSingle(arr1)); 36 | res.push_back(findSingle(arr2)); 37 | return res; 38 | } 39 | 40 | int findSingle (vector &arr) { 41 | // 理论上使用 异或 的时候应该使用 无符号数字 42 | int res = arr[0]; 43 | for (std::size_t i = 1; i < arr.size(); i++) { 44 | res = res ^ arr[i]; 45 | } 46 | return res; 47 | } 48 | }; 49 | 50 | 51 | int main() { 52 | Solution solution; 53 | vector arr { 1,2,10,4,1,4,3,3}; 54 | auto res = solution.singleNumbers(arr); 55 | for (auto item : res) { 56 | cout << item << '\t' ; 57 | } 58 | return 0; 59 | } -------------------------------------------------------------------------------- /code4interview/c++/面试题56 - II. 数组中数字出现的次数 II.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | unsigned int bitArr[32]; 4 | int singleNumber (vector &nums) { 5 | // 使用 二进制 字符串来做 6 | for (const auto &item : nums) { 7 | updateArr(item); 8 | } 9 | int res=0; 10 | for (int i = 31; i > 0; i--) { 11 | res += bitArr[i] %3; 12 | res = res << 1; 13 | } 14 | res += bitArr[0] %3; 15 | return res; 16 | } 17 | 18 | void updateArr (int x) { 19 | unsigned int bitMask = 1; 20 | for (int i = 0; i < 32; i++) { 21 | bitArr[i] += (bitMask & x) ? 1: 0; 22 | bitMask = bitMask << 1; 23 | } 24 | } 25 | }; -------------------------------------------------------------------------------- /code4interview/c++/面试题57 - II. 和为s的连续正数序列.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | class Solution { 10 | public: 11 | vector> findContinuousSequence(int target) { 12 | vector> res; 13 | deque tmp; 14 | int left = 1, sum = 1, right; 15 | tmp.push_back(left); 16 | 17 | for (int i = 2; i < target; i++) { 18 | right = i; 19 | sum = sum + right; 20 | tmp.push_back(right); 21 | while (sum > target && left < right) { 22 | sum -= left; // sum 要先减去左边那个 23 | left = left + 1; 24 | 25 | tmp.pop_front(); 26 | } 27 | 28 | if (sum == target) { 29 | res.emplace_back(tmp.begin(), tmp.end()); 30 | } 31 | } 32 | 33 | return res; 34 | } 35 | }; 36 | 37 | int main() { 38 | Solution solution; 39 | auto res = solution.findContinuousSequence(9); 40 | for (const auto &item: res) { 41 | for (const auto &i: item) { 42 | cout << i << '\t'; 43 | } 44 | cout << '\n' << endl; 45 | } 46 | 47 | return 0; 48 | } -------------------------------------------------------------------------------- /code4interview/c++/面试题57. 和为s的两个数字.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | 11 | class Solution { 12 | public: 13 | vector twoSum(vector& nums, int target) { 14 | vector res; 15 | std::size_t left = 0, right = nums.size() -1; 16 | while (left < right) { 17 | if (nums[left] + nums[right] == target) { 18 | res.push_back(nums[left]); 19 | res.push_back(nums[right]); 20 | break; 21 | } else if (nums[left] + nums[right] > target) { 22 | right--; 23 | } else { 24 | left++; 25 | } 26 | } 27 | return res; 28 | } 29 | }; 30 | 31 | int main() { 32 | Solution solution; 33 | return 0; 34 | } -------------------------------------------------------------------------------- /code4interview/c++/面试题58 - I. 翻转单词顺序.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | 11 | /* 12 | 其实可以又比较多的做法 13 | 方法一: 反转两次字符,第一次反转所有,第二次反转单词。不使用额外空间 14 | 方法二:split(" ") concat 15 | 方法三: 直接和我写的一样,遇到一个空格加到 ans 里面 16 | */ 17 | 18 | 19 | class Solution { 20 | public: 21 | string reverseWords(string s) { 22 | // 最简单的方法,申明新的结果 23 | if(s.empty())return s; 24 | int len = 0; 25 | string res; 26 | for(int m = s.size()-1; m >=0; m--) { 27 | if(s[m]==' ' && len!=0) { 28 | res += s.substr(m + 1, len) + " "; 29 | len = 0; 30 | continue; 31 | } 32 | if(s[m]!= ' ')len++; 33 | } 34 | if( len !=0 ) 35 | res += s.substr(0, len) + " "; 36 | if(res.size() > 0 ) 37 | res.erase(res.size() - 1, 1); 38 | return res; 39 | } 40 | }; 41 | 42 | 43 | int main() { 44 | Solution solution; 45 | return 0; 46 | } -------------------------------------------------------------------------------- /code4interview/c++/面试题58 - II. 左旋转字符串.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | 11 | class Solution { 12 | public: 13 | string reverseLeftWords(string s, int n) { 14 | size_t lenIdx = s.size() - 1, originalLen = s.size(); 15 | int k = n; 16 | s.resize(s.size() + n); 17 | while (k) { 18 | s[lenIdx + k] = s[k -1]; 19 | k--; 20 | } 21 | return s.substr(n, originalLen); 22 | } 23 | }; 24 | 25 | int main() { 26 | Solution solution; 27 | cout << solution.reverseLeftWords("abcdef", 2); 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /code4interview/c++/面试题59 - I. 滑动窗口的最大值.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | 11 | class Solution { 12 | public: 13 | vector maxSlidingWindow(vector& nums, int k) { 14 | std::deque windows; 15 | vector res; 16 | 17 | // 如果只有 ++, 那么可以使用 size_t 18 | for (std::size_t i = 0; i < nums.size(); i++) { 19 | while (!windows.empty() && nums[windows.back()] < nums[i]) { 20 | windows.pop_back(); 21 | } 22 | windows.push_back(i); 23 | 24 | if (windows.front() + std::size_t(k) == i) 25 | windows.pop_front(); 26 | if (i >= k -1) 27 | res.push_back(nums[windows.front()]); 28 | } 29 | return res; 30 | } 31 | }; 32 | 33 | int main() { 34 | Solution solution; 35 | return 0; 36 | } -------------------------------------------------------------------------------- /code4interview/c++/面试题62. 圆圈中最后剩下的数字.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | int lastRemaining(int n, int m) { 4 | int last = 0; 5 | for (std::size_t i = 2; i <= n; i++) { 6 | last = (last + m) % i; 7 | } 8 | return last; 9 | } 10 | }; -------------------------------------------------------------------------------- /code4interview/c++/面试题63. 股票的最大利润.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | 10 | class Solution { 11 | public: 12 | int maxProfit(vector& prices) { 13 | // 从前往后遍历 保存最小的 14 | // TODO: 从后往前遍历记录最大的。留给读者的作业 15 | if (prices.size() <= 1) return 0; 16 | int curMin = prices[0], res = 0; 17 | 18 | for (std::size_t i = 1; i < prices.size(); i++) { 19 | res = std::max(res, prices[i] - curMin); 20 | curMin = std::min(prices[i], curMin); 21 | } 22 | return res; 23 | } 24 | }; 25 | 26 | int main() { 27 | Solution solution; 28 | 29 | return 0; 30 | } -------------------------------------------------------------------------------- /code4interview/c++/面试题64. 求1+2+…+n.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | class Solution { 10 | public: 11 | int sumNums(int n) { 12 | int ans = n; 13 | ans && (ans += sumNums(n -1)); 14 | return ans; 15 | } 16 | }; 17 | 18 | int main() { 19 | Solution solution; 20 | 21 | 22 | return 0; 23 | } -------------------------------------------------------------------------------- /code4interview/c++/面试题65. 不用加减乘除做加法.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | class Solution { 10 | public: 11 | int add(int a, int b) { 12 | // 要使用 unsigned int, 不然好像会溢出 13 | while (a != 0) { 14 | int noCarryPlus = a ^ b ; // 不进位加法 15 | a = (unsigned int)(a & b ) << 1 ; // 进位 16 | b = noCarryPlus ; 17 | } 18 | return b ; 19 | } 20 | }; 21 | 22 | int main() { 23 | Solution solution; 24 | 25 | 26 | return 0; 27 | } -------------------------------------------------------------------------------- /code4interview/c++/面试题66. 构建乘积数组.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | using namespace std; 7 | 8 | class Solution { 9 | public: 10 | vector constructArr(vector& a) { 11 | vector res(a.size(), 1); 12 | int tmp = 1; 13 | 14 | for (int i = 0; i < a.size(); i++) { 15 | res[i] = tmp; 16 | tmp = tmp * a[i]; 17 | } 18 | tmp = 1; 19 | for (int i = a.size() -1; i > -1; i--) { 20 | res[i] *= tmp; 21 | tmp *= a[i]; 22 | } 23 | return res; 24 | 25 | } 26 | }; 27 | 28 | int main() { 29 | Solution solution; 30 | return 0; 31 | } -------------------------------------------------------------------------------- /code4interview/c++/面试题68 - I. 二叉搜索树的最近公共祖先.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | 11 | /** 12 | * Definition for a binary tree node. 13 | * struct TreeNode { 14 | * int val; 15 | * TreeNode *left; 16 | * TreeNode *right; 17 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 18 | * }; 19 | */ 20 | 21 | struct TreeNode { 22 | int val; 23 | TreeNode *left; 24 | TreeNode *right; 25 | explicit TreeNode(int x): val(x), left(nullptr), right(nullptr) {} 26 | }; 27 | 28 | 29 | 30 | class Solution { 31 | public: 32 | TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) { 33 | // 递归解法 34 | if (!root) return root; 35 | if (p->val < root->val && q->val < root->val) 36 | return lowestCommonAncestor(root->left, p, q); 37 | if (p->val > root->val && q->val > root->val) 38 | return lowestCommonAncestor(root->right, p, q); 39 | 40 | return root; 41 | } 42 | }; 43 | 44 | 45 | int main() { 46 | Solution solution; 47 | return 0; 48 | } -------------------------------------------------------------------------------- /code4interview/c++/面试题68 - II. 二叉树的最近公共祖先.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | using namespace std; 9 | 10 | 11 | /** 12 | * Definition for a binary tree node. 13 | * struct TreeNode { 14 | * int val; 15 | * TreeNode *left; 16 | * TreeNode *right; 17 | * TreeNode(int x) : val(x), left(NULL), right(NULL) {} 18 | * }; 19 | */ 20 | 21 | struct TreeNode { 22 | int val; 23 | TreeNode *left; 24 | TreeNode *right; 25 | explicit TreeNode(int x): val(x), left(nullptr), right(nullptr) {} 26 | }; 27 | 28 | 29 | 30 | class Solution { 31 | public: 32 | TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) { 33 | if (!root || root == q || root == p) return root; 34 | TreeNode *left = lowestCommonAncestor(root->left, p, q); 35 | TreeNode *right = lowestCommonAncestor(root->right, p, q); 36 | 37 | // 如果在左边 38 | if (!right) return left; 39 | if (!left) return right; 40 | return root; 41 | } 42 | }; 43 | 44 | 45 | int main() { 46 | Solution solution; 47 | cout << solution.lowestCommonAncestor("abcdef", 2); 48 | return 0; 49 | } -------------------------------------------------------------------------------- /leetcode-algorithms/001. Two Sum/Solution.java: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public int[] twoSum(int[] nums, int target) { 3 | Map map = new HashMap<>(); 4 | for (int i = 0; i < nums.length; i++) { 5 | map.put(nums[i], i); 6 | } 7 | for (int i = 0; i < nums.length; i++) { 8 | int complement = target - nums[i]; 9 | if (map.get(complement) != null && map.get(complement) != i) { 10 | return new int[] { i, map.get(complement) }; 11 | } 12 | } 13 | 14 | throw new IllegalArgumentException("No two sum solution"); 15 | } 16 | } -------------------------------------------------------------------------------- /leetcode-algorithms/001. Two Sum/solution.cpp: -------------------------------------------------------------------------------- 1 | class Solution { 2 | public: 3 | vector twoSum(vector& nums, int target) { 4 | unordered_map m; 5 | vector result; 6 | for(int i=0; i< nums.size(); i++){ 7 | // not found the second one 8 | if (m.find(nums[i]) == m.end()) { 9 | // store the first one position into the second one's key 10 | m[target - nums[i]] = i; 11 | }else { 12 | // found the second one 13 | result.push_back(m[nums[i]]); 14 | result.push_back(i); 15 | break; 16 | } 17 | } 18 | return result; 19 | } 20 | }; -------------------------------------------------------------------------------- /leetcode-algorithms/001. Two Sum/twoSum.js: -------------------------------------------------------------------------------- 1 | /* 2 | this function is too slow. We need to have another solution. 3 | */ 4 | 5 | function twoSum(nums, target){ 6 | var tmp, 7 | position, 8 | a = []; 9 | for(var i = 0; i < nums.length; i++){ 10 | tmp = target - nums[i]; 11 | position = nums.indexOf(tmp); 12 | if(position !== i && position !== -1){ 13 | a.push(i, position); 14 | break; 15 | } 16 | } 17 | return a; 18 | } 19 | 20 | // method 2 21 | //这里还是利用了hash的思想,我利用python做这道题也是这样做的。 22 | var twoSum = function(nums, target){ 23 | var hash = {}, 24 | result = []; 25 | for(var i = 0; i < nums.length; i++){ 26 | hash[nums[i]] = i; 27 | } 28 | for(var j = 0; j< nums.length; j++){ 29 | var a = target - nums[j]; 30 | if(hash[a]){ 31 | result.push(j, hash[a]); 32 | break; 33 | } 34 | } 35 | return result; 36 | } -------------------------------------------------------------------------------- /leetcode-algorithms/001. Two Sum/two_sum.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Created by Bruce yuan on 18-1-23. 3 | 4 | 5 | class Solution(object): 6 | def twoSum(self, nums, target): 7 | i = 0 8 | q = 0 9 | for i in range(0, len(nums)): 10 | m = target - nums[i] 11 | if m in nums: 12 | q = nums.index(m) 13 | if q != i: 14 | break 15 | return [i, q] 16 | 17 | 18 | class Solution2(object): 19 | def twoSum(self, nums, target): 20 | """ 21 | :type nums: List[int] 22 | :type target: int 23 | :rtype: List[int] 24 | """ 25 | d = {} 26 | for index, item in enumerate(nums): 27 | # if d.get(target - item, None) or d.get(target - item, None) == 0: 28 | if (target - item) in d: 29 | return [d.get(target - item), index] 30 | else: 31 | d[item] = index 32 | 33 | 34 | if __name__ == '__main__': 35 | s = Solution() 36 | print(s.twoSum([6, 2, 4], 6)) 37 | s = Solution2() 38 | print(s.twoSum([6, 2, 4], 6)) 39 | -------------------------------------------------------------------------------- /leetcode-algorithms/002. Add Two Numbers/AddTwoNumbers.js: -------------------------------------------------------------------------------- 1 | //this is dum 2 | var addTwoNumbers = function(l1, l2) { 3 | var add = 0, 4 | ans, 5 | head; 6 | 7 | while(l1 || l2){ 8 | var a = l1 ? l1.val : 0, 9 | b = l2 ? l2.val : 0; 10 | 11 | var sum = a + b + add; 12 | add = ~~(sum / 10);//这里是去除小数地作用。 13 | //类似于Math.floor(sum / 10); 14 | var node = new ListNode(sum % 10); 15 | if(!ans){ 16 | ans = head = node; 17 | } else { 18 | head.next = node; 19 | head = node; 20 | } 21 | 22 | if (l1){ 23 | l1 = l1.next; 24 | } 25 | if (l2){ 26 | l2 = l2.next; 27 | } 28 | 29 | } 30 | 31 | if(add){ 32 | var node1 = new ListNode(add); 33 | head.next = node1; 34 | head = node1; 35 | } 36 | return ans; 37 | 38 | 39 | }; 40 | -------------------------------------------------------------------------------- /leetcode-algorithms/002. Add Two Numbers/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Created by Bruce yuan on 18-2-17. 3 | 4 | 5 | # Definition for singly-linked list. 6 | class ListNode(object): 7 | def __init__(self, x): 8 | self.val = x 9 | self.next = None 10 | 11 | 12 | class Solution(object): 13 | def addTwoNumbers(self, l1, l2): 14 | """ 15 | :type l1: ListNode 16 | :type l2: ListNode 17 | :rtype: ListNode 18 | """ 19 | dummy = cur = ListNode(0) 20 | carry = 0 21 | while l1 or l2 or carry: 22 | if l1: 23 | carry += l1.val 24 | l1 = l1.next 25 | if l2: 26 | carry += l2.val 27 | l2 = l2.next 28 | cur.next = ListNode(carry % 10) 29 | cur = cur.next 30 | carry //= 10 31 | return dummy.next 32 | -------------------------------------------------------------------------------- /leetcode-algorithms/003. Longest Substring Without Repeating Characters/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Created by Bruce yuan on 18-2-7. 3 | 4 | 5 | class Solution: 6 | def lengthOfLongestSubstring(self, s): 7 | """ 8 | :type s: str 9 | :rtype: int 10 | """ 11 | if not s: 12 | return 0 13 | tmp = {} 14 | max_ = 0 15 | start = 0 16 | for i in range(len(s)): 17 | # 如果开始是大于我们要的那个,其实没有意义了。不需要重新弄开始 18 | if s[i] in tmp and start <= tmp.get(s[i]): 19 | start = tmp.get(s[i]) + 1 20 | else: 21 | max_ = max(max_, i - start + 1) 22 | tmp[s[i]] = i 23 | return max_ 24 | 25 | 26 | def main(): 27 | s = Solution() 28 | r = s.lengthOfLongestSubstring("pwwkew") 29 | print(r) 30 | 31 | 32 | if __name__ == '__main__': 33 | main() 34 | -------------------------------------------------------------------------------- /leetcode-algorithms/004. Median of Two Sorted Arrays/findMedianOfTwoArray.js: -------------------------------------------------------------------------------- 1 | function findMedian(nums1, nums2){ 2 | var result = [], 3 | il = 0, 4 | ir = 0; 5 | while(il < nums1.length && ir < nums2.length){ 6 | if(nums1[il] < nums2[ir]){ 7 | result.push(nums1[il]); 8 | il++; 9 | } else { 10 | result.push(nums2[ir]); 11 | ir++; 12 | } 13 | } 14 | 15 | while(il < nums1.length){ 16 | result.push(nums1[il]); 17 | il++; 18 | } 19 | while(ir < nums2.length){ 20 | result.push(nums2[ir]); 21 | ir++; 22 | } 23 | 24 | if(result.length % 2 === 0){ 25 | var i = (result.length / 2 - 1), 26 | j = (result.length / 2); 27 | console.log(i, j); 28 | 29 | return (result[i] + result[j]) / 2; 30 | 31 | } else { 32 | return result[Math.floor(result.length / 2)]; 33 | } 34 | 35 | } 36 | 37 | var a = findMedian([1,2,5], [3,4]); 38 | console.log(a); -------------------------------------------------------------------------------- /leetcode-algorithms/004. Median of Two Sorted Arrays/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Created by BBruceyuan on 18-3-2. 3 | 4 | 5 | class Solution: 6 | def findMedianSortedArrays(self, nums1, nums2): 7 | """ 8 | 有点搞笑,就这么简单的算法都beat 100% 9 | :type nums1: List[int] 10 | :type nums2: List[int] 11 | :rtype: float 12 | """ 13 | a = [] 14 | i1 = 0 15 | i2 = 0 16 | while i2 < len(nums2) and i1 < len(nums1): 17 | if nums1[i1] < nums2[i2]: 18 | a.append(nums1[i1]) 19 | i1 += 1 20 | else: 21 | a.append(nums2[i2]) 22 | i2 += 1 23 | while i1 < len(nums1): 24 | a.append(nums1[i1]) 25 | i1 += 1 26 | while i2 < len(nums2): 27 | a.append(nums2[i2]) 28 | i2 += 1 29 | 30 | # 见了一个新的数组,利用归并排序 31 | # 下面只需要找到中间的数字就好了 32 | if len(a) % 2 == 0: 33 | mid = len(a) // 2 34 | return (a[mid - 1] + a[mid]) / 2 35 | else: 36 | return a[len(a) // 2] 37 | -------------------------------------------------------------------------------- /leetcode-algorithms/005. Longest Palindromic Substring/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Created by BBruceyuan on 18-3-2. 3 | 4 | 5 | class Solution: 6 | def longestPalindrome(self, s): 7 | """ 8 | :type s: str 9 | :rtype: str 10 | """ 11 | start = end = 0 12 | for i in range(len(s)): 13 | len1 = self.extend_around_center(s, i, i) 14 | len2 = self.extend_around_center(s, i, i + 1) 15 | # print(len1, len2) 16 | length = max(len1, len2) 17 | # print(length) 18 | if length > end - start: 19 | start = i - (length - 1) // 2 20 | end = i + length // 2 21 | return s[start:end+1] 22 | 23 | @staticmethod 24 | def extend_around_center(s, l, r): 25 | left, right = l, r 26 | while left >= 0 and right < len(s) and s[left] == s[right]: 27 | left -= 1 28 | right += 1 29 | # 为什么要减一,因为结束之后,左右都各自加一或者减一了 30 | return right - left - 1 31 | 32 | @staticmethod 33 | def dynamic(s): 34 | """ 35 | 动态规划的方法来做 36 | :param s: 37 | :return: 38 | """ 39 | dp = [[0 for _ in range(len(s))] for _ in range(len(s))] 40 | ans = '' 41 | for i in range(len(s) - 1, -1, -1): 42 | for j in range(i, len(s)): 43 | dp[i][j] = (s[i] == s[j] and (j - i < 2 or dp[i + 1][j - 1])) 44 | 45 | if dp[i][j] and (ans == '' or j - i + 1 > len(ans)): 46 | ans = s[i:j+1] 47 | return ans 48 | 49 | 50 | def main(): 51 | s = Solution() 52 | # ans = s.longestPalindrome('aba') 53 | # print(ans) 54 | ans = s.longestPalindrome('ababa') 55 | print(ans) 56 | 57 | 58 | if __name__ == '__main__': 59 | main() 60 | -------------------------------------------------------------------------------- /leetcode-algorithms/006. ZigZag Conversion/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Created by BBruceyuan on 18-3-2. 3 | 4 | 5 | class Solution: 6 | def convert(self, s, numRows): 7 | """ 8 | :type s: str 9 | :type numRows: int 10 | :rtype: str 11 | """ 12 | if numRows == 1 or len(s) > numRows: 13 | return s 14 | 15 | ans = [''] * len(s) 16 | index = 0 17 | step = 1 18 | for x in s: 19 | ans[index] += x 20 | if index == 0: 21 | # 竖着走 22 | step = 1 23 | elif index == len(s) - 1: 24 | # 往回走 25 | step = -1 26 | index += step 27 | return ''.join(ans) 28 | 29 | -------------------------------------------------------------------------------- /leetcode-algorithms/007. Reverse Integer/reverse.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number} x 3 | * @return {number} 4 | */ 5 | 6 | //这里有一个好弱智的地方啊,其实不能用Number.MAX_VALUE来表示是否超过这了这个数的极限数字。 7 | //还有就是需要知道js的除法是不会自动取整啊。而且最后不要用Math.floor()这个方法,貌似有点慢啊 8 | var reverse = function(x) { 9 | var MAX = (1 << 30) * 2 - 1; 10 | var sum = 0; 11 | while(x !== 0){ 12 | sum = sum * 10 + x % 10; 13 | // ~~ 取整数 14 | x = ~~(x / 10); 15 | } 16 | 17 | return (Math.abs(sum) > MAX) ? 0 : sum; 18 | 19 | }; 20 | 21 | console.log(reverse(-21)); 22 | -------------------------------------------------------------------------------- /leetcode-algorithms/007. Reverse Integer/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Created by BBruceyuan on 18-2-19. 3 | """ 4 | Assume we are dealing with an environment which could only hold 5 | integers within the 32-bit signed integer range. 6 | For the purpose of this problem, assume that your function returns 0 7 | when the reversed integer overflows. 8 | """ 9 | 10 | 11 | class Solution(object): 12 | def reverse(self, x): 13 | """ 14 | 首先定义一下最大值 15 | :type x: int 16 | :rtype: int 17 | """ 18 | # 这就是有32bit的最大数字 (其实有一个bit_length的方法) 19 | num_max = (1 << 31) - 1 20 | sum_ = 0 21 | flag = -1 if x < 0 else 1 22 | x = abs(x) 23 | while x != 0: 24 | sum_ = sum_ * 10 + x % 10 25 | x //= 10 26 | return 0 if sum_ > num_max else sum_ * flag 27 | 28 | 29 | if __name__ == '__main__': 30 | s = Solution() 31 | print(s.reverse(-21)) 32 | -------------------------------------------------------------------------------- /leetcode-algorithms/009. Palindrome Number/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Created by Bruce yuan on 18-1-31. 3 | 4 | 5 | class Solution: 6 | def isPalindrome(self, x): 7 | """ 8 | 如果直接将数字翻转,就可能出现数字溢出,所以不能直接翻转,只能翻转一半 9 | 但是需要考虑到如果是个位数,就没法判断了 10 | :type x: int 11 | :rtype: bool 12 | """ 13 | if x < 0 or (x % 10 == 0 and x != 0): 14 | return False 15 | m = 0 16 | # 至于为什么能考虑到如果后面是一个零的情况,那是因为测试用例 17 | while x > m: 18 | tmp = x % 10 19 | m = m * 10 + tmp 20 | x = x // 10 21 | print(m) 22 | print(x) 23 | return x == m or x == m // 10 24 | 25 | 26 | if __name__ == '__main__': 27 | solution = Solution() 28 | print(solution.isPalindrome(1000)) 29 | -------------------------------------------------------------------------------- /leetcode-algorithms/011. Container With Most Water/watercontainer.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} height 3 | * @return {number} 4 | */ 5 | 6 | /*设置两个指针i, j, 一头一尾, 相向而行. 假设i指向的挡板较低, j指向的挡板较高(height[i] < height[j]). 7 | 下一步移动哪个指针? 8 | -- 若移动j, 无论height[j-1]是何种高度, 形成的面积都小于之前的面积. 9 | -- 若移动i, 若height[i+1] <= height[i], 面积一定缩小; 但若height[i+1] > height[i], 面积则有可能增大. 10 | 综上, 应该移动指向较低挡板的那个指针. 11 | */ 12 | var maxArea = function(height) { 13 | var max = 0, 14 | low = 0, 15 | k, 16 | high = height.length - 1; 17 | 18 | while(low < high){ 19 | max = Math.max(max, (high - low) * Math.min(height[low], height[high])); 20 | if(height[low] < height[high]){ 21 | //move low 22 | k = low + 1; 23 | if(k < high && height[k] <= height[low]){ 24 | k++; 25 | } 26 | low = k; 27 | 28 | } else{ 29 | //move high 30 | k = high - 1; 31 | if(k > low && height[k] <= height[high]){ 32 | k--; 33 | } 34 | high = k; 35 | } 36 | } 37 | 38 | return max; 39 | }; -------------------------------------------------------------------------------- /leetcode-algorithms/012. Integer to Roman/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Created by BBruceyuan on 18-3-3. 3 | 4 | 5 | class Solution: 6 | def intToRoman(self, num): 7 | """ 8 | :type num: int 9 | :rtype: str 10 | """ 11 | values = [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1] 12 | strs = ["M", "CM", "D", "CD", 13 | "C", "XC", "L", "XL", 14 | "X", "IX", "V", "IV", "I"] 15 | ans = [] 16 | for i, item in enumerate(values): 17 | while num >= item: 18 | num -= item 19 | ans.append(strs[i]) 20 | return ''.join(ans) 21 | -------------------------------------------------------------------------------- /leetcode-algorithms/013. Roman to Integer/romanToInt.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string} s 3 | * @return {number} 4 | */ 5 | var romanToInt = function(s) { 6 | let roman = {'M': 1000,'D': 500 ,'C': 100,'L': 50,'X': 10,'V': 5,'I': 1}; 7 | let z = 0; 8 | for (let i = 0; i < s.length - 1; i++) { 9 | if (roman[s[i]] < roman[s[i + 1]]) { 10 | z -= roman[s[i]]; 11 | } else { 12 | z += roman[s[i]]; 13 | } 14 | } 15 | 16 | return z + roman[s[s.length - 1]]; 17 | }; -------------------------------------------------------------------------------- /leetcode-algorithms/013. Roman to Integer/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Created by BBruceyuan on 18-2-26. 3 | 4 | 5 | class Solution: 6 | def romanToInt(self, s): 7 | """ 8 | :type s: str 9 | :rtype: int 10 | """ 11 | roman = {'M': 1000, 12 | 'D': 500, 13 | 'C': 100, 14 | 'L': 50, 15 | 'X': 10, 16 | 'V': 5, 17 | 'I': 1 18 | } 19 | z = 0 20 | for i in range(0, len(s) - 1): 21 | if roman[s[i]] < roman[s[i+1]]: 22 | z -= roman[s[i]] 23 | else: 24 | z += roman[s[i]] 25 | # 加上单位 26 | return z + roman[s[-1]] 27 | -------------------------------------------------------------------------------- /leetcode-algorithms/014. Longest Common Prefix/longestPre.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string[]} strs 3 | * @return {string} 4 | */ 5 | var longestCommonPrefix = function(strs) { 6 | let pre = strs[0]; 7 | let i = 1; 8 | 9 | while (i < strs.length) { 10 | while (!strs[i].startsWith(pre)) { 11 | pre = strs[0].substring(0, pre.length - 1); 12 | } 13 | 14 | i++; 15 | } 16 | 17 | return pre === undefined ? '' : pre; 18 | }; -------------------------------------------------------------------------------- /leetcode-algorithms/014. Longest Common Prefix/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Created by BBruceyuan on 18-3-20. 3 | 4 | 5 | class Solution: 6 | def longestCommonPrefix(self, strs): 7 | if len(strs) == 0: 8 | return '' 9 | ans = strs[0] 10 | for item in strs: 11 | while not item.startswith(ans): 12 | ans = strs[0][:len(ans) - 1] 13 | return ans 14 | 15 | @staticmethod 16 | def method(strs): 17 | if len(strs) == 0: 18 | return '' 19 | ans = '' 20 | for char in strs[0]: 21 | ans += char 22 | for item in strs: 23 | if not item.startswith(ans): 24 | return ans[:len(ans) - 1] 25 | return ans 26 | 27 | 28 | def main(): 29 | s = Solution() 30 | ans = s.method(['a', 'b']) 31 | print(ans) 32 | 33 | 34 | if __name__ == '__main__': 35 | main() 36 | -------------------------------------------------------------------------------- /leetcode-algorithms/015. 3Sum/3Sum.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums 3 | * @return {number[][]} 4 | */ 5 | 6 | //方法一。 7 | var threeSum = function(nums) { 8 | var hash = {}; 9 | 10 | nums.sort(function(a, b){ 11 | return a - b; 12 | }); 13 | 14 | nums.forEach(function(item){ 15 | if(hash[item]){ 16 | hash[item]++;//有重复而且要知道每个出现了多少次,因为可以一个数字出现两次。甚至三次。 17 | }else{ 18 | hash[item] = 1; 19 | } 20 | }); 21 | 22 | var result = [], 23 | hashSet = {}; 24 | 25 | for(var i = 0; i < nums.length; i++){ 26 | for(var j = i + 1; j < nums.length; j++){ 27 | var a = nums[i], 28 | b = nums[j], 29 | c = 0 - a -b; 30 | 31 | if(c < b){ 32 | break; 33 | } 34 | 35 | if(hashSet[a + ',' + b + ',' + c]){ 36 | continue; 37 | } 38 | hash[a]--; 39 | hash[b]--;//如果出现多次表示还可以继续用这个数字,否则不能用。 40 | 41 | if(hash[c]){ 42 | hashSet[a + ',' + b + ',' + c] = true; 43 | result.push([a, b, c]); 44 | } 45 | 46 | hash[a]++; 47 | hash[b]++; 48 | } 49 | } 50 | 51 | return result; 52 | 53 | }; 54 | 55 | console.log(threeSum([1,-1,-1,-1,-1,2,2,2,0,0,0])); 56 | -------------------------------------------------------------------------------- /leetcode-algorithms/015. 3Sum/3sum.py: -------------------------------------------------------------------------------- 1 | #coding: utf-8 2 | 3 | """ 4 | 想法都是一样的,不想写javascript版本了。 5 | """ 6 | 7 | class Solution(object): 8 | '''算法思路: 9 | 同上,不过这次却巧妙去重 10 | ''' 11 | def threeSum(self, nums): 12 | nums, n, r = sorted(nums), len(nums), [] 13 | for i, target in enumerate(nums): 14 | if i and nums[i - 1] == target: 15 | continue 16 | 17 | j, k = i + 1, n - 1 18 | while j < k: 19 | sum = nums[j] + nums[k] 20 | if sum > -target: 21 | k -= 1 22 | elif sum < -target: 23 | j += 1 24 | else: 25 | r.append([target, nums[j], nums[k]]) 26 | while j < k and nums[j + 1] == nums[j]: 27 | j += 1 28 | while j < k and nums[k - 1] == nums[k]: 29 | k -= 1 30 | j += 1 31 | return r -------------------------------------------------------------------------------- /leetcode-algorithms/016. 3Sum Closest/3sumClosest.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums 3 | * @param {number} target 4 | * @return {number} 5 | */ 6 | //感觉和前面的3sum思想有点接近。 7 | var threeSumClosest = function(nums, target) { 8 | var MAX_VLAUE = 2147483647; 9 | 10 | if(nums.length < 3){ 11 | return 0; 12 | } 13 | //先排序一波 14 | nums.sort(function(a, b){ 15 | return a - b; 16 | }); 17 | 18 | 19 | var minDiff = MAX_VLAUE, 20 | nowDiff, 21 | p1, 22 | p2, 23 | complement, 24 | sum, 25 | result; 26 | 27 | for(var i = 0; i < nums.length - 2; i++){//确保后面还有至少两个数 28 | complement = target - nums[i]; 29 | 30 | p1 = i+ 1; 31 | p2 = len - 1; 32 | while(p1 < p2){ 33 | sum = nums[p1] + nums[p2]; 34 | nowDiff = Math.abs(complement - sum); 35 | if(minDiff > nowDiff){ 36 | minDiff = nowDiff; 37 | result = sum + nums[i];//有遇到更小的差值的才改变 38 | } 39 | if(minDiff === 0){ 40 | break; 41 | } 42 | if(sum > complement){ 43 | p2--; 44 | }else if(sum < complement){ 45 | p1++; 46 | } 47 | } 48 | while(nums[i+1] === nums[i]){ 49 | i++;//为了做更少的工作,其实这一步只是在减少重复工作。 50 | } 51 | } 52 | 53 | return result; 54 | }; 55 | 56 | -------------------------------------------------------------------------------- /leetcode-algorithms/017. Letter Combinations of a Phone Number/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # created by BBruceyuan on 18-5-7 3 | 4 | 5 | class Solution: 6 | def letterCombinations(self, digits): 7 | """ 8 | :type digits: str 9 | :rtype: List[str] 10 | """ 11 | dic = { 12 | '2': 'abc', 13 | '3': 'def', 14 | '4': 'ghi', 15 | '5': 'jkl', 16 | '6': 'mno', 17 | '7': 'pqrs', 18 | '8': 'tuv', 19 | '9': 'wxyz' 20 | } 21 | a = [dic[x] for x in digits] 22 | from itertools import product # 笛卡尔积 23 | res = list(''.join(x) for x in product(*a)) 24 | return res if len(digits) != 0 else [] 25 | 26 | 27 | def main(): 28 | s = Solution() 29 | print(s.letterCombinations('')) 30 | 31 | 32 | if __name__ == '__main__': 33 | main() 34 | -------------------------------------------------------------------------------- /leetcode-algorithms/018. 4Sum/4sum.js: -------------------------------------------------------------------------------- 1 | /* 2 | 这里用的还是和3sum一个意思。就是先排序,然后前后逼近。 3 | 感觉要是有直接去重的set就好了,类似于python一样的。 4 | */ 5 | 6 | var fourSum = function(nums, target){ 7 | nums.sort(function(a, b){ 8 | return a - b; 9 | }); 10 | 11 | var len = nums.length, 12 | l1 = 0, 13 | l2, 14 | sum, 15 | result = [], 16 | hash = {}; 17 | 18 | var low, high; 19 | 20 | while(l1 < nums.length - 3){ 21 | l2 = l1 + 1; 22 | 23 | while(l2 < nums.length - 2){ 24 | [low, high] = [l2+1, nums.length-1]; 25 | 26 | while(low < high){ 27 | sum = nums[l1] + nums[l2] + nums[low] + nums[high]; 28 | if(sum < target){ 29 | low += 1; 30 | }else if(sum > target){ 31 | high -= 1; 32 | }else{ 33 | var str = nums[l1] + "," + nums[l2] + "," + nums[low] + "," + nums[high]; 34 | if(!hash[str]){ 35 | hash[str] = true; 36 | result.push([nums[l1], nums[l2], nums[low], nums[high]]); 37 | } 38 | low += 1; 39 | } 40 | } 41 | 42 | l2 += 1; 43 | } 44 | 45 | l1 += 1; 46 | } 47 | 48 | return result; 49 | }; 50 | 51 | console.log(fourSum([1,0,-1,0,-2,2], 0)); 52 | 53 | 54 | // method two 55 | /* 56 | 为什么这样的时间比原来那个hash做的还要慢。,简直是心态炸了 57 | */ 58 | var fourSum = function(nums, target){ 59 | nums.sort(function(a, b){ 60 | return a - b; 61 | }); 62 | 63 | var i = 0, 64 | jj = nums.length - 1, 65 | low, 66 | high, 67 | sum, 68 | result = []; 69 | 70 | 71 | while(i < nums.length - 3){ 72 | if(i && nums[i] === nums[i - 1]){ 73 | i ++; 74 | continue; 75 | } 76 | 77 | j = nums.length - 1 78 | while(j < nums.length && j > i + 2){ 79 | if(j < nums.length -1 && nums[j] === nums[j + 1]){ 80 | j--; 81 | continue; 82 | } 83 | 84 | [low, high] = [i + 1, j - 1]; 85 | while(low < high){ 86 | sum = nums[i] + nums[j] + nums[low] + nums[high]; 87 | if(sum < target){ 88 | low += 1; 89 | }else if(sum > target){ 90 | high -= 1; 91 | }else { 92 | result.push([nums[i], nums[low], nums[high], nums[j]]); 93 | while(low < high && nums[low] === nums[low + 1]){ 94 | low += 1; 95 | } 96 | while(low < high && nums[high] === nums[high - 1]){ 97 | high -= 1; 98 | } 99 | 100 | low += 1; 101 | } 102 | } 103 | 104 | j -= 1; 105 | } 106 | 107 | i++; 108 | } 109 | 110 | return result; 111 | }; 112 | 113 | console.log(fourSum([1,0,-1,0,-2,2], 0)); -------------------------------------------------------------------------------- /leetcode-algorithms/020. Valid Parentheses/isValid.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string} s 3 | * @return {boolean} 4 | */ 5 | var isValid = function(s) { 6 | let map = new Map([ 7 | [')','('], 8 | ['}', '{'], 9 | [']', '['] 10 | ]); 11 | let res = []; 12 | 13 | for (let i = 0; i < s.length; i++) { 14 | if (s[i] === '(' || s[i] === '[' || s[i] === '{') { 15 | res.push(s[i]); 16 | } else { 17 | if (map.get(s[i]) === res[res.length - 1]) { 18 | res.pop(); 19 | } else { 20 | return false; 21 | } 22 | } 23 | } 24 | 25 | if (res.length !== 0) return false; 26 | return true; 27 | }; -------------------------------------------------------------------------------- /leetcode-algorithms/020. Valid Parentheses/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Created by BBruceyuan on 18-2-19. 3 | 4 | 5 | class Solution: 6 | def isValid(self, s): 7 | """ 8 | :type s: str 9 | :rtype: bool 10 | """ 11 | stack = [] 12 | dict_ = {"]": "[", "}": "{", ")": "("} 13 | for char in s: 14 | if char in dict_.values(): 15 | stack.append(char) 16 | elif char in dict_.keys(): 17 | if stack == [] or dict_[char] != stack.pop(): 18 | return False 19 | else: 20 | return False 21 | return stack == [] 22 | -------------------------------------------------------------------------------- /leetcode-algorithms/021. Merge Two Sorted Lists/MergeTwoSortedLists.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for singly-linked list. 3 | * function ListNode(val) { 4 | * this.val = val; 5 | * this.next = null; 6 | * } 7 | */ 8 | /** 9 | * @param {ListNode} l1 10 | * @param {ListNode} l2 11 | * @return {ListNode} 12 | */ 13 | //using recursion to min my code size 14 | var mergeTwoLists = function(l1, l2) { 15 | var head; 16 | 17 | if(l1 === null){ 18 | return l2; 19 | } 20 | if(l2 === null){ 21 | return l1; 22 | } 23 | if(l1.val <= l2.val){ 24 | head = l1; 25 | head.next = mergeTwoLists(l1.next, l2); 26 | }else if(l1.val > l2.val){ 27 | head = l2; 28 | head.next = mergeTwoLists(l1, l2.next); 29 | } 30 | return head; 31 | }; 32 | 33 | //這個代碼實現要比上面的那個慢好多啊。 34 | var mergeTwoLists1 = function(l1, l2){ 35 | var head; 36 | if(l1 === null){ 37 | return l2; 38 | } 39 | if(l2 === null){ 40 | return l1; 41 | } 42 | 43 | if(l1.val < l2.val){ 44 | head = l1; 45 | l1 = l1.next; 46 | } else { 47 | head = l2; 48 | l2 = l2.next; 49 | } 50 | var cur = head; 51 | while(l1 && l2){ 52 | if(l1.val < l2.val){ 53 | cur.next = l1; 54 | cur = l1; 55 | l1 = l1.next; 56 | } else{ 57 | cur.next = l2; 58 | cur = l2; 59 | l2 = l2.next; 60 | } 61 | } 62 | 63 | if(l1){ 64 | cur.next = l1; 65 | } 66 | if(l2){ 67 | cur.next = l2; 68 | } 69 | 70 | 71 | return head; 72 | } -------------------------------------------------------------------------------- /leetcode-algorithms/026. Remove Duplicates from Sorted Array/removeDuplicates.js: -------------------------------------------------------------------------------- 1 | var removeDuplicates = function(nums) { 2 | var i = 0; 3 | for(var j = 1; j < nums.length; j++){ 4 | if(nums[i] !== nums[j]){ 5 | nums[++i] = nums[j]; 6 | } 7 | 8 | } 9 | return i+1; 10 | }; 11 | console.log(removeDuplicates([1,1,1,2,2,3,3])); 12 | 13 | // method two 14 | //利用splice可以删除元素的特点。 15 | var removeDuplicates = function(nums){ 16 | var index = 1; 17 | while(index < nums.length){ 18 | if(nums[index] === nums[index - 1]){ 19 | nums.splice(index, 1); 20 | } 21 | index++; 22 | } 23 | return nums.length; 24 | }; 25 | 26 | var a = removeDuplicates([1,2,2,3,3,3]); 27 | console.log(a); 28 | -------------------------------------------------------------------------------- /leetcode-algorithms/027. Remove Element/removeElement.js: -------------------------------------------------------------------------------- 1 | //这是最先想到的方法, 2 | var removeElement = function(nums, val) { 3 | var index = nums.indexOf(val); 4 | 5 | while(index !== -1){ 6 | nums.splice(index, 1); 7 | index = nums.indexOf(val);//这种做法每次必须从0开始,因为改变了数组的长度和解构 8 | } 9 | return nums.length; 10 | }; 11 | console.log(removeElement([1,1,2,3], 3)); 12 | 13 | // method two 14 | //利用两个指针,这里是指前后,这样只需要遍历一次。 15 | var removeElement = function(nums, val) { 16 | var start = 0, 17 | end = nums.length -1; 18 | 19 | while(start <= end){ 20 | if(nums[start] === val){ 21 | [nums[start], nums[end]] = [nums[end], nums[start]]; //我就试下这种解构赋值,感觉没有python的好看啊。 22 | end -= 1; 23 | } else{ 24 | start += 1; 25 | } 26 | } 27 | 28 | return start; 29 | } 30 | console.log(removeElement([1,1,2,3], 3)); -------------------------------------------------------------------------------- /leetcode-algorithms/028. Implement strStr()/strStr.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string} haystack 3 | * @param {string} needle 4 | * @return {number} 5 | */ 6 | 7 | // 这题主要是自己实现一个indexOf 8 | var strStr = function(haystack, needle) { 9 | for (let i = 0; ; i++) { 10 | for (let j = 0; ; j++) { 11 | if (j === needle.length) return i; 12 | if (i + j === haystack.length) return -1; 13 | if (needle.charAt(j) !== haystack.charAt(i + j)) break; 14 | } 15 | } 16 | }; -------------------------------------------------------------------------------- /leetcode-algorithms/031. Next Permutation/nextPermutation.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums 3 | * @return {void} Do not return anything, modify nums in-place instead. 4 | */ 5 | var nextPermutation = function(nums) { 6 | if (nums.lengt === 1) { 7 | return; 8 | } 9 | let i = nums.length - 2; 10 | // find first reversed num, 11 | for (; i >= 0 ; i--) { 12 | if (nums[i] < nums[i + 1]) { 13 | break; 14 | } 15 | } 16 | if (i < 0) { 17 | nums.sort((a, b) => a - b); 18 | } else { 19 | let j = i + 1, 20 | ni = nums[i]; 21 | // find first num that bigger than the first reversed num, (start from end) 22 | for (; j < nums.length; j++) { 23 | if (nums[j] <= ni) break; 24 | } 25 | j--; 26 | [nums[i], nums[j]] = [nums[j], nums[i]]; 27 | let tempArray = nums.slice(i + 1).sort((a, b) => a - b); 28 | nums.length = i + 1; 29 | Array.prototype.push.apply(nums, tempArray); 30 | } 31 | }; -------------------------------------------------------------------------------- /leetcode-algorithms/033. Search in Rotated Sorted Array/search.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums 3 | * @param {number} target 4 | * @return {number} 5 | */ 6 | //相当于自己实现了一下indexOf这个函数的简单版。 7 | var search = function(nums, target) { 8 | // for(var i = 0; i < nums.length; i++){ 9 | // if(nums[i] === target){ 10 | // return i; 11 | // } 12 | // } 13 | 14 | // return -1; 15 | return nums.indexOf(target); 16 | }; 17 | 18 | 19 | // mothod two 20 | // /** 21 | // * @param {number[]} nums 22 | // * @param {number} target 23 | // * @return {number} 24 | // */ 25 | //这里的二分法就是快一点。 26 | var search = function(nums, target){ 27 | var i = 0, 28 | j = nums.length - 1, 29 | mid; 30 | 31 | while(i <= j){ 32 | mid = i + ~~((j - i) / 2); 33 | //console.log(mid); 34 | if(nums[mid] > target){ 35 | if(nums[i] > nums[j] && target <= nums[j] &&nums[mid] >= nums[i]){ 36 | i = mid + 1;//左边全排列 37 | }else{ 38 | j = mid - 1; 39 | } 40 | }else if(nums[mid] < target){ 41 | if(nums[i] > nums[j] && target >= nums[i] && nums[mid] <= nums[i]){ 42 | j = mid - 1; 43 | }else { 44 | i = mid + 1; 45 | } 46 | }else { 47 | return mid; 48 | } 49 | } 50 | 51 | return -1; 52 | }; 53 | 54 | console.log(search([5,7,8,9,1,2,3], 45)); 55 | 56 | 57 | 58 | /* 59 | #python的写法。 60 | def search(self, nums, target): 61 | """ 62 | :type nums: List[int] 63 | :type target: int 64 | :rtype: int 65 | """ 66 | return self.binarySearch(0, len(nums)-1, nums, target) 67 | 68 | def binarySearch(self, begin, end, nums, target): 69 | if begin > end: 70 | return -1 71 | mid = (begin + end)/2 72 | if nums[mid] == target: 73 | return mid 74 | if nums[mid] < nums[end]: # sorted right half 75 | if target > nums[mid] and target <= nums[end]: 76 | return self.binarySearch(mid+1, end, nums, target) 77 | else: 78 | return self.binarySearch(begin, mid-1, nums, target) 79 | else: # sorted left half 80 | if target < nums[mid] and target >= nums[begin]: 81 | return self.binarySearch(begin, mid-1, nums, target) 82 | else: 83 | return self.binarySearch(mid+1, end, nums, target) 84 | */ 85 | -------------------------------------------------------------------------------- /leetcode-algorithms/034. Search for a Range/searchForARange.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums 3 | * @param {number} target 4 | * @return {number[]} 5 | */ 6 | 7 | //这题思路简直不要太简单,可以直接调用函数。 8 | var searchRange = function(nums, target) { 9 | var result = []; 10 | result.push(nums.indexOf(target)); 11 | result.push(nums.lastIndexOf(target)); 12 | return result; 13 | }; 14 | 15 | // meothod 2 16 | //自己写一个函数来执行 就好了,前后同时遍历,特别值得一提的是这个方法竟然要比上面那个方法快 17 | var searchRange2 = function(nums, target) { 18 | var result = []; 19 | 20 | nums.filter(function(item, index, array){ 21 | if(item === target){ 22 | result.push(index); 23 | } 24 | }); 25 | if(result.length === 0){ 26 | result.push(-1, -1); 27 | } else if(result.length === 1){ 28 | result[1] = result[0]; 29 | } else { 30 | result.splice(1, result.length - 2); 31 | } 32 | 33 | return result; 34 | }; 35 | 36 | 37 | // method3 38 | //二分法时间复杂度就是o(lgn),时间上还是比前面两种方法要慢 39 | var searchRange3 = function(nums, target) { 40 | 41 | let loPos = -1, hiPos = -1; 42 | 43 | searchPos(0, nums.length - 1); 44 | 45 | function searchPos(lo, hi) { 46 | if (lo > hi) return; 47 | 48 | const mid = parseInt((lo + hi) / 2); 49 | 50 | if (nums[mid] === target) { 51 | if (loPos === -1 || loPos > mid) loPos = mid; 52 | if (hiPos === -1 || hiPos < mid) hiPos = mid; 53 | searchPos(lo, mid - 1); 54 | searchPos(mid + 1, hi); 55 | } 56 | 57 | if (nums[mid] > target) { 58 | searchPos(lo, mid - 1); 59 | } 60 | 61 | if (nums[mid] < target) { 62 | searchPos(mid + 1, hi); 63 | } 64 | } 65 | 66 | return [loPos, hiPos]; 67 | }; -------------------------------------------------------------------------------- /leetcode-algorithms/035. Search Insert Position/searchInsert.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums 3 | * @param {number} target 4 | * @return {number} 5 | */ 6 | //二分法 7 | var searchInsert = function(nums, target) { 8 | var low = 0, 9 | high = nums.length - 1, 10 | mid; 11 | 12 | while(low <= high){ 13 | mid = low + Math.floor((high - low) / 2); 14 | 15 | if(target < nums[mid]){ 16 | if(mid === 0 || ((mid > 0) && nums[mid - 1] < target)){ 17 | return mid; 18 | } 19 | high = mid - 1; 20 | }else if(target > nums[mid]){ 21 | low = mid + 1; 22 | }else { 23 | return mid; 24 | } 25 | } 26 | return low; 27 | }; 28 | 29 | console.log(searchInsert([1,2,3], 2.5)); 30 | 31 | // method two 32 | var searchInsert2 = function(nums, target) { 33 | var hash = {}; 34 | nums.forEach(function(item, index, array){ 35 | hash[item] = index; 36 | }); 37 | 38 | if(hash[target] !== undefined){ 39 | return hash[target]; 40 | } 41 | nums[-1] = -Number.MAX_VALUE; 42 | nums[nums.length] = Number.MAX_VALUE; 43 | for(var i = 0; i < nums.length; i++){ 44 | if(nums[i - 1] < target && nums[i] > target){ 45 | return i; 46 | } 47 | } 48 | }; 49 | 50 | console.log(searchInsert([1,2,3], 0)); -------------------------------------------------------------------------------- /leetcode-algorithms/038. Count and Say/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Created by Bruce yuan on 18-1-25. 3 | 4 | 5 | class Solution: 6 | def countAndSay(self, n): 7 | """ 8 | :type n: int 9 | :rtype: str 10 | """ 11 | s = '1' 12 | for _ in range(n - 1): 13 | num, tmp_str, count = s[0], '', 0 14 | for char in s: 15 | if num == char: 16 | count += 1 17 | else: 18 | tmp_str += str(count) + num 19 | num = char 20 | count = 1 21 | tmp_str += str(count) + char 22 | s = tmp_str 23 | return s 24 | 25 | 26 | def main(): 27 | a = Solution() 28 | result = a.countAndSay(4) 29 | print(result) 30 | 31 | if __name__ == '__main__': 32 | main() -------------------------------------------------------------------------------- /leetcode-algorithms/039. Combination Sum/combinationSum.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} candidates 3 | * @param {number} target 4 | * @return {number[][]} 5 | */ 6 | 7 | //这里真是搞了我好久,一开始没有想到递归调用,直接就GG 8 | var ans, res; 9 | 10 | function search(index, sum, candidates, target) { 11 | if(sum === target){ 12 | var temp = ans.map(function(item){ 13 | return item; 14 | }); 15 | res.push(temp); 16 | return; 17 | } 18 | 19 | for(var i = index; i < candidates.length; i++){ 20 | if(sum + candidates[i] > target) break; 21 | ans.push(candidates[i]); 22 | console.log(ans); 23 | search(i, sum + candidates[i], candidates, target); 24 | ans.pop(); 25 | } 26 | } 27 | 28 | var combinationSum = function(candidates, target) { 29 | res = []; 30 | candidates.sort(function(a, b){ 31 | return a - b; 32 | }); 33 | for(var i = 0; i < candidates.length; i++){ 34 | ans = [candidates[i]]; 35 | search(i, candidates[i], candidates, target); 36 | } 37 | return res; 38 | }; 39 | console.log(combinationSum([1,2], 3)); -------------------------------------------------------------------------------- /leetcode-algorithms/040. Combination Sum II/combinationSumTwo.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} candidates 3 | * @param {number} target 4 | * @return {number[][]} 5 | */ 6 | //一开始用hash = {}来去重,慢了很多。以后尽量少用这个来去重 7 | var ans, 8 | res; 9 | var combinationSum2 = function(candidates, target) { 10 | res = []; 11 | candidates.sort(function(a, b){ 12 | return a - b; 13 | }); 14 | for(var i = 0; i < candidates.length; i++){ 15 | if(i && candidates[i] === candidates[i -1]) continue; 16 | ans = [candidates[i]]; 17 | search(i + 1, candidates[i], candidates, target); 18 | } 19 | return res; 20 | }; 21 | 22 | function search(index, sum, candidates, target){ 23 | if(sum === target){ 24 | var temp = ans.map(function(item){ 25 | return item; 26 | }); 27 | res.push(temp); 28 | return; 29 | } 30 | 31 | for(var i = index; i < candidates.length; i++){ 32 | if(sum + candidates[i] > target) break; 33 | if(i > index && candidates[i] === candidates[i - 1]) continue; 34 | ans.push(candidates[i]); 35 | search(i + 1, sum + candidates[i], candidates, target); 36 | ans.pop(); 37 | } 38 | } 39 | 40 | console.log(combinationSum2([10, 1, 2, 7, 6, 1, 5],8)); 41 | console.log(combinationSum2([2,2,2,2],4)); 42 | console.log(combinationSum2([1,1],1)); 43 | 44 | //hash去重,还有就是leetcode在测试多个test的时候只是调用了函数,所以全局变量不会改变。 45 | //所以hash要在主函数里面初始化。 46 | // var ans, 47 | // res, 48 | // hash; 49 | // var combinationSum2 = function(candidates, target) { 50 | // hash = {}; 51 | // res = []; 52 | // candidates.sort(function(a, b){ 53 | // return a - b; 54 | // }); 55 | // for(var i = 0; i < candidates.length; i++){ 56 | // //if(i && candidates[i] === candidates[i -1]) continue; 57 | // ans = [candidates[i]]; 58 | // search(i + 1, candidates[i], candidates, target); 59 | // } 60 | // return res; 61 | // }; 62 | 63 | // function search(index, sum, candidates, target){ 64 | // if(sum === target){ 65 | // var temp = ans.map(function(item){ 66 | // return item; 67 | // }); 68 | // if(!hash[temp]){ 69 | // res.push(temp); 70 | // hash[temp] = true; 71 | // } 72 | // return; 73 | // } 74 | 75 | // for(var i = index; i < candidates.length; i++){ 76 | // if(sum + candidates[i] > target) break; 77 | // ans.push(candidates[i]); 78 | // search(i + 1, sum + candidates[i], candidates, target); 79 | // ans.pop(); 80 | // } 81 | // } -------------------------------------------------------------------------------- /leetcode-algorithms/041. First Missing Positive/firstMissingPositive.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums 3 | * @return {number} 4 | */ 5 | //O(n) S(n);注释写的这种方法其实是不符合要求,空间复杂度超了 6 | var firstMissingPositive = function(nums) { 7 | // var hash = {}; 8 | // nums.forEach(function(item){ 9 | // hash[item] = true; 10 | // }); 11 | // var first = 1; 12 | // while(hash[first]){ 13 | // first += 1; 14 | // } 15 | // return first; 16 | nums.forEach(function(item, index, array){ 17 | var current = item;//当前待处理符号。 18 | while(current > 0 && current <= nums.length && nums[current - 1] !== current){ 19 | var temp = nums[current - 1];//下一个待处理符号 20 | // [nums[index], nums[current - 1]] = [nums[current - 1], nums[index]]; 21 | nums[current - 1] = current; 22 | current = temp; 23 | } 24 | }); 25 | console.log(nums); 26 | for(var i = 0; i < nums.length; i++){ 27 | if(nums[i] !== i + 1){ 28 | return i + 1; 29 | } 30 | } 31 | return nums.length + 1; 32 | }; 33 | console.log(firstMissingPositive([3,4,-1,1,5])); -------------------------------------------------------------------------------- /leetcode-algorithms/043. Multiply Strings/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Created by Bruce yuan on 18-1-27. 3 | 4 | 5 | class Solution: 6 | def multiply(self, num1, num2): 7 | """ 8 | :type num1: str 9 | :type num2: str 10 | :rtype: str 11 | """ 12 | # 因为题目说了不会用 0 开头,所以 0 开头一定是 0 13 | if num1[0] == '0' or num2[0] == '0': 14 | return '0' 15 | # 用一个数组来表示结果 16 | result = [0] * (len(num1) + len(num2)) 17 | cur_pos = len(result) - 1 18 | 19 | for first_str in reversed(num1): 20 | # 第一个乘数 21 | int1 = int(first_str) 22 | tmp_pos = cur_pos 23 | carry = 0 24 | for second_str in reversed(num2): 25 | # 第二个乘数 26 | int2 = int(second_str) 27 | tmp_result = int1 * int2 28 | # 返回进位和当前位置的数字,因为两个数相乘最多等于 81 29 | result[tmp_pos] += tmp_result 30 | result[tmp_pos - 1] += result[tmp_pos] // 10 31 | result[tmp_pos] = result[tmp_pos] % 10 32 | # print(result) 33 | tmp_pos -= 1 34 | cur_pos -= 1 35 | for index, item in enumerate(result): 36 | if item != 0: 37 | pos = index 38 | break 39 | return ''.join(str(item) for item in result[pos:]) 40 | 41 | 42 | def main(): 43 | a = Solution() 44 | result = a.multiply('999', '999') 45 | print(result) 46 | 47 | if __name__ == '__main__': 48 | main() 49 | -------------------------------------------------------------------------------- /leetcode-algorithms/048. Rotate Image/rotate.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[][]} matrix 3 | * @return {void} Do not return anything, modify matrix in-place instead. 4 | */ 5 | 6 | /* 7 | * clockwise rotate 8 | * first reverse up to down, then swap the symmetry 9 | * 1 2 3 7 8 9 7 4 1 10 | * 4 5 6 => 4 5 6 => 8 5 2 11 | * 7 8 9 1 2 3 9 6 3 12 | */ 13 | 14 | /* 15 | * anticlockwise rotate 16 | * first reverse left to right, then swap the symmetry 17 | * 1 2 3 3 2 1 3 6 9 18 | * 4 5 6 => 6 5 4 => 2 5 8 19 | * 7 8 9 9 8 7 1 4 7 20 | */ 21 | var rotate = function(matrix) { 22 | matrix = matrix.reverse(); 23 | for (let i = 0; i < matrix.length; i++) { 24 | for (let j = i + 1; j < matrix.length; j++) { 25 | [matrix[i][j], matrix[j][i]] = [matrix[j][i], matrix[i][j]]; 26 | } 27 | } 28 | }; -------------------------------------------------------------------------------- /leetcode-algorithms/048. Rotate Image/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Created by BBruceyuan on 18-2-28. 3 | 4 | 5 | class Solution: 6 | def rotate(self, matrix): 7 | """ 8 | 具体做法可以查看一下我在js文件中的解释 9 | 10 | 这里我是先直接reverse,然后转置一下 11 | 12 | 这题不需要return anything 13 | :type matrix: List[List[int]] 14 | :rtype: void Do not return anything, modify matrix in-place instead. 15 | """ 16 | matrix.reverse() 17 | for i in range(len(matrix)): 18 | for j in range(i + 1, len(matrix)): 19 | matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j] 20 | -------------------------------------------------------------------------------- /leetcode-algorithms/050. Pow(x, n)/myPow.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number} x 3 | * @param {number} n 4 | * @return {number} 5 | */ 6 | 7 | // 迭代法 8 | var myPow = function(x, n) { 9 | var isNegative = n < 0 ? (n *= -1, true) : false; 10 | 11 | var ans = 1; 12 | while (n) { 13 | (n & 1) && (ans *= x); 14 | x *= x; 15 | n >>>= 1; // 无符号右移 16 | } 17 | 18 | return isNegative ? 1 / ans : ans; 19 | }; 20 | 21 | 22 | // 递归 23 | function myPow2(x, n) { 24 | if (n === 0) { 25 | return 1; 26 | } 27 | if (n === 1) { 28 | return x; 29 | } 30 | if (n < 0) { 31 | n = - n; 32 | x = 1 / x; 33 | } 34 | return (n%2===0) ? myPow2(x*x, n/2) : x * myPow2(x, n - 1); 35 | } 36 | 37 | -------------------------------------------------------------------------------- /leetcode-algorithms/053. Maximum Subarray/maxSubArray.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums 3 | * @return {number} 4 | */ 5 | var maxSubArray = function(nums) { 6 | var max = nums[0], 7 | current = 0; 8 | for(var i = 0; i < nums.length; i++){ 9 | if(current > 0){ 10 | current += nums[i]; 11 | }else{ 12 | current = nums[i]; 13 | } 14 | if(current > max){ 15 | max = current; 16 | } 17 | } 18 | return max; 19 | }; 20 | 21 | console.log(maxSubArray([-1,-2,-3])); 22 | -------------------------------------------------------------------------------- /leetcode-algorithms/054. Spiral Matrix/spiralOrder.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[][]} matrix 3 | * @return {number[]} 4 | */ 5 | var spiralOrder = function(matrix) { 6 | var result = []; 7 | if(matrix.length === 0)return result; 8 | var rowEnd = matrix.length - 1,//列的长度 9 | colEnd = matrix[0].length - 1, 10 | rowBegin = 0, 11 | colBegin = 0; 12 | 13 | while(rowBegin <= rowEnd && colBegin <= colEnd){ 14 | //往又遍历 15 | for(let i = colBegin; i <= colEnd; i++){ 16 | result.push(matrix[rowBegin][i]); 17 | } 18 | rowBegin++; 19 | for(let i = rowBegin; i <= rowEnd; i++){ 20 | result.push(matrix[i][colEnd]); 21 | } 22 | colEnd--; 23 | if(rowBegin <= rowEnd){ 24 | for(let i = colEnd; i >= colBegin; i--){ 25 | result.push(matrix[rowEnd][i]); 26 | } 27 | } 28 | rowEnd--; 29 | if(colBegin <= colEnd){ 30 | for(let i = rowEnd; i >= rowBegin; i--){ 31 | result.push(matrix[i][colBegin]); 32 | } 33 | } 34 | colBegin++; 35 | }//end while 36 | 37 | return result; 38 | }; 39 | 40 | console.log(spiralOrder([[ 1, 2, 3 ],[ 4, 5, 6 ],[ 7, 8, 9 ]])); -------------------------------------------------------------------------------- /leetcode-algorithms/055. Jump Game/canjmp.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums 3 | * @return {boolean} 4 | */ 5 | var canJump = function(nums) { 6 | var sum = 0, 7 | target = nums.length - 1; 8 | 9 | //i要小于sum是因为这里要保证必须玩下调,如果不往下跳肯定到不了最后一个 10 | for(var i = 0; i < nums.length && i <= sum; i++){ 11 | if(sum >= target)return true; 12 | sum = Math.max(sum, i + nums[i]); 13 | } 14 | return false; 15 | }; -------------------------------------------------------------------------------- /leetcode-algorithms/058. Length of Last Word/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Created by Bruce yuan on 18-1-30. 3 | 4 | 5 | class Solution: 6 | def lengthOfLastWord(self, s): 7 | """ 8 | :type s: str 9 | :rtype: int 10 | """ 11 | return len(s.strip().split(' ')[-1]) 12 | -------------------------------------------------------------------------------- /leetcode-algorithms/059. Spiral Matrix II/generateMatrix.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number} n 3 | * @return {number[][]} 4 | */ 5 | var generateMatrix = function(n) { 6 | if(n === 0){ 7 | return []; 8 | } 9 | var max = n * n, 10 | rowBegin = 0, //行 11 | rowEnd = n - 1, 12 | colBegin = 0, //列 13 | colEnd = n - 1, 14 | result = [], 15 | temp; 16 | //其实可以并不需要把每一个初始化为零,不过这里为了速度更快,就初始化了 17 | /* 18 | for(let i = 0; i < n; i++){ 19 | result.push([]); 20 | }//这样就可以,因为js可以给空数组赋值并且将其他未复制的自动填上undefined. 21 | */ 22 | for(let i = 0; i < n; i++){ 23 | temp = []; 24 | for(let j = 0; j < n; j++){ 25 | temp.push(0); 26 | } 27 | result.push(temp); 28 | } 29 | 30 | var i = 1; 31 | while(i <= max && colBegin <= colEnd && rowBegin <= rowEnd){ 32 | for(let j = colBegin; j <= colEnd; j++){ 33 | result[rowBegin][j] = i++; 34 | } 35 | rowBegin++; 36 | 37 | for(let j = rowBegin; j <= rowEnd; j++){ 38 | result[j][colEnd] = i++; 39 | } 40 | colEnd--; 41 | 42 | if(colEnd >= colBegin){ 43 | for(let j = colEnd; j >= colBegin; j--){ 44 | result[rowEnd][j] = i++; 45 | } 46 | } 47 | rowEnd--; 48 | 49 | if(rowEnd >= rowBegin){ 50 | for(let j = rowEnd; j >= rowBegin; j--){ 51 | result[j][colBegin] = i++; 52 | } 53 | } 54 | colBegin++; 55 | } 56 | 57 | return result; 58 | }; 59 | 60 | console.log(generateMatrix(3)); -------------------------------------------------------------------------------- /leetcode-algorithms/066. Plus One/plusOne.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} digits 3 | * @return {number[]} 4 | */ 5 | //下面这个方法要快,是不是只要有判断速度就会变慢啊。 6 | 7 | var plusOne = function(digits) { 8 | // for(var i = digits.length - 1; i >= 0; i--){ 9 | // if(digits[i] < 9){ 10 | // digits[i]++; 11 | // return digits; 12 | // } 13 | // digits[i] = 0; 14 | // } 15 | // digits.unshift(1); 16 | // return digits; 17 | var ans = [], 18 | add = 0, 19 | len = digits.length; 20 | 21 | digits[len - 1]++; 22 | 23 | for(var i = len - 1; i >= 0; i--) { 24 | var sum = digits[i] + add; 25 | 26 | ans[i] = sum % 10; 27 | add = ~~(sum / 10); 28 | } 29 | 30 | if (add) 31 | ans.unshift(add); 32 | 33 | return ans; 34 | }; 35 | 36 | console.log(plusOne([1,2,3,9])); -------------------------------------------------------------------------------- /leetcode-algorithms/067. Add Binary/addBinary.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string} a 3 | * @param {string} b 4 | * @return {string} 5 | */ 6 | var addBinary = function(a, b) { 7 | a = a.split('').reverse(); 8 | b = b.split('').reverse(); 9 | 10 | let res = []; 11 | let carr = 0; 12 | 13 | for (let i = 0; i < Math.max(a.length, b.length); i++) { 14 | let sum = (a[i] === undefined ? 0 : Number(a[i])) + 15 | (b[i] === undefined ? 0 : Number(b[i])) + carr; 16 | res[i] = sum & 1; 17 | if (sum >= 2) { 18 | carr = 1; 19 | } else { 20 | carr = 0; 21 | } 22 | } 23 | 24 | if (carr) { 25 | res[Math.max(a.length, b.length)] = 1; 26 | } 27 | 28 | return res.reverse().join(''); 29 | 30 | }; 31 | console.log(addBinary('110', '11111')); -------------------------------------------------------------------------------- /leetcode-algorithms/069. Sqrt(x)/mySqt.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number} x 3 | * @return {number} 4 | * 只会用二分法,牛顿迭代之类的都忘了 5 | */ 6 | var mySqrt = function(x) { 7 | if (x === 0) return 0; 8 | let low = 0, 9 | high = x; 10 | 11 | while (true) { 12 | let a = ~~((low + high) / 2);// 很烦这种题,其实可以更精确,非要搞成是整数。 13 | 14 | if (a * a > x) { 15 | high = a - 1; 16 | } else { 17 | let b = a + 1; 18 | if (b * b > x) { 19 | return a; 20 | } 21 | low = a + 1; 22 | } 23 | } 24 | }; -------------------------------------------------------------------------------- /leetcode-algorithms/070. Climbing Stairs/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Created by Bruce yuan on 18-2-4. 3 | 4 | 5 | class Solution: 6 | def climbStairs(self, n): 7 | """ 8 | :type n: int 9 | :rtype: int 10 | """ 11 | if n == 1 or n == 0: 12 | return n 13 | a, b = 1, 2 14 | for _ in range(2, n): 15 | tmp = a + b 16 | a = b 17 | b = tmp 18 | # a, b = b, a + b # 效果是一样的,实际上也用了一个额外的空间 19 | return b 20 | 21 | def dynamic_method(self, n): 22 | """ 23 | 和上面用斐波那契数列方法本质是一样的 24 | :param n: 25 | :return: 26 | """ 27 | if n == 0 or n == 1: 28 | return n 29 | a = [1, 2] 30 | for i in range(2, n): 31 | a.append(a[i - 1] + a[i - 2]) 32 | return a[-1] 33 | 34 | def recursive_method(self, n): 35 | """ 36 | 这个方法超时了 37 | :param n: 38 | :return: 39 | """ 40 | if n == 1 or n == 0: 41 | return n 42 | if n == 2: 43 | return 2 44 | # 这个竟然超时了 45 | return self.climbStairs(n - 1) + self.climbStairs(n - 2) -------------------------------------------------------------------------------- /leetcode-algorithms/083. Remove Duplicates from Sorted List/deleteDuplicates.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for singly-linked list. 3 | * function ListNode(val) { 4 | * this.val = val; 5 | * this.next = null; 6 | * } 7 | */ 8 | /** 9 | * @param {ListNode} head 10 | * @return {ListNode} 11 | * 注释部分是我自己想到的方法,后面递归是看的大神的 12 | * 自己还有另外一个想法,就是把这个链表的所有数字先建一个set 13 | * 然后等于去重了,然后再根据这个东西新建一个链表。 14 | * 思路其实和注释一样,只是可以用一些语法糖 15 | */ 16 | var deleteDuplicates = function(head) { 17 | // let result = []; 18 | // while(head) { 19 | // result.push(new ListNode(head.val)); 20 | // head = head.next; 21 | // } 22 | 23 | // if (result.length === 0) return head; 24 | // for (let i = result.length - 1; i >= 1; i--) { 25 | // if (result[i].val === result[i - 1].val) { 26 | // result.splice(i, 1); 27 | // } 28 | // } 29 | 30 | // for (let i = 0; i < result.length; i++) { 31 | // result[i].next = result[i + 1]; 32 | // } 33 | 34 | // return result[0]; 35 | 36 | if (head === null || head.next === null) return head; 37 | 38 | head.next = deleteDuplicates(head.next); 39 | return head.val == head.next.val ? head.next : head; 40 | }; -------------------------------------------------------------------------------- /leetcode-algorithms/084. Largest Rectangle in Histogram/largestRectangleArea.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} heights 3 | * @return {number} 4 | */ 5 | var largestRectangleArea = function(heights) { 6 | heights.push(0); 7 | 8 | var max = 0; 9 | 10 | var stack = []; 11 | 12 | for (var i = 0, len = heights.length; i < len; i++) { 13 | while (stack.length && heights[i] < heights[stack[stack.length - 1]]) { 14 | var top = stack.pop(); // 取到最高的那一列 15 | 16 | // 然后找到次高的那一列 17 | var nextTop = stack.length === 0 ? -1 : stack[stack.length - 1]; 18 | 19 | max = Math.max((i - nextTop - 1) * heights[top], max); 20 | } 21 | 22 | stack.push(i); 23 | } 24 | 25 | return max; 26 | }; 27 | 28 | 29 | console.log(largestRectangleArea([2,4,5,6,2,3])); -------------------------------------------------------------------------------- /leetcode-algorithms/088. Merge Sorted Array/mergeSortedArray.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums1 3 | * @param {number} m 4 | * @param {number[]} nums2 5 | * @param {number} n 6 | * @return {void} Do not return anything, modify nums1 in-place instead. 7 | */ 8 | 9 | // 因为不提供新的额外空间,所以这里最好是从后面开始往前遍历 10 | var merge = function(nums1, m, nums2, n) { 11 | while (m > 0 && n > 0) { 12 | if (nums1[m - 1] > nums2[n - 1]) { 13 | nums1[m + n - 1] = nums1[m - 1]; 14 | m--; 15 | } else { 16 | nums1[m + n - 1] = nums2[n - 1]; 17 | n--; 18 | } 19 | } 20 | while (m > 0) { 21 | nums1[m - 1] = nums1[m - 1]; 22 | m--; 23 | } 24 | while (n > 0) { 25 | nums1[n - 1] = nums2[n - 1]; 26 | n--; 27 | } 28 | }; -------------------------------------------------------------------------------- /leetcode-algorithms/092. Reverse Linked List II/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Created by Bruce yuan on 18-2-2. 3 | # Definition for singly-linked list. 4 | 5 | 6 | class ListNode(object): 7 | def __init__(self, x): 8 | self.val = x 9 | self.next = None 10 | 11 | 12 | class Solution: 13 | def reverse_list(self, head, m, n): 14 | """ 15 | 需要一个头结点,因为加入需要从第一个开始,我们就需要记录前面那个一个节点 16 | """ 17 | if head is None: 18 | return None 19 | dummy = ListNode(0) 20 | dummy.next = head 21 | pre = dummy 22 | for _ in range(m - 1): 23 | pre = pre.next 24 | 25 | start = pre.next 26 | then = pre.next.next 27 | 28 | for _ in range(n - m): 29 | start.next = then.next 30 | then.next = pre.next 31 | pre.next = then 32 | then = start.next 33 | return dummy.next 34 | -------------------------------------------------------------------------------- /leetcode-algorithms/100. Same Tree/isSameTree.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * function TreeNode(val) { 4 | * this.val = val; 5 | * this.left = this.right = null; 6 | * } 7 | */ 8 | /** 9 | * @param {TreeNode} p 10 | * @param {TreeNode} q 11 | * @return {boolean} 12 | */ 13 | var isSameTree = function(p, q) { 14 | if (p === null && q === null) return true; 15 | if (p === null || q === null) return false; 16 | if (p.val !== q.val) { 17 | return false; 18 | } else { 19 | return isSameTree(p.left, q.left) && isSameTree(p.right, q.right); 20 | } 21 | }; -------------------------------------------------------------------------------- /leetcode-algorithms/101. Symmetric Tree/isSymmetric.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for a binary tree node. 3 | * function TreeNode(val) { 4 | * this.val = val; 5 | * this.left = this.right = null; 6 | * } 7 | */ 8 | /** 9 | * @param {TreeNode} root 10 | * @return {boolean} 11 | */ 12 | var isSymmetric = function(root) { 13 | if (root === null) { 14 | return true; 15 | } else { 16 | return isSymmetriced(root.left, root.right); 17 | } 18 | }; 19 | 20 | function isSymmetriced (left, right) { 21 | if (left === null || right === null) { 22 | return left === right; 23 | } 24 | if (left.val !== right.val) { 25 | return false; 26 | } 27 | 28 | return isSymmetriced(left.left, right.right) && isSymmetriced(left.right, right.left); 29 | } -------------------------------------------------------------------------------- /leetcode-algorithms/102. Binary Tree Level Order Traversal/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Created by Bruce yuan on 18-2-6. 3 | 4 | 5 | # Definition for a binary tree node. 6 | # class TreeNode: 7 | # def __init__(self, x): 8 | # self.val = x 9 | # self.left = None 10 | # self.right = None 11 | 12 | class Solution: 13 | def levelOrder(self, root): 14 | """ 15 | :type root: TreeNode 16 | :rtype: List[List[int]] 17 | """ 18 | if root is None: 19 | return [] 20 | import queue 21 | q = queue.Queue() 22 | q.put(root) 23 | result = [] 24 | while not q.empty(): 25 | tmp = [] 26 | for _ in range(q.qsize()): 27 | item = q.get() 28 | tmp.append(item.val) 29 | if item.left is not None: 30 | q.put(item.left) 31 | if item.right is not None: 32 | q.put(item.right) 33 | result.append(tmp) 34 | return result 35 | -------------------------------------------------------------------------------- /leetcode-algorithms/104. Maximum Depth of Binary Tree/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Created by Bruce yuan on 18-2-4. 3 | 4 | 5 | # Definition for a binary tree node. 6 | # class TreeNode: 7 | # def __init__(self, x): 8 | # self.val = x 9 | # self.left = None 10 | # self.right = None 11 | 12 | class Solution: 13 | def maxDepth(self, root): 14 | """ 15 | :type root: TreeNode 16 | :rtype: int 17 | """ 18 | if root is None: 19 | return 0 20 | return 1 + max(self.maxDepth(root.left), self.maxDepth(root.right)) 21 | 22 | @staticmethod 23 | def method_two(root): 24 | if root is None: 25 | return 0 26 | import queue 27 | q = queue.Queue() 28 | q.put(root) 29 | count = 0 30 | # BFS 遍历 31 | while not q.empty(): 32 | count += 1 33 | for _ in range(q.qsize()): 34 | item = q.get() 35 | # 下面两个都要判断 36 | if item.left is not None: 37 | q.put(item.left) 38 | if item.right is not None: 39 | q.put(item.right) 40 | return count 41 | 42 | @staticmethod 43 | def method_three(root): 44 | # DFS 45 | if root is None: 46 | return 0 47 | node = [root] 48 | value = [1] 49 | max_num = 0 50 | while len(node) != 0: 51 | item = node.pop() 52 | tmp = value.pop() 53 | max_num = max(tmp, max_num) 54 | if item.left is not None: 55 | node.push(item.left) 56 | value.push(tmp + 1) 57 | if item.right is not None: 58 | node.push(item.right) 59 | value.push(tmp + 1) 60 | return max_num 61 | -------------------------------------------------------------------------------- /leetcode-algorithms/107. Binary Tree Level Order Traversal II/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Created by Bruce yuan on 18-2-6. 3 | 4 | 5 | # Definition for a binary tree node. 6 | # class TreeNode: 7 | # def __init__(self, x): 8 | # self.val = x 9 | # self.left = None 10 | # self.right = None 11 | 12 | class Solution: 13 | def levelOrderBottom(self, root): 14 | """ 15 | 做了上面这个之后,竟然一次就过了2333,哈哈哈 16 | :type root: TreeNodes 17 | :rtype: List[List[int]] 18 | """ 19 | if root == None: 20 | return [] 21 | ans = [] 22 | import queue 23 | q = queue.Queue() 24 | q.put(root) 25 | while not q.empty(): 26 | tmp = [] 27 | for _ in range(q.qsize()): 28 | item = q.get() 29 | tmp.append(item.val) 30 | if item.left is not None: 31 | q.put(item.left) 32 | if item.right is not None: 33 | q.put(item.right) 34 | ans.insert(0, tmp) 35 | return ans 36 | -------------------------------------------------------------------------------- /leetcode-algorithms/108. Convert Sorted Array to Binary Search Tree/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Created by Bruce yuan on 18-2-7. 3 | 4 | 5 | # Definition for a binary tree node. 6 | class TreeNode: 7 | def __init__(self, x): 8 | self.val = x 9 | self.left = None 10 | self.right = None 11 | 12 | 13 | class Solution: 14 | def sortedArrayToBST(self, nums): 15 | """ 16 | :type nums: List[int] 17 | :rtype: TreeNode 18 | """ 19 | if len(nums) == 0: 20 | return None 21 | mid = len(nums) // 2 22 | root = TreeNode(nums[mid]) 23 | root.left = self.sortedArrayToBST(nums[0:mid]) 24 | root.right = self.sortedArrayToBST(nums[mid + 1:]) 25 | return root 26 | -------------------------------------------------------------------------------- /leetcode-algorithms/110. Balanced Binary Tree/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Created by Bruce yuan on 18-2-7. 3 | 4 | 5 | # Definition for a binary tree node. 6 | # class TreeNode: 7 | # def __init__(self, x): 8 | # self.val = x 9 | # self.left = None 10 | # self.right = None 11 | 12 | class Solution: 13 | def isBalanced(self, root): 14 | """ 15 | 这题需要注意的是,我们不可以只判断root.left和root.right高度之间的差距 16 | 因为子树之间也还有可能不平衡 17 | :type root: TreeNode 18 | :rtype: bool 19 | """ 20 | if root is None: 21 | return True 22 | return self.is_valid(root) != -1 23 | 24 | @classmethod 25 | def is_valid(cls, root): 26 | if root is None: 27 | return 0 28 | l = cls.is_valid(root.left) 29 | r = cls.is_valid(root.right) 30 | if abs(l - r) > 1 or l == -1 or r == -1: 31 | return -1 32 | return 1 + max(l, r) 33 | -------------------------------------------------------------------------------- /leetcode-algorithms/111. Minimum Depth of Binary Tree/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Created by Bruce yuan on 18-2-7. 3 | 4 | 5 | # Definition for a binary tree node. 6 | # class TreeNode: 7 | # def __init__(self, x): 8 | # self.val = x 9 | # self.left = None 10 | # self.right = None 11 | 12 | class Solution: 13 | def minDepth(self, root): 14 | """ 15 | :type root: TreeNode 16 | :rtype: int 17 | """ 18 | # BFS 19 | if root is None: 20 | return 0 21 | import queue 22 | q = queue.Queue() 23 | q.put(root) 24 | depth = 0 25 | while not q.empty(): 26 | depth += 1 27 | for _ in range(q.qsize()): 28 | item = q.get() 29 | if item.left is not None: 30 | q.put(item.left) 31 | if item.right is not None: 32 | q.put(item.right) 33 | if item.left is None and item.right is None: 34 | return depth 35 | return depth 36 | 37 | @staticmethod 38 | def dfs(root): 39 | """ 40 | 用可以用非递归的dfs来做吗?暂时没想到 41 | :param root: 42 | :return: 43 | """ 44 | if root is None: 45 | return 0 46 | node = [root] 47 | pass 48 | 49 | def recurrent(self, root): 50 | """ 51 | 这个超级好理解。 52 | :param root: 53 | :return: 54 | """ 55 | if root is None: 56 | return 0 57 | l = self.recurrent(root.left) 58 | r = self.recurrent(root.right) 59 | return l + r + 1 if l == 0 or r == 0 else min(l, r) + 1 60 | -------------------------------------------------------------------------------- /leetcode-algorithms/112. Path Sum/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Created by Bruce yuan on 18-2-7. 3 | 4 | 5 | # Definition for a binary tree node. 6 | # class TreeNode: 7 | # def __init__(self, x): 8 | # self.val = x 9 | # self.left = None 10 | # self.right = None 11 | 12 | class Solution: 13 | def hasPathSum(self, root, sum): 14 | """ 15 | 这种情况看起来只能用DFS 16 | :type root: TreeNode 17 | :type sum: int 18 | :rtype: bool 19 | """ 20 | if root is None: 21 | return False 22 | if root.left is None and root.right is None and root.val == sum: 23 | return True 24 | return self.hasPathSum(root.left, sum - root.val) or self.hasPathSum(root.right, sum - root.val) 25 | 26 | @staticmethod 27 | def dfs(root, sum_): 28 | if root is None: 29 | return False 30 | nodes = [root] 31 | while len(nodes) != 0: 32 | curr = nodes.pop() 33 | if curr.left is None and curr.right is None: 34 | if curr.val == sum_: 35 | return True 36 | if curr.left is not None: 37 | curr.left.val = curr.val + curr.left.val 38 | nodes.append(curr.left) 39 | if curr.right is not None: 40 | curr.right.val = curr.val + curr.right.val 41 | nodes.append(curr.right) 42 | return False 43 | -------------------------------------------------------------------------------- /leetcode-algorithms/118. Pascal's Triangle/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Created by Bruce yuan on 18-2-8. 3 | 4 | 5 | class Solution: 6 | def generate(self, numRows): 7 | """ 8 | :type numRows: int 9 | :rtype: List[List[int]] 10 | """ 11 | if numRows == 0: 12 | return [] 13 | ans = [[1]] 14 | for i in range(1, numRows): 15 | ans.append([1]) 16 | for j in range(1, i): 17 | ans[i].append(ans[i - 1][j - 1] + ans[i - 1][j]) 18 | ans[i].append(1) 19 | return ans 20 | 21 | @staticmethod 22 | def method_two(num): 23 | """ 24 | 用移位的方式,比如: 25 | 1 1 0 26 | + 0 1 1 27 | --------- 28 | 1 2 1 29 | :param num: 30 | :return: 31 | """ 32 | if num == 0: 33 | return [] 34 | ans = [[1]] 35 | for i in range(num - 1): 36 | ans.append([sum(item) for item in zip(ans[i] + [0], [0] + ans[i])]) 37 | for i in ans: 38 | print(i) 39 | 40 | 41 | if __name__ == '__main__': 42 | s = Solution() 43 | s.method_two(5) 44 | print(s.generate(6)) 45 | -------------------------------------------------------------------------------- /leetcode-algorithms/119. Pascal's Triangle II/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Created by Bruce yuan on 18-2-8. 3 | 4 | 5 | # 这题大坑,input是index,而不是逻辑位置 6 | class Solution: 7 | def getRow(self, rowIndex): 8 | """ 9 | :type rowIndex: int 10 | :rtype: List[int] 11 | """ 12 | if rowIndex == 0: 13 | return [1] 14 | ans = [0] * (rowIndex + 1) 15 | ans[0] = 1 16 | for i in range(1, rowIndex + 1): 17 | for j in range(i, 0, -1): 18 | ans[j] = ans[j] + ans[j -1] 19 | return ans 20 | 21 | 22 | if __name__ == '__main__': 23 | s = Solution() 24 | print(s.getRow(5)) 25 | -------------------------------------------------------------------------------- /leetcode-algorithms/121. Best Time to Buy and Sell Stock/maxProfit.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} prices 3 | * @return {number} 4 | */ 5 | var maxProfit = function(prices) { 6 | var profit = 0, 7 | current = prices[0]; 8 | 9 | for(var i = 1; i < prices.length; i++){ 10 | if(prices[i] < current){ 11 | current = prices[i]; 12 | } else { 13 | profit = Math.max(prices[i] - current, profit); 14 | } 15 | } 16 | return profit; 17 | }; 18 | 19 | console.log(maxProfit([7, 1, 5, 3, 6, 4])); -------------------------------------------------------------------------------- /leetcode-algorithms/122. Best Time to Buy and Sell Stock II/maxProfit.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} prices 3 | * @return {number} 4 | */ 5 | var maxProfit = function(prices) { 6 | var sum = 0; 7 | for(var i = 1; i < prices.length; i++){ 8 | var temp = prices[i] - prices[i - 1]; 9 | if(temp > 0){ 10 | sum += temp; 11 | } 12 | //sum += Math.max(prices[i] - prices[i -1], 0); 13 | } 14 | return sum; 15 | }; 16 | 17 | // method two 18 | //总是先求出当前一小段时间内的最大利润,然后再把每一段最大利润相加 19 | var maxProfit2 = function(prices) { 20 | var min = prices[0], 21 | max = 0, 22 | sum = 0, 23 | temp; 24 | 25 | for(var i = 1; i < prices.length; i++){ 26 | temp = prices[i] - min; 27 | if(temp > max){ 28 | max = temp; 29 | if(i === prices.length - 1){ 30 | sum += max; 31 | } 32 | }else{ 33 | sum += max; 34 | min = prices[i]; 35 | max = 0; 36 | } 37 | }//end for 38 | 39 | return sum; 40 | }; 41 | console.log(maxProfit([])); -------------------------------------------------------------------------------- /leetcode-algorithms/123. Best Time to Buy and Sell Stock III/maxProfit.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} prices 3 | * @return {number} 4 | */ 5 | var maxProfit = function(prices){ 6 | if(prices.length === 0)return 0; 7 | var leftProfit = []; 8 | var leftProfitMax = 0, 9 | leftMin = prices[0]; 10 | var temp; 11 | for(var i = 0; i < prices.length; i++){ 12 | if(prices[i] < leftMin) leftMin = prices[i]; 13 | temp = prices[i] - leftMin; 14 | if(temp > leftProfitMax)leftProfitMax = temp; 15 | leftProfit[i] = leftProfitMax; 16 | } 17 | 18 | var maxProfits = 0, 19 | rightProfitMax = 0, 20 | rightMax = prices[prices.length - 1], 21 | currentProfit; 22 | for(var i = prices.length - 1; i >= 0; i--){ 23 | if(prices[i] > rightMax) rightMax = prices[i]; 24 | temp = rightMax - prices[i]; 25 | if(temp > rightProfitMax)rightProfitMax = temp; 26 | currentProfit = rightProfitMax + (i > 0 ?leftProfit[i]:0); 27 | if(currentProfit > maxProfits)maxProfits = currentProfit; 28 | } 29 | 30 | return maxProfits; 31 | }; 32 | 33 | console.log(maxProfit([1,2,3,2,7,2,9])); 34 | -------------------------------------------------------------------------------- /leetcode-algorithms/125. Valid Palindrome/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Created by Bruce yuan on 18-2-9. 3 | 4 | 5 | class Solution: 6 | def isPalindrome(self, s): 7 | """ 8 | :type s: str 9 | :rtype: bool 10 | """ 11 | head, tail = 0, len(s) - 1 12 | while head < tail: 13 | h_tmp, t_tmp = s[head].lower(), s[tail].lower() 14 | if not (h_tmp.isalpha() or h_tmp.isdecimal()): 15 | head += 1 16 | elif not (t_tmp.isalpha() or t_tmp.isdecimal()): 17 | tail -= 1 18 | else: 19 | if h_tmp != t_tmp: 20 | return False 21 | head += 1 22 | tail -= 1 23 | return True 24 | 25 | 26 | if __name__ == '__main__': 27 | s = Solution() 28 | print(s.isPalindrome('ab')) 29 | 30 | -------------------------------------------------------------------------------- /leetcode-algorithms/136. Single Number/singleNumber.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums 3 | * @return {number} 4 | */ 5 | var singleNumber = function(nums) { 6 | var a = 0; 7 | // for(var i = 0; i < nums.length; i++){ 8 | // a = a ^ nums[i]; 9 | // } 10 | // return a; 11 | nums.forEach(function(item, index, array){ 12 | a ^= array[index];//这样写竟然比 a^=item又速度上的提升 13 | }); 14 | return a; 15 | }; -------------------------------------------------------------------------------- /leetcode-algorithms/137. Single Number II/singleNumber2.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums 3 | * @return {number} 4 | */ 5 | var singleNumber = function(nums) { 6 | var a = 0, 7 | b = 0; 8 | 9 | for (var i = 0; i < nums.length; i++){ 10 | // a = (a ^ nums[i]) & ~b; 11 | // b = (b ^ nums[i]) & ~a; 12 | 13 | b = a & (b ^ nums[i]); 14 | a = b | (a ^ nums[i]); 15 | } 16 | 17 | return a; 18 | }; -------------------------------------------------------------------------------- /leetcode-algorithms/141. Linked List Cycle/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Created by Bruce yuan on 18-2-11. 3 | """ 4 | 这题我竟然一下就想到了用双指针,太奇怪了吧。 5 | 是因为以前做题还有点印想? 6 | 7 | append: 这题当然也可以用dict来做,保存前面出现过的 8 | """ 9 | 10 | # Definition for singly-linked list. 11 | # class ListNode(object): 12 | # def __init__(self, x): 13 | # self.val = x 14 | # self.next = None 15 | 16 | 17 | class Solution(object): 18 | def hasCycle(self, head): 19 | """ 20 | :type head: ListNode 21 | :rtype: bool 22 | """ 23 | if head is None: 24 | return False 25 | slow, fast = head, head 26 | while fast.next and fast.next.next: 27 | slow = slow.next 28 | fast = fast.next.next 29 | if slow.val == fast.val: 30 | return True 31 | return False 32 | -------------------------------------------------------------------------------- /leetcode-algorithms/155. Min Stack/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Created by Bruce yuan on 18-2-12. 3 | 4 | 5 | import numpy 6 | 7 | 8 | class MinStack(object): 9 | def __init__(self): 10 | """ 11 | initialize your data structure here. 12 | """ 13 | self.element = [] 14 | self.min = numpy.Inf 15 | self.count = 0 16 | 17 | def push(self, x): 18 | """ 19 | :type x: int 20 | :rtype: void 21 | """ 22 | self.element.append(x) 23 | self.count += 1 24 | if x < self.min: 25 | self.min = x 26 | 27 | def pop(self): 28 | """ 29 | :rtype: void 30 | """ 31 | x = self.element.pop() 32 | self.count -= 1 33 | if x == self.min: 34 | if self.count == 0: 35 | self.min = numpy.Inf 36 | else: 37 | self.min = min(self.element) 38 | 39 | def top(self): 40 | """ 41 | :rtype: int 42 | """ 43 | return self.element[-1] 44 | 45 | def getMin(self): 46 | """ 47 | :rtype: int 48 | """ 49 | return self.min 50 | 51 | 52 | # Your MinStack object will be instantiated and called as such: 53 | # obj = MinStack() 54 | # obj.push(x) 55 | # obj.pop() 56 | # param_3 = obj.top() 57 | # param_4 = obj.getMin() 58 | -------------------------------------------------------------------------------- /leetcode-algorithms/160. Intersection of Two Linked Lists/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Created by Bruce yuan on 18-2-12. 3 | 4 | 5 | # Definition for singly-linked list. 6 | # class ListNode(object): 7 | # def __init__(self, x): 8 | # self.val = x 9 | # self.next = None 10 | 11 | 12 | class Solution(object): 13 | def getIntersectionNode(self, headA, headB): 14 | """ 15 | :type head1, head1: ListNode 16 | :rtype: ListNode 17 | """ 18 | len_a, len_b = self.get_length(headA), self.get_length(headB) 19 | while len_a < len_b: 20 | len_b -= 1 21 | headB = headB.next 22 | while len_a > len_b: 23 | len_a -= 1 24 | headA = headA.next 25 | while headA != headB: 26 | headA = headA.next 27 | headB = headB.next 28 | return headA 29 | 30 | @staticmethod 31 | def get_length(head): 32 | length = 0 33 | while head: 34 | length += 1 35 | head = head.next 36 | return length 37 | -------------------------------------------------------------------------------- /leetcode-algorithms/167. Two Sum II - Input array is sorted/twoSum.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} numbers 3 | * @param {number} target 4 | * @return {number[]} 5 | */ 6 | var twoSum = function(numbers, target) { 7 | let i = 0, j = numbers.length - 1; 8 | let res = numbers[i] + numbers[j]; 9 | while(res !== target) { 10 | if (res < target) { 11 | i++; 12 | } else { 13 | j--; 14 | } 15 | res = numbers[i] + numbers[j]; 16 | } 17 | return [i+ 1, j + 1]; 18 | }; 19 | -------------------------------------------------------------------------------- /leetcode-algorithms/168. Excel Sheet Column Title/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Created by Bruce yuan on 18-2-13. 3 | 4 | 5 | class Solution: 6 | def convertToTitle(self, n): 7 | """ 8 | :type n: int 9 | :rtype: str 10 | """ 11 | ans = '' 12 | while n > 0: 13 | ans = chr((n-1) % 26 + 65) + ans 14 | n = (n - 1) // 26 15 | return ans 16 | 17 | 18 | if __name__ == '__main__': 19 | s = Solution() 20 | print(s.convertToTitle(1)) 21 | -------------------------------------------------------------------------------- /leetcode-algorithms/169. Majority Element/majorityElement.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums 3 | * @return {number} 4 | */ 5 | 6 | var majorityElement = function(nums) { 7 | let hash = []; 8 | for(let i = 0, len = nums.length; i < len; i++) { 9 | if (!hash[nums[i]]) hash[nums[i]] = 1; 10 | else hash[nums[i]]++; 11 | 12 | if (hash[nums[i]] > len / 2) 13 | return nums[i]; 14 | } 15 | }; 16 | 17 | // method two 18 | var majorityElement2 = function(nums) { 19 | nums.sort((a,b)=>a-b); 20 | let count = 1; 21 | let n = Math.floor(nums.length / 2); 22 | for (let i = 0; i < nums.length - 1; i++) { 23 | if (nums[i] === nums[i + 1]) { 24 | count += 1; 25 | } else { 26 | if (count > n) { 27 | return nums[i]; 28 | } 29 | count = 1; 30 | } 31 | } 32 | if (count > n) { 33 | return nums[nums.length - 1]; 34 | } 35 | }; -------------------------------------------------------------------------------- /leetcode-algorithms/171. Excel Sheet Column Number/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Created by Bruce yuan on 18-2-15. 3 | 4 | 5 | class Solution: 6 | def titleToNumber(self, s): 7 | """ 8 | :type s: str 9 | :rtype: int 10 | """ 11 | sum_ = 0 12 | for index, item in enumerate(s[::-1]): 13 | sum_ += (ord(item) - 65 + 1) * (26 ** index) 14 | return sum_ 15 | -------------------------------------------------------------------------------- /leetcode-algorithms/172. Factorial Trailing Zeroes/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Created by Bruce yuan on 18-2-16. 3 | """ 4 | 这个为啥我看不懂啊,这东西好难啊,感觉智商下降的好厉害啊, 5 | 先提交一下,以后慢慢想 6 | """ 7 | 8 | 9 | class Solution: 10 | def trailingZeroes(self, n): 11 | """ 12 | :type n: int 13 | :rtype: int 14 | """ 15 | r = 0 16 | while n > 0: 17 | n //= 5 18 | r += n 19 | return r 20 | -------------------------------------------------------------------------------- /leetcode-algorithms/189. Rotate Array/rotate.js: -------------------------------------------------------------------------------- 1 | // /** 2 | // * @param {number[]} nums 3 | // * @param {number} k 4 | // * @return {void} Do not return anything, modify nums in-place instead. 5 | // */ 6 | 7 | var rotate = function(nums, k) { 8 | k %= nums.length;//这一波操作不能省啊,感觉是因为我英文理解有问题 9 | var temp = nums.splice(0, nums.length - k); 10 | Array.prototype.push.apply(nums, temp); 11 | console.log(nums); 12 | }; 13 | rotate([1,2],1); 14 | 15 | // method two 16 | var rotate2 = function(nums, k) { 17 | k %= nums.length; 18 | reverse(nums, 0, nums.length - k - 1); 19 | reverse(nums, nums.length - k, nums.length - 1); 20 | reverse(nums, 0, nums.length - 1); 21 | return nums; 22 | }; 23 | 24 | function reverse(nums, start, end){ 25 | while(start < end){ 26 | [nums[start], nums[end]] = [nums[end], nums[start]]; 27 | start++; 28 | end--; 29 | } 30 | } 31 | 32 | // method three 33 | /* 34 | 直接看别人的思路 35 | For each element at position i, we need to move them to (i + k) % n, use a buffer to save the element that has been replaced, and move the replaced element to its right place. 36 | We will start from an element, and mark that, if we come back to the starting point, means we need to start over from the element next of the current starting point. 37 | Work terminates when we have move exactly n times. 38 | 39 | Example: 40 | Input: 41 | [1,2,3,4,5,6] 42 | 2 43 | 44 | Process: 45 | 46 | startIdx = 0 47 | 1, [1,2,3,4,5,6] -> 3, [1,2,1,4,5,6] -> 5, [1,2,1,4,3,6] -> [5,2,1,4,3,6] 48 | 49 | startIdx = 1 50 | 2, [5,2,1,4,3,6] -> 4, [5,2,1,2,3,6] -> 6, [5,2,1,2,3,4] -> [5,6,1,2,3,4] 51 | */ 52 | var rotate3 = function(nums, k){ 53 | var startIndex = 0, 54 | len = nums.length, 55 | move = 0, 56 | idx = 0, 57 | elem; 58 | 59 | [elem, startIndex] = [nums[idx], idx]; 60 | while(move < len){ 61 | idx = (idx + k) % len; 62 | [elem, nums[idx]] = [nums[idx], elem]; 63 | move++; 64 | 65 | if(idx === startIndex){ 66 | idx++; 67 | if(idx >= len)break; 68 | [elem, startIndex] = [nums[idx], idx]; 69 | } 70 | } 71 | console.log(nums); 72 | }; -------------------------------------------------------------------------------- /leetcode-algorithms/204. Count Primes/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Created by Bruce yuan on 18-2-14. 3 | 4 | 5 | import math 6 | 7 | 8 | class Solution: 9 | def countPrimes(self, n): 10 | """ 11 | :type n: int 12 | :rtype: int 13 | """ 14 | if n <= 2: 15 | return 0 16 | res = [True] * n 17 | res[0] = res[1] = False 18 | for i in range(2, n): 19 | if res[i] is True: 20 | for j in range(i, (n - 1) // i + 1): 21 | res[i * j] = False 22 | return sum(res) 23 | 24 | def method(self, n): 25 | """ 26 | 这个方法竟然超时了,心累啊 27 | :param n: 28 | :return: 29 | """ 30 | if n < 2: 31 | return 0 32 | count = 0 33 | for i in range(2, n): 34 | count += self.is_prime(i) 35 | return count 36 | 37 | @staticmethod 38 | def is_prime(n): 39 | for j in range(2, int(math.sqrt(n)) + 1): 40 | if n % j == 0: 41 | return 0 42 | return 1 43 | 44 | if __name__ == '__main__': 45 | s = Solution() 46 | print(s.countPrimes(5)) 47 | -------------------------------------------------------------------------------- /leetcode-algorithms/205. Isomorphic Strings/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Created by Bruce yuan on 18-2-13. 3 | 4 | 5 | class Solution: 6 | def isIsomorphic(self, s, t): 7 | """ 8 | :type s: str 9 | :type t: str 10 | :rtype: bool 11 | """ 12 | if len(s) != len(t): 13 | return False 14 | s_arr = [0] * len(s) 15 | t_arr = [0] * len(s) 16 | s_dict = {} 17 | t_dict = {} 18 | for i in range(len(s)): 19 | if s[i] in s_dict: 20 | s_arr[i] = s_dict[s[i]] 21 | else: 22 | s_arr[i] = i 23 | s_dict[s[i]] = i 24 | if t[i] in t_dict: 25 | t_arr[i] = t_dict[t[i]] 26 | else: 27 | t_arr[i] = i 28 | t_dict[t[i]] = i 29 | return s_arr == t_arr 30 | -------------------------------------------------------------------------------- /leetcode-algorithms/206. Reverse Linked List/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Created by Bruce yuan on 18-2-1. 3 | 4 | 5 | # Definition for singly-linked list. 6 | # class ListNode: 7 | # def __init__(self, x): 8 | # self.val = x 9 | # self.next = None 10 | 11 | class Solution: 12 | def reverseList(self, head): 13 | """ 14 | :type head: ListNode 15 | :rtype: ListNode 16 | """ 17 | pre = None 18 | while head: 19 | next_ = head.next 20 | head.next = pre 21 | pre = head 22 | head = next_ 23 | return pre 24 | 25 | # 这里定义一个递归版本的 26 | # 需要两个节点,好像好好想想还是能理解的 27 | def reverse_list(self, node, prev=None): 28 | if not node: 29 | return prev 30 | n = node.next 31 | node.next = prev 32 | return self.reverse_list(n, node) 33 | -------------------------------------------------------------------------------- /leetcode-algorithms/215. Kth Largest Element in an Array/kthLagestElement.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums 3 | * @param {number} k 4 | * @return {number} 5 | */ 6 | 7 | //注意这里找的是第K大得元素, 8 | //运用得是快速排序中position得思想。所以就相当于从大到 9 | //小排序。 10 | var findKthLargest = function(nums, k) { 11 | var left = 0, 12 | right = nums.length - 1; 13 | 14 | while(true){ 15 | var a = position(nums, left, right); 16 | 17 | if(k > a + 1){ 18 | left = a + 1; 19 | } else if (k < a + 1){ 20 | right = a - 1; 21 | } else{ 22 | return nums[k - 1]; 23 | } 24 | } 25 | }; 26 | 27 | function position(nums, left, right){ 28 | var key = nums[left]; 29 | 30 | while(left < right){ 31 | while(nums[right] <= key && left < right){ 32 | right--; 33 | } 34 | nums[left] = nums[right]; 35 | while(nums[left] >= key && left < right){ 36 | left++; 37 | } 38 | nums[right] = nums[left]; 39 | } 40 | 41 | nums[left] = key; 42 | return left; 43 | } -------------------------------------------------------------------------------- /leetcode-algorithms/217. Contains Duplicate/containDumplicated.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums 3 | * @return {boolean} 4 | */ 5 | var containsDuplicate = function(nums) { 6 | let hash = {}; 7 | 8 | for (let i = 0; i < nums.length; i++) { 9 | if (hash[nums[i]] === true) { 10 | return true; 11 | } 12 | hash[nums[i]] = true; 13 | } 14 | return false; 15 | }; -------------------------------------------------------------------------------- /leetcode-algorithms/219. Contains Duplicate II/containsNearbyDumplicate.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums 3 | * @param {number} k 4 | * @return {boolean} 5 | */ 6 | 7 | var containsNearbyDuplicate = function(nums, k) { 8 | let pos = []; 9 | for (let i = 0; i < nums.length; i++) { 10 | if (pos[nums[i]] === undefined) { 11 | pos[nums[i]] = i; 12 | } else { 13 | if (i - pos[nums[i]] <= k) { 14 | return true; 15 | } 16 | pos[nums[i]] = i; 17 | } 18 | } 19 | return false; 20 | }; 21 | -------------------------------------------------------------------------------- /leetcode-algorithms/220. Contains Duplicate III/containsNearbyAlmostDuplicate.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums 3 | * @param {number} k 4 | * @param {number} t 5 | * @return {boolean} 6 | */ 7 | var containsNearbyAlmostDuplicate = function(nums, k, t) { 8 | for (let i = 0; i < nums.length; i++) { 9 | for (let j = i + 1; j <= Math.min(nums.length - 1, i + k); j++) { 10 | if (Math.abs(nums[i] - nums[j]) <= t) return true; 11 | } 12 | } 13 | return false; 14 | }; -------------------------------------------------------------------------------- /leetcode-algorithms/221. Maximal Square/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # created by BBruceyuan on 18-5-2 3 | 4 | 5 | import numpy as np 6 | 7 | 8 | class Solution: 9 | def maximalSquare(self, matrix): 10 | """ 11 | :type matrix: List[List[str]] 12 | :rtype: int 13 | """ 14 | if len(matrix) == 0: 15 | return 0 16 | matrix = np.array(matrix) 17 | row, column = len(matrix), len(matrix[0]) 18 | dp = np.zeros((row + 1, column + 1)) 19 | print(dp) 20 | max_sqlen = 0 21 | for i in range(1, row + 1): 22 | for j in range(1, column + 1): 23 | if matrix[i - 1][j - 1] == '1': 24 | dp[i][j] = min(dp[i][j - 1], dp[i - 1][j], dp[i - 1][j - 1]) + 1 25 | max_sqlen = max(max_sqlen, dp[i][j]) 26 | return int(max_sqlen ** 2) 27 | 28 | 29 | def main(): 30 | s = Solution() 31 | a = s.maximalSquare([["1","0","1","0","0"], 32 | ["1","0","1","1","1"], 33 | ["1","1","1","1","1"], 34 | ["1","0","0","1","0"]]) 35 | print(a) 36 | 37 | 38 | if __name__ == '__main__': 39 | main() 40 | -------------------------------------------------------------------------------- /leetcode-algorithms/226. Invert Binary Tree/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Created by BBruceyuan on 18-2-25. 3 | 4 | 5 | # Definition for a binary tree node. 6 | # class TreeNode: 7 | # def __init__(self, x): 8 | # self.val = x 9 | # self.left = None 10 | # self.right = None 11 | 12 | class Solution: 13 | def invertTree(self, root): 14 | """ 15 | 这个问题其实还是很好解决的 16 | :type root: TreeNode 17 | :rtype: TreeNode 18 | """ 19 | if root is None: 20 | return None 21 | left = self.invertTree(root.left) 22 | right = self.invertTree(root.right) 23 | root.right = left 24 | root.left = right 25 | return root 26 | -------------------------------------------------------------------------------- /leetcode-algorithms/234. Palindrome Linked List/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Created by Bruce yuan on 18-1-31. 3 | 4 | 5 | # Definition for singly-linked list. 6 | class ListNode: 7 | def __init__(self, x): 8 | self.val = x 9 | self.next = None 10 | 11 | 12 | class Solution: 13 | def isPalindrome(self, head): 14 | """ 15 | 这题我想不到怎么 O(1) space 16 | :type head: ListNode 17 | :rtype: bool 18 | """ 19 | current = head 20 | count = 0 21 | while current: 22 | count += 1 23 | current = current.next 24 | if count == 1: 25 | return True 26 | # 把她重新用作中位数 27 | count = count // 2 if count % 2 == 0 else count // 2 + 1 28 | current = head 29 | for _ in range(count): 30 | current = current.next 31 | # 123 4 321 0 0 32 | current = self.reverse_list(current) 33 | # print(current.val) 34 | # print(head.val) 35 | while current and head: 36 | # print('test test') 37 | if current.val != head.val: 38 | return False 39 | current = current.next 40 | head = head.next 41 | # print(current) 42 | # print(head) 43 | return True 44 | 45 | @staticmethod 46 | def reverse_list(head): 47 | pre = None 48 | # 这就是头插法,竟然都忘记了。简直了 49 | while head: 50 | next_ = head.next 51 | head.next = pre 52 | pre = head 53 | head = next_ 54 | return pre 55 | 56 | 57 | def main(): 58 | head = ListNode(0) 59 | next_ = ListNode(0) 60 | head.next = next_ 61 | solution = Solution() 62 | result = solution.isPalindrome(head) 63 | print(result) 64 | 65 | 66 | if __name__ == '__main__': 67 | main() 68 | -------------------------------------------------------------------------------- /leetcode-algorithms/268. Missing Number/missingNumber.js: -------------------------------------------------------------------------------- 1 | //方法一 2 | //感觉这种题,自己做完之后应该去看看其他大佬得想法。 3 | function missingNumber(nums){ 4 | var sum = nums.reduce(function(pre, cur, index, array){ 5 | return pre + cur; 6 | }), 7 | sumArray = ((nums.length * (nums.length + 1)) / 2); 8 | return sumArray - sum; 9 | 10 | } 11 | console.log(missingNumber([0,1,3,4])); 12 | 13 | //方法二。 14 | //同样是用了线性时间,不过这里等于遍历了两遍,所以时间会有一些慢。 15 | var missingNumber2 = function(nums) { 16 | var hash = []; 17 | nums.forEach(function(item) { 18 | hash[item] = true; 19 | }); 20 | 21 | for (var i = 0; ; i++) 22 | if (!hash[i]) 23 | return i; 24 | }; 25 | 26 | //方法三,这是一个好想法啊, 27 | //利用xor操作能够两个清零,所以再来一个0-n的数组就可以直接放回这样一个数字。直接用python写方便一点 28 | /* 29 | def missingNumber(self, nums): 30 | return reduce(lambda x, y: x xor y, nums + list(range(len(n) + 1)); 31 | */ 32 | 33 | function missingNumber3(nums){ 34 | var result = nums.length;//这一步一定要有,因为必须有0-nums,length之间全部的数字。 35 | for(var i = 0; i < nums.length; i++){ 36 | result = i ^ nums[i]; 37 | } 38 | return result; 39 | } 40 | -------------------------------------------------------------------------------- /leetcode-algorithms/278. First Bad Version/firstBadVersion.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Definition for isBadVersion() 3 | * 4 | * @param {integer} version number 5 | * @return {boolean} whether the version is bad 6 | * isBadVersion = function(version) { 7 | * ... 8 | * }; 9 | */ 10 | 11 | /** 12 | * @param {function} isBadVersion() 13 | * @return {function} 14 | */ 15 | var solution = function(isBadVersion) { 16 | /** 17 | * @param {integer} n Total versions 18 | * @return {integer} The first bad version 19 | */ 20 | return function(n) { 21 | let start = 0, 22 | mid, 23 | end = n; 24 | 25 | while (start <= end) { 26 | mid = Math.floor((start + end) / 2); 27 | if (isBadVersion(mid) === true) { 28 | end = mid - 1; 29 | } else { 30 | start = mid + 1; 31 | } 32 | } 33 | return start; 34 | }; 35 | }; -------------------------------------------------------------------------------- /leetcode-algorithms/283. Move Zeroes/moveZeroes.js: -------------------------------------------------------------------------------- 1 | //这个比较简单,就是比较慢,不知道为啥 2 | var moveZeroes = function(nums) { 3 | var count = nums.length; 4 | 5 | for(var i = 0; i < count; i++){ 6 | if(nums[i] === 0 && i < count){ 7 | nums.push(nums.splice(i, 1)[0]); 8 | i = i - 1; 9 | count--; 10 | } 11 | 12 | } 13 | }; 14 | 15 | var a = [0,0,1]; 16 | moveZeroes(a); 17 | console.log(a); 18 | -------------------------------------------------------------------------------- /leetcode-algorithms/287. Find the Duplicate Number/findDuplicateNumber.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums 3 | * @return {number} 4 | */ 5 | 6 | //直接利用这个思路,其实和two number sum 这道题的思路是一样的 7 | //不过这里是利用了空间来换取时间上的性能,时间复杂度超了, 8 | //变成了O(n),所以应该算是错的,不过觉得这样的思路好就直接这样写了 9 | var findDuplicate = function(nums) { 10 | var hash = {}; 11 | for(var i = 0; i < nums.length; i++){ 12 | if(!hash[nums[i]]){ 13 | hash[nums[i]] = true; 14 | } else{ 15 | return nums[i]; 16 | } 17 | } 18 | }; 19 | 20 | 21 | // method two 22 | //循环法,肯定会有一个重复的圈。,只要找到最先重复的那个圈圈。 23 | var findDuplicate2 = function(nums) { 24 | //好慢啊,这个比上面那个慢了太多了。 25 | var slow = 0, 26 | fast = 0; 27 | 28 | do{ 29 | slow = nums[slow]; 30 | fast = nums[nums[fast]]; 31 | }while(slow !== fast); 32 | slow = 0; 33 | while(true){ 34 | slow = nums[slow]; 35 | fast = nums[fast]; 36 | if(slow === fast){ 37 | return slow; 38 | } 39 | } 40 | }; -------------------------------------------------------------------------------- /leetcode-algorithms/349. Intersection of Two Arrays/intersection.js: -------------------------------------------------------------------------------- 1 | /** 2 | - * @param {number[]} nums1 3 | - * @param {number[]} nums2 4 | - * @return {number[]} 5 | */ 6 | var intersection = function(nums1, nums2) { 7 | let hash = {}; 8 | let result = []; 9 | for (let i = 0; i < nums1.length; i++) { 10 | if(!hash[nums1[i]]) { 11 | hash[nums1[i]] = true; 12 | } 13 | } 14 | 15 | for (let i = 0; i < nums2.length; i++) { 16 | if (hash[nums2[i]]) { 17 | result.push(nums2[i]); 18 | hash[nums2[i]] = false; 19 | } 20 | } 21 | 22 | return result; 23 | } 24 | console.log(intersection([1,2,3], [1,4,6])); 25 | 26 | // es6不过时间感觉要更久 27 | /* 28 | var intersection = function(nums1, nums2) { 29 | let a = new Set(nums1); 30 | let b = new Set(nums2); 31 | let result = new Set([...a].filter(x => b.has(x))); 32 | return Array.from(result); 33 | }; 34 | 35 | */ -------------------------------------------------------------------------------- /leetcode-algorithms/350. Intersection of Two Arrays II/intersect.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums1 3 | * @param {number[]} nums2 4 | * @return {number[]} 5 | */ 6 | 7 | 8 | /** 9 | * What if the given array is already sorted? How would you optimize your algorithm? 10 | * What if nums1's size is small compared to nums2's size? Which algorithm is better? 11 | * What if elements of nums2 are stored on disk, and the memory is limited 12 | * such that you cannot load all elements into the memory at once? 13 | */ 14 | var intersect = function(nums1, nums2) { 15 | let hash = {}; 16 | let result = []; 17 | 18 | nums1.forEach((item, index)=>{ 19 | if (!hash[item]) { 20 | hash[item] = 1; 21 | } else { 22 | hash[item] += 1; 23 | } 24 | }); 25 | 26 | nums2.forEach((item, index) => { 27 | if (hash[item]) { 28 | result.push(item); 29 | hash[item] -= 1; 30 | } 31 | }); 32 | 33 | return result; 34 | }; -------------------------------------------------------------------------------- /leetcode-algorithms/367. Valid Perfect Square/isPerfectSquare.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number} num 3 | * @return {boolean} 4 | */ 5 | var isPerfectSquare = function(num) { 6 | if (num === 1) return true; 7 | let left = 1, right = Math.floor(num / 2); 8 | while(left <= right) { 9 | let mid = Math.floor((left + right) / 2); 10 | if (mid === num / mid) { 11 | return true; 12 | } else if (mid > num / mid) { 13 | right = mid - 1; 14 | } else { 15 | left = mid + 1; 16 | } 17 | } 18 | 19 | return false; 20 | }; -------------------------------------------------------------------------------- /leetcode-algorithms/374. Guess Number Higher or Lower/guessNumber.py: -------------------------------------------------------------------------------- 1 | # The guess API is already defined for you. 2 | # @param num, your guess 3 | # @return -1 if my number is lower, 1 if my number is higher, otherwise return 0 4 | # def guess(num): 5 | 6 | class Solution(object): 7 | def guessNumber(self, n): 8 | """ 9 | :type n: int 10 | :rtype: int 11 | """ 12 | low = 1 13 | high = n 14 | while low <= high: 15 | mid = (low + high) / 2 16 | if guess(mid) == 0: 17 | return mid 18 | elif guess(mid) == 1: 19 | low = mid + 1 20 | elif guess(mid) == -1: 21 | high = mid - 1 22 | -------------------------------------------------------------------------------- /leetcode-algorithms/414. Third Maximum Number/thirdMax.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums 3 | * @return {number} 4 | */ 5 | 6 | 7 | // 尽管现在知道了直接遍历要比forEach快好多 8 | // 结果保存在result数组中,从大到小排列 9 | var thirdMax = function(nums) { 10 | let result = []; 11 | 12 | nums.forEach(function(item) { 13 | let len = result.length; 14 | 15 | if (len === 0) { 16 | result.push(item); 17 | } else if (len === 1) { 18 | if (result[0] > item) { 19 | result.push(item); 20 | } else if (item > result[0]) { 21 | result.unshift(item); 22 | } 23 | } else if (len === 2) { 24 | if (item < result[1]) { 25 | result.push(item); 26 | } else if (item > result[0]) { 27 | result.unshift(item); 28 | } else if (item < result[0] && item > result[1]){ 29 | result.splice(1, 0, item); 30 | } 31 | } else if (len === 3) { 32 | if (item > result[2] && item != result[1] && item != result[0]) { 33 | result.pop() 34 | if(item > result[0]) { 35 | result.unshift(item); 36 | } else if (item < result[1]) { 37 | result.push(item); 38 | } else if (item < result[0] && item > result[1]) { 39 | result.splice(1, 0, item); 40 | } 41 | } 42 | } 43 | }); 44 | 45 | return result.length === 3 ? result[2] : result[0]; 46 | }; 47 | 48 | 49 | console.log(thirdMax([1,2,2,5,3,5])); 50 | 51 | console.log(thirdMax([3, 2, 1])); 52 | console.log(thirdMax([1, 2])); -------------------------------------------------------------------------------- /leetcode-algorithms/415. Add Strings/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Created by Bruce yuan on 18-1-27. 3 | 4 | 5 | class Solution: 6 | def addStrings(self, num1, num2): 7 | """ 8 | :type num1: str 9 | :type num2: str 10 | :rtype: str 11 | """ 12 | carry = 0 13 | result = [] 14 | num1, num2 = list(num1), list(num2) 15 | while len(num2) > 0 or len(num1) > 0: 16 | n1 = int(num1.pop()) if len(num1) > 0 else 0 17 | n2 = int(num2.pop()) if len(num2) > 0 else 0 18 | tmp = n1 + n2 + carry 19 | result.append(tmp % 10) 20 | carry = tmp // 10 21 | if carry == 0: 22 | result.append(carry) 23 | return ''.join(str(x) for x in result[::-1]) 24 | -------------------------------------------------------------------------------- /leetcode-algorithms/442. Find All Duplicates in an Array/findDuplicates.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums 3 | * @return {number[]} 4 | */ 5 | 6 | // 思路和原来那个找disappeared number是一样的 7 | var findDuplicates = function(nums) { 8 | let result = []; 9 | for(let i = 0; i < nums.length; ++i){ 10 | let current = Math.abs(nums[i]) - 1; 11 | 12 | if(nums[current] < 0){ 13 | result.push(current + 1); 14 | } 15 | nums[current] = -nums[current]; 16 | } 17 | return result; 18 | }; 19 | 20 | -------------------------------------------------------------------------------- /leetcode-algorithms/448. Find All Numbers Disappeared in an Array/findDisappearedNumbers.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums 3 | * @return {number[]} 4 | */ 5 | 6 | // 思路就是把每一个数放在它本来应该出现的位置上; 7 | // 然后再遍历这个数组就可以找到少了哪几个数字 8 | var findDisappearedNumbers = function(nums) { 9 | let result = []; 10 | nums.forEach(function(item, index, array){ 11 | while(nums[item - 1] != item){ 12 | let temp = nums[item - 1]; 13 | nums[item - 1] = item; 14 | item = temp; 15 | } 16 | }); 17 | 18 | nums.forEach(function(item, index, array){ 19 | if(array[index] != index + 1){ 20 | result.push(index + 1); 21 | } 22 | }); 23 | return result; 24 | }; 25 | 26 | findDisappearedNumbers([4,3,2,7,8,2,3,1]); 27 | -------------------------------------------------------------------------------- /leetcode-algorithms/453. Minimum Moves to Equal Array Elements/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Created by Bruce yuan on 18-1-28. 3 | 4 | 5 | # TODO 6 | # 这个还没有很好的理解?(差不多理解了? 7 | # 好好理解!!! 8 | class Solution(object): 9 | def minMoves(self, nums): 10 | """ 11 | :type nums: List[int] 12 | :rtype: int 13 | """ 14 | return sum(nums) - len(nums)*min(nums) 15 | 16 | @staticmethod 17 | def min_move_two(nums): 18 | """ 19 | 和上面那个其实是一样的,不过需要真的理解为什么要这么做 20 | :param nums: 21 | :return: 22 | """ 23 | nums.sort() 24 | c = 0 25 | for i in range(len(nums) - 1, -1, -1): 26 | if nums[i] == nums[0]: 27 | break 28 | c += nums[i] - nums[0] 29 | return c 30 | -------------------------------------------------------------------------------- /leetcode-algorithms/462. Minimum Moves to Equal Array Elements II/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Created by Bruce yuan on 18-1-28. 3 | 4 | 5 | class Solution: 6 | """ 7 | 这是计算,经过多少步能够使得数字相等 8 | 那意思很明显,我们只要找到中间值, 9 | 大于它的就减去它,小于它的就被减,然后加起来就好了 10 | """ 11 | def minMoves2(self, nums): 12 | """ 13 | :type nums: List[int] 14 | :rtype: int 15 | """ 16 | nums = sorted(nums) 17 | i, j = 0, len(nums) - 1 18 | count = 0 19 | while i < j: 20 | count += nums[j] - nums[i] 21 | i += 1 22 | j -= 1 23 | return count 24 | 25 | 26 | if __name__ == '__main__': 27 | s = Solution() 28 | ans = s.minMoves2([1, 1, 1, 2, 2, 2]) 29 | print(ans) 30 | -------------------------------------------------------------------------------- /leetcode-algorithms/485. Max Consecutive Ones/consectiveOnes.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {number[]} nums 3 | * @return {number} 4 | */ 5 | 6 | // 这题就是典型的动态规划问题,每次要求最优 7 | 8 | var findMaxConsecutiveOnes = function(nums) { 9 | let max = 0, 10 | count = 0; 11 | nums.forEach(function(item, index, array){ 12 | if(item === 1){ 13 | count++; 14 | } else{ 15 | if(count > max){ 16 | max = count; 17 | count = 0; 18 | } else { 19 | count = 0; 20 | } 21 | } 22 | }); 23 | if(count > max){ 24 | max = count; 25 | } else { 26 | count = 0; 27 | } 28 | return max; 29 | }; 30 | 31 | console.log(findMaxConsecutiveOnes([0,0])); -------------------------------------------------------------------------------- /leetcode-algorithms/609. Find Duplicate File in System/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Created by Bruce yuan on 18-1-25. 3 | """ 4 | Input: 5 | ["root/a 1.txt(abcd) 2.txt(efgh)", "root/c 3.txt(abcd)", "root/c/d 4.txt(efgh)", "root 4.txt(efgh)"] 6 | Output: 7 | [["root/a/2.txt","root/c/d/4.txt","root/4.txt"],["root/a/1.txt","root/c/3.txt"]] 8 | """ 9 | import re 10 | 11 | 12 | class Solution: 13 | def findDuplicate(self, paths): 14 | """ 15 | :type paths: List[str] 16 | :rtype: List[List[str]] 17 | """ 18 | result = {} 19 | for item in paths: 20 | result = self.__extract_content(item, result) 21 | 22 | return [x for x in result.values() if len(x) > 1] 23 | 24 | def __extract_content(self, string, result): 25 | """ 26 | 把括号里面的内容匹配出来 27 | :param string: 28 | :param result: 一个字典,用来存储匹配结果 29 | :return: 30 | """ 31 | # group(1) 就是文件名,group(2)就是文件内容 32 | file_content = re.compile(r'(.*)\((.*)\)') 33 | dir_and_files = string.split(' ') 34 | directory, files = dir_and_files[0], dir_and_files[1:] 35 | # print(directory) 36 | for item in files: 37 | matched = file_content.match(item) 38 | if matched is not None: 39 | content = matched.group(2) 40 | file_name = matched.group(1) 41 | if result.get(content, None): 42 | result.get(content).append(directory + '/' + file_name) 43 | else: 44 | result[content] = [directory + '/' + file_name] 45 | # print(result) 46 | return result 47 | 48 | 49 | def main(): 50 | solution = Solution() 51 | result = solution.findDuplicate(["root/a 1.txt(abcd) 2.txt(efgh)","root/c 3.txt(abcd)","root/c/d 4.txt(efgh)","root 4.txt(efgh)"]) 52 | result2 = solution.findDuplicate(["root/a 1.txt(abcd) 2.txt(efsfgh)","root/c 3.txt(abdfcd)","root/c/d 4.txt(efggdfh)"]) 53 | print(result2) 54 | print(result) 55 | 56 | 57 | if __name__ == '__main__': 58 | main() 59 | -------------------------------------------------------------------------------- /leetcode-algorithms/637. Average of Levels in Binary Tree/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Created by Bruce yuan on 18-2-7. 3 | 4 | 5 | # Definition for a binary tree node. 6 | # class TreeNode: 7 | # def __init__(self, x): 8 | # self.val = x 9 | # self.left = None 10 | # self.right = None 11 | 12 | class Solution: 13 | def averageOfLevels(self, root): 14 | """ 15 | :type root: TreeNode 16 | :rtype: List[float] 17 | """ 18 | if root is None: 19 | return [0] 20 | import queue 21 | import functools 22 | q = queue.Queue() 23 | q.put(root) 24 | ans = [] 25 | while not q.empty(): 26 | tmp = [] 27 | for _ in range(q.qsize()): 28 | node = q.get() 29 | tmp.append(node.val) 30 | if node.left is not None: 31 | q.put(node.left) 32 | if node.right is not None: 33 | q.put(node.right) 34 | average = functools.reduce(lambda x, y: x + y, tmp) / len(tmp) 35 | ans.append(average) 36 | return ans 37 | -------------------------------------------------------------------------------- /leetcode-algorithms/725. Split Linked List in Parts/solution.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # Created by Bruce yuan on 18-1-25. 3 | 4 | # Definition for singly-linked list. 5 | # class ListNode(object): 6 | # def __init__(self, x): 7 | # self.val = x 8 | # self.next = None 9 | 10 | 11 | class Solution(object): 12 | def splitListToParts(self, root, k): 13 | """ 14 | :type root: ListNode 15 | :type k: int 16 | :rtype: List[ListNode] 17 | """ 18 | # reminder 余数 19 | min_width, reminder = self.__count_and_div(root, k) 20 | result = [] 21 | for i in range(k): 22 | if i < reminder: 23 | tmp, root = self.__build_list(root, min_width + 1) 24 | result.append(tmp) 25 | else: 26 | tmp, root = self.__build_list(root, min_width) 27 | result.append(tmp) 28 | return result 29 | 30 | @staticmethod 31 | def __count_and_div(root, k): 32 | count = 0 33 | while root: 34 | count += 1 35 | root = root.next 36 | return divmod(count, k) 37 | 38 | @staticmethod 39 | def __build_list(curr, length): 40 | """ 41 | 构建链表,这里是根据原来的链表构建的,而不是新建一个链表 42 | :param curr: 当前节点 43 | :param length: 构建链表的长度 44 | :return: 返回头结点(这里是指第一个节点 45 | """ 46 | if length == 0 or curr is None: 47 | return None, None 48 | tmp = curr 49 | for i in range(length - 1): 50 | curr = curr.next 51 | next_head = curr.next 52 | curr.next = None 53 | return tmp, next_head 54 | -------------------------------------------------------------------------------- /scripts/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bbruceyuan/algorithms-and-oj/f71118e8e05d4bcdcfb2dfc42187c73961b8b926/scripts/1.png -------------------------------------------------------------------------------- /scripts/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bbruceyuan/algorithms-and-oj/f71118e8e05d4bcdcfb2dfc42187c73961b8b926/scripts/2.png -------------------------------------------------------------------------------- /scripts/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bbruceyuan/algorithms-and-oj/f71118e8e05d4bcdcfb2dfc42187c73961b8b926/scripts/3.png -------------------------------------------------------------------------------- /scripts/readme.md: -------------------------------------------------------------------------------- 1 | ## 脚本使用方法 2 | 首先,需要安装`requests`这个库,如果没有安装,请使用下面这个命令 3 | ``` 4 | pip install requests 5 | ``` 6 | 然后,打开该文件,在`Config`类中配置自己的路径,有两个地方需要配置。 7 | `local_path` 和 `github_leetcode_url`,如下图: 8 | ![](1.png) 9 | 10 | 11 | 12 | 13 | - local_path`是你本地保存github仓库中的路径,如图: 14 | 15 | ![](2.png) 16 | 17 | 18 | 19 | 20 | 21 | 22 | - `github_leetcode_url`是你github上解题结果的路径,如图: 23 | ![](3.png) 24 | 25 | 26 | 然后只需要在对应目录下面使用下面命令运行该脚本就好了 27 | ``` 28 | python readme.py 29 | ``` 30 | 31 | 首次创建就运行上面的脚本。 32 | 33 | 更新就把对应题目的解答放到相对于文件夹下面,然后运行该脚本。 34 | --------------------------------------------------------------------------------