├── DynamicProgram ├── 121-best-time-to-buy-and-sell-stock.md ├── 122-best-time-to-buy-and-sell-stock-ii.md ├── 139-word-break.md ├── 221-maximal-square.md ├── 300-longest-increasing-subsequence.md ├── 53-maximum-subarray.md ├── lint109-triangle.md ├── lint110-minimum-path-sum.md ├── lint111-climbing-stairs.md ├── lint114-unique-paths.md ├── lint115-unique-paths-ii.md ├── lint116-jump-game.md ├── lint117-jump-game-ii.md ├── lint125-backpack-ii.md ├── lint397-longest-increasing-continuous-subsequence.md ├── lint42-maximum-subarray-ii.md ├── lint77-longest-common-subsequence.md ├── lint92-backpack.md └── readme.md ├── README.md ├── String ├── 05-Longest-Palindromic-Substring.md ├── 125-valid-pal.md ├── 172-Remove-Element.md ├── 28-implement-strstr.md ├── 38-countAndSay.md ├── 44-Wildcard-Matching.md ├── 49-group-anagrams.md ├── 58-length-of-last-word.md ├── lint08-rotate-string.md ├── lint138-Subarray-Sum.md ├── lint158-anagrams.md ├── lint171-group-anagrams.md ├── lint192-Wildcard-Matching.md ├── lint200-Longest-Palindromic-Substring.md ├── lint212-Space-Replacement.md ├── lint39-Recover-Rotated-Sorted-Array.md ├── lint415-valid-pal.md ├── lint50-Product-Array-Exclude-itself.md ├── lint53-reverseWord.md ├── lint55-compare-string.md ├── lint79-LCS.md └── readme.md ├── binaryTree ├── 102-binary-tree-level-order-traversal.md ├── 103-binary-tree-zigzag-level-order-traversal.md ├── 104-maximum-depth-of-binary-tree.md ├── 105-construct-binary-tree-from-preorder-and-inorder-traversal.md ├── 110-balanced-binary-tree.md ├── 144-binary-tree-preorder-traversal.md ├── 145-binary-tree-postorder-traversal.md ├── 94-binary-tree-inorder-traversal.md ├── lint245-subtree.md ├── lint88-lowest-common-ancestor.md └── readme.md ├── bitMani ├── 2017-3-7-lint82single-number.md ├── 2017-3-9-lint181-flip-bits.md ├── 96-Unique-Binary-Search-Trees.md └── readme.md ├── code_interview ├── 360_2.md ├── baidu_123.md ├── didi.cpp ├── disifanshi_23.md ├── huanjushidai_1.md ├── hypereal_1.md ├── kuaishou_1.md ├── nvidia_1.md ├── nvidia_23456.md ├── pinduoduo_2.md ├── pinduoduo_3.md ├── readme.md ├── tencent.md ├── ulsee_2.md └── wangyi.cpp ├── data-structure ├── 239-sliding-window-maximum.md ├── lint12-min-stack.md ├── lint40-implement-queue-by-two-stacks.md └── reame.md ├── exhaustiveSearch ├── 131-palindrome-partitioning.md ├── 31-next-permutation.md ├── 39-combination-sum.md ├── 40-combination-sum-ii.md ├── 46-permutations.md ├── 47-permutations-ii.md ├── 51-previous-permutation.md ├── 60-permutation-sequence.md ├── 77-combinations.md ├── 78-subsets.md ├── 79-word-search.md ├── 90-subsets-ii.md ├── 95-unique-binary-search-trees-ii.md ├── lint197-Permutatio- Index.md ├── lint198-permutation-index-ii.md └── readme.md ├── graph ├── lint127-topological-sorting.md ├── lint127-word-ladder.md ├── lint176-route-between-two-nodes-in-graph.md └── readme.md ├── improve_sort_algorithm ├── imporve_mergeSort.md ├── improve_fast_sort.md └── readme.md ├── integer-arr ├── 01-Two-Sum.md ├── 16-3Sum-Closest.md ├── 215-kth-largest-element-in-an-array.md ├── 26-Remove-Duplicates-from-Sorted-Array.md ├── 35-3sum.md ├── 41-first-missing-positive.md ├── 80-Remove-Duplicates-from-Sorted-Array-II.md ├── 80-remove-duplicates-from-sorted-array-ii.md ├── 88-Merge-Sorted-Array.md ├── images │ └── 1.jpg ├── lint189-First-Missing-Positive.md ├── lint31-Partition-Array.md ├── lint373-Partition-Array-by-Odd-and-Even.md ├── lint64-merge-two-sorted-arrays.md ├── lint80-median.md ├── offer03_find_element_in_2D_array ├── offer04_replace_blank ├── offer08_rotate_arr_min_num └── readme.md ├── linked_list ├── 002-add-two-numbers.md ├── 138-copy-list-with-random-pointer.md ├── 141-linked-list-cycle.md ├── 142-linked-list-cycle-ii.md ├── 143-reorder-list.md ├── 146-lru-cache.md ├── 147-insertion-sort-list.md ├── 148-sort-list.md ├── 203-remove-linked-list-elements.md ├── 206-reverse-linked-list.md ├── 21-merge-two-sorted-lists.md ├── 23-merge-k-sorted-lists.md ├── 234-palindrome-linked-list.md ├── 24-swap-nodes-in-pairs.md ├── 61-rotate-list.md ├── 82-remove-duplicates-from-sorted-list-ii.md ├── 83-remove-duplicates-from-sorted-list.md ├── 86-partition-list.md ├── 92-reverse-linked-list-ii.md ├── gfg-remove-duplicates-from-an-unsorted-linked-list.md ├── gfg-sum-of-two-linked-lists.md ├── lint174-remove-nth-node-from-end-of-list.md └── readme ├── search ├── 153-find-minimum-in-rotated-sorted-array.md ├── 154-find-minimum-in-rotated-sorted-array-ii.md ├── 2017-3-7-lint183-wood-cut.md ├── 240-search-a-2d-matrix2.md ├── 33-search-in-rotated-sorted-array.md ├── 34-search-for-range.md ├── 74-search-a-2d-matrix.md ├── 81-search-in-rotated-sorted-array-ii.md ├── lint-60-search-insert-position.md └── readme.md └── sword_to_offer ├── 15_find_back_k_elem.md ├── 16_reverse_linkedlist.md ├── 17_combine_linkedList.md ├── 1_two_dim_arr_search.cpp ├── 1_two_dim_arr_search2.cpp ├── 37_same_node.md ├── 39_Tree_depth.md ├── 39_balance_binaryTree.md ├── 3_rebuild_tree.cpp ├── 45_the_last_nubmer.md └── readme.md /DynamicProgram/121-best-time-to-buy-and-sell-stock.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 121-best-time-to-buy-and-sell-stock 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # problem 9 | [121-best-time-to-buy-and-sell-stock](https://leetcode.com/problems/best-time-to-buy-and-sell-stock/#/description) 10 | 11 | # solution 12 | 13 | ## solution 1.DP 14 | 15 | time out 16 | ```cpp 17 | int maxProfit(vector& prices) { 18 | if (prices.empty()) 19 | return 0; 20 | vector result(prices.size(),0); 21 | for (int i = 1; i < prices.size(); i++) 22 | for (int j = i-1; j>=0;j--) 23 | if (prices[j] < prices[i]) 24 | result[i] = max(result[i],result[j] + prices[i] - prices[j]); 25 | return *max_element(result.begin(),result.end()); 26 | } 27 | ``` 28 | 29 | ## solution 2. Dp 30 | 使用坐标记录最小值; 31 | ```cpp 32 | int maxProfit(vector& prices) { 33 | if (prices.empty()) 34 | return 0; 35 | vector result(prices.size(),0); 36 | int min_elem = 0; 37 | for (int i = 1; i < prices.size(); i++) 38 | { 39 | if (prices[i] > prices[min_elem]) 40 | result[i] = result[min_elem] + prices[i] - prices[min_elem]; 41 | else 42 | min_elem = i; 43 | } 44 | return *max_element(result.begin(),result.end()); 45 | } 46 | 47 | ``` -------------------------------------------------------------------------------- /DynamicProgram/122-best-time-to-buy-and-sell-stock-ii.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 122-best-time-to-buy-and-sell-stock-ii 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # problem 9 | [122-best-time-to-buy-and-sell-stock-ii](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/#/description) 10 | 11 | # solution 12 | ```cpp 13 | int maxProfit(vector& prices) { 14 | //找到一段自增段; 15 | if (prices.empty()||prices.size() == 1) 16 | return 0; 17 | int maxElem = -1, minElem = -1, result = 0; 18 | while ((maxElem < (int)prices.size()) && (minElem < (int)prices.size()) ) 19 | { 20 | //先找局部最小值; 21 | int i = maxElem + 1; 22 | for (; i < prices.size() - 1; i++) 23 | if (prices[i+1] > prices[i]) 24 | break; 25 | minElem = i; 26 | int j = i + 1; 27 | for (; j < prices.size() -1; j++) 28 | if (prices[j+1] < prices[j]) 29 | break; 30 | maxElem = j; 31 | if (maxElem > minElem && maxElem < (int)prices.size()) 32 | result += prices[maxElem] - prices[minElem]; 33 | } 34 | return result; 35 | } 36 | ``` -------------------------------------------------------------------------------- /DynamicProgram/139-word-break.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 139-word-break 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # problem 9 | [139-word-break](https://leetcode.com/problems/word-break/#/description) 10 | 11 | # solution 12 | 13 | ```cpp 14 | bool wordBreak(string s, vector& wordDict) { 15 | int len = s.size(); 16 | //自底向上; 17 | vector status(false, len);// 表明从开头到当前的位置的字符串能够被字典表示 18 | for (int i = 1; i <= len; i++)//以长度进行遍历 19 | { 20 | string str = s.substr(0, i); 21 | if (find(wordDict.begin(), wordDict.end(), str) != wordDict.end()) 22 | status[i-1] = true; 23 | else // 如果没有就从中间拆分;遍历每个可索引字符串的后缀 24 | for (int j = i -2; j >= 0; j--) 25 | if (status[j] == true && find(wordDict.begin(), wordDict.end(), s.substr(j + 1,i -j -1))!=wordDict.end() ) 26 | { 27 | status[i-1] = true; 28 | break; 29 | } 30 | } 31 | return status[len - 1]; 32 | } 33 | ``` -------------------------------------------------------------------------------- /DynamicProgram/300-longest-increasing-subsequence.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 300-longest-increasing-subsequence 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # problem 9 | [300-longest-increasing-subsequence](https://leetcode.com/problems/longest-increasing-subsequence/#/description) 10 | # solution 11 | ## solution 1 DP 12 | 转移矩阵先把问题转换成以这个点结束的最长递增子序列,在最后的时候遍历所有的节点,找到最长的长度 13 | ```cpp 14 | int lengthOfLIS(vector& nums) { 15 | if (nums.empty() || nums.size() == 0) 16 | return 0; 17 | vector lens( nums.size(),0 );//标记的是以这个位置结束的自增序列的长度; 18 | lens[0] = 1; 19 | for (int i = 1; i < nums.size(); i++) 20 | { 21 | //从0开始找比它大的位置; 22 | int bigger = 0; 23 | for (int j = 0 ; j < i; j ++) 24 | if (nums[i] > nums[j] && lens[j] > bigger) 25 | bigger = lens[j]; 26 | lens[i] = bigger + 1;//这里设置的比较巧妙,当i是递增序列中的第一个元素的时候,依然是成立的 27 | } 28 | //找到lens数组中的最大值; 29 | int maxLen = 0; 30 | for (int i = 0; i < lens.size(); i++) 31 | if (maxLen < lens[i]) 32 | maxLen = lens[i]; 33 | return maxLen; 34 | } 35 | ``` 36 | ## solution2 lower bound 37 | 38 | [longest_increasing_subsequence](https://algorithm.yuanbin.me/zh-hans/dynamic_programming/longest_increasing_subsequence.html) 39 | 40 | ```cpp 41 | int lengthOfLIS(vector& nums) { 42 | if (nums.empty()) return 0; 43 | 44 | vector lis; 45 | for (int i = 0; i < nums.size(); ++i) { 46 | vector::iterator it = lower_bound(lis.begin(), lis.end(), nums[i]); 47 | if (it == lis.end()) { 48 | lis.push_back(nums[i]); 49 | } else { 50 | *it = nums[i]; 51 | } 52 | } 53 | 54 | return lis.size(); 55 | } 56 | ``` 57 | 58 | # reference 59 | 60 | [c++的新特性](http://blog.csdn.net/wangshubo1989/article/details/50575008) -------------------------------------------------------------------------------- /DynamicProgram/53-maximum-subarray.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 53-maximum-subarray 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # problem 9 | [53-maximum-subarray](https://leetcode.com/problems/maximum-subarray/#/description) 10 | 11 | # solution 12 | ## 使用辅助空间+贪心法 13 | 14 | 15 | ```cpp 16 | int maxSubArray(vector& nums) { 17 | //转移方程为,以当前节点结尾的最大的串,看前面的最大串的结果,如果为负数就算了。然后这个过程中的最大值就是全局的最大值 18 | if (nums.empty()) 19 | return 0; 20 | vector result(nums.size(), 0);//其实可以拷贝一份; 21 | result[0] = nums[0]; 22 | for (int i = 1; i < nums.size(); i++) 23 | { 24 | if (result[i-1] > 0) 25 | result[i] = result[i-1]; 26 | result[i] += nums[i]; 27 | } 28 | return *max_element(result.begin(),result.end()); 29 | } 30 | ``` 31 | 32 | ### 代码分析 33 | 这里使用了辅助空间,空间复杂度为0(n); 34 | 35 | ## 贪心算法 不用辅助空间 36 | 37 | ```cpp 38 | int maxSubArray(vector& nums) { 39 | //转移方程为,以当前节点结尾的最大的串,看前面的最大串的结果,如果为负数就算了。 40 | if (nums.empty()) 41 | return 0; 42 | int sum = nums[0]; 43 | int maxSum = nums[0]; 44 | for (int i = 1; i < nums.size(); i++) 45 | { 46 | sum=nums[i] += max(0, sum); 47 | maxSum = max(sum, maxSum); 48 | } 49 | return maxSum; 50 | } 51 | ``` 52 | 53 | ## 动态规划 54 | 只要一出现最小最大的字眼,就适合用动态规划。这里的思路是当前节点的最大和为当前节点的前面所有和减去当前节点之前的最小和。 55 | ```cpp 56 | int maxSubArray(vector& nums) { 57 | //转移方程为,以当前节点结尾的最大的串,看前面的最大串的结果,如果为负数就算了。 58 | if (nums.empty()) 59 | return 0; 60 | int sum = nums[0]; 61 | int maxSum = nums[0]; 62 | int minSum = 0; 63 | for (int i = 1; i < nums.size(); i++) 64 | { 65 | minSum = min(sum,minSum); 66 | sum += nums[i]; 67 | maxSum = max(maxSum,sum - minSum); 68 | } 69 | return maxSum; 70 | } 71 | ``` -------------------------------------------------------------------------------- /DynamicProgram/lint109-triangle.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: lint109-triangle 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # problem 9 | [lint109-triangle](http://www.lintcode.com/en/problem/triangle/) 10 | 11 | # solution 12 | ## 解法1,自上而下递归法 13 | ``` 14 | int minimumTotal(vector > &triangle) { 15 | // write your code here 16 | if (triangle.empty()) 17 | return 0; 18 | return dfs(triangle, 0, 0); 19 | } 20 | int dfs(vector > &triangle, int i, int j) 21 | { 22 | if (i == triangle.size() - 1)//最后一行; 23 | return triangle[i][j]; 24 | int left = dfs(triangle, i + 1, j); 25 | int right = dfs(triangle, i + 1, j+1); 26 | return left < right ? triangle[i][j] + left : triangle[i][j] + right; 27 | } 28 | ``` 29 | ### analysis 30 | 31 | 因为递归导致重复计算,所以会导致超时,可以通过使用缓存数组来减少计算量,通过率53%,total runtime 1211ms 32 | 33 | ## 解法2, 递归+辅助空间 34 | ``` 35 | int minimumTotal(vector > &triangle) { 36 | // write your code here 37 | if (triangle.empty()) 38 | return 0; 39 | vector > nums; 40 | for (int i = 0; i < triangle.size() - 1; i++) 41 | nums.push_back(vector(triangle[i].size(), INT_MIN) ); 42 | return dfs(triangle, 0, 0, nums); 43 | } 44 | int dfs(vector > &triangle, int i, int j,vector > &nums) 45 | { 46 | if (i == triangle.size() - 1)//最后一行; 47 | return triangle[i][j]; 48 | if (nums[i][j] != INT_MIN) return nums[i][j]; 49 | int left = dfs(triangle, i + 1, j, nums); 50 | int right = dfs(triangle, i + 1, j+1, nums); 51 | nums[i][j] = left < right ? triangle[i][j] + left : triangle[i][j] + right; 52 | return nums[i][j]; 53 | } 54 | ``` 55 | ### analysis 56 | 会通过计算。 57 | 58 | ## 解法3.用循环就能通过 59 | ``` 60 | int minimumTotal(vector > &triangle) { 61 | // write your code here 62 | if (triangle.empty()) 63 | return 0; 64 | vector > nums; 65 | for (int i = 0; i < triangle.size() ; i++) 66 | nums.push_back(vector(triangle[i].size(), 0) ); 67 | for (int i = 0; i < nums[nums.size()-1].size(); i++) 68 | nums[nums.size()-1][i] = triangle[nums.size()-1][i]; 69 | //从下往上算一遍; 70 | for (int i = triangle.size()-2; i >= 0;i --) 71 | { 72 | for (int j = 0; j < nums[i].size(); j ++) 73 | nums[i][j] = nums[i+1][j] < nums[i+1][j+1]?nums[i+1][j]+triangle[i][j]:nums[i+1][j+1]+triangle[i][j]; 74 | } 75 | return nums[0][0]; 76 | } 77 | ``` 78 | 79 | ### analysis 80 | 但是依然是全部遍历后打结果,不太智能. 81 | 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /DynamicProgram/lint110-minimum-path-sum.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: lint110-minimum-path-sum 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # problem 9 | [lin110-minimum-path-sum](http://www.lintcode.com/en/problem/minimum-path-sum/) 10 | # solution 11 | 12 | ```cpp 13 | int minPathSum(vector > &grid) { 14 | // write your code here 15 | if (grid.empty() || grid[0].empty()) 16 | return 0; 17 | int m = grid.size(); 18 | int n = grid[0].size(); 19 | //下面开始进行遍历; 20 | vector minSums = vector(n, 0); 21 | //初始化第一行 22 | minSums[0] = grid[0][0]; 23 | for (int i = 1; i 0 && minSums[j] > minSums[j-1]) 29 | minSums[j] = minSums[j-1] + grid[i][j]; 30 | else 31 | minSums[j] += grid[i][j]; 32 | return minSums[n-1]; 33 | } 34 | 35 | ``` 36 | -------------------------------------------------------------------------------- /DynamicProgram/lint111-climbing-stairs.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: lint111-climbing-stairs 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # problem 9 | [lint111-climbing-stairs](http://www.lintcode.com/en/problem/climbing-stairs/) 10 | 11 | # solution 12 | ```cpp 13 | int climbStairs(int n) { 14 | // write your code here 15 | if (n < 2) 16 | return 1; 17 | vector result(n+1, 0); 18 | result[0] = 1; 19 | result[1] = 1; 20 | for (int i = 2; i <= n; i++) 21 | result[i] = result[i-2] + result[i-1]; 22 | return result[n]; 23 | } 24 | 25 | ``` -------------------------------------------------------------------------------- /DynamicProgram/lint114-unique-paths.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: lint114-unique-paths 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # problem 9 | [lint114-unique-paths](http://www.lintcode.com/en/problem/unique-paths/) 10 | 11 | # solution 12 | ```cpp 13 | int uniquePaths(int m, int n) { 14 | // wirte your code here 15 | if (m == 0 || n == 0 ) 16 | return 0; 17 | if (m ==1 || n==1) 18 | return 1; 19 | vector nums(n, 1); 20 | for (int i = 1; i < m; i++) 21 | for (int j = 1;j < n; j++) 22 | nums[j] += nums[j-1]; 23 | return nums[n-1]; 24 | } 25 | ``` 26 | 27 | -------------------------------------------------------------------------------- /DynamicProgram/lint115-unique-paths-ii.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: lint115-unique-paths-ii 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # problem 9 | [lint115-unique-paths-ii](http://www.lintcode.com/en/problem/unique-paths-ii/) 10 | 11 | # solution 12 | 13 | 注意初始化 14 | ```cpp 15 | int uniquePathsWithObstacles(vector > &obstacleGrid) { 16 | // write your code here 17 | if (obstacleGrid.empty() || obstacleGrid[0].empty()) 18 | return 0; 19 | int m = obstacleGrid.size(); 20 | int n = obstacleGrid[0].size(); 21 | vector nums(n, 0); 22 | nums[0] = 1 - obstacleGrid[0][0]; 23 | for (int i = 1; i < n; i++) 24 | if (obstacleGrid[0][i] == 1 ) 25 | nums[i] = 0; 26 | else 27 | nums[i] = nums[i-1]; 28 | //接下来判断 29 | for (int i = 1; i < m; i++) 30 | { 31 | if ( obstacleGrid[i][0] == 1) 32 | nums[0] = 0; 33 | for (int j = 1; j < n; j++) 34 | if (obstacleGrid[i][j] == 1) 35 | nums[j] = 0; 36 | else 37 | nums[j] += nums[j-1]; 38 | } 39 | return nums[n-1]; 40 | } 41 | 42 | ``` -------------------------------------------------------------------------------- /DynamicProgram/lint116-jump-game.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: lint116-jump-game 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # problem 9 | [lint116-jump-game](http://www.lintcode.com/en/problem/jump-game/) 10 | 11 | # solution 12 | ## solution1, 自顶向下 13 | ```cpp 14 | bool canJump(vector A) { 15 | // write you code here 16 | if (A[0] == 0 && A.size() > 1) 17 | return false; 18 | int maxPos = A[0]; 19 | for (int i = 1 ; i < A.size();) 20 | { 21 | int maxPosNow = -1; 22 | //统计这一段中的最大值; 23 | for (int j = i; j <= maxPos; j++) 24 | if (j + A[j] > maxPosNow) 25 | maxPosNow = j+A[j]; 26 | i = maxPos + 1; 27 | if (maxPosNow <= maxPos && maxPosNow < A.size()-1) 28 | return false; 29 | maxPos = maxPosNow; 30 | if (maxPos >= A.size() - 1) 31 | return true; 32 | 33 | } 34 | return true; 35 | } 36 | ``` 37 | 38 | ## solution2. 更规范的自顶向下 39 | 40 | ```cpp 41 | bool canJump(vector A) { 42 | // write you code here 43 | if (A.empty()) 44 | return true; 45 | vector status(false, A.size()); 46 | status[0] = true; 47 | int farest = A[0]; 48 | for (int i = 1; i < A.size(); i++) 49 | { 50 | if (i > farest) 51 | return false; 52 | if (A[i] + i > farest) 53 | farest = A[i] + i; 54 | } 55 | return true; 56 | } 57 | ``` 58 | 59 | ## solution3. 自底向上法 60 | 61 | ```cpp 62 | bool canJump(vector A) { 63 | // write you code here 64 | if (A.empty()) 65 | return true; 66 | int last = A.size() - 1; 67 | for (int i = A.size() -2 ; i>=0 ; i--) 68 | { 69 | if (i+A[i] >= last) 70 | { 71 | last = i; 72 | } 73 | } 74 | return last == 0; 75 | } 76 | ``` -------------------------------------------------------------------------------- /DynamicProgram/lint117-jump-game-ii.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: lint117-jump-game-ii 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # problem 9 | [lint117-jump-game-ii](http://www.lintcode.com/en/problem/jump-game-ii/) 10 | # solution 11 | ```cpp 12 | int jump(vector A) { 13 | // wirte your code here 14 | if (A.empty()) 15 | return 0; 16 | int lastPos = 1; 17 | int pos = 0; 18 | int k = 1; 19 | for (int i = 0; i < A.size();) 20 | { 21 | if (i+A[i] >= A.size()) 22 | break; 23 | //从当前的pos开始到下一个pos; 24 | // int j = i+1; 25 | // for (; j <= i+A[i]; j++) 26 | // if (j + A[j] > pos) 27 | // pos = j + A[j]; 28 | // //开始交换 29 | // if (pos <= i+A[i]) 30 | // return -1;//不能到最后 31 | i = i+A[i] + 1; 32 | k++; 33 | } 34 | return k; 35 | } 36 | ``` -------------------------------------------------------------------------------- /DynamicProgram/lint125-backpack-ii.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: lint125-backpack-ii 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # problem 9 | [lint125-backpack-ii](http://www.lintcode.com/en/problem/backpack-ii/) 10 | # solution 11 | 这是0-1背包问题的解法 12 | ``` 13 | int backPackII(int m, vector A, vector V) { 14 | // write your code here 15 | if (A.empty() || V.empty() || m<1) 16 | return 0; 17 | vector result(m+1, 0); 18 | int len = A.size(); 19 | for (int i = 0; i< len; i++) 20 | for (int j = m; j > 0; j--) 21 | if (A[i] <= j && result[j] < result[j - A[i]] + V[i]) 22 | result[j] = result[j - A[i]] + V[i]; 23 | return result[m]; 24 | } 25 | ``` -------------------------------------------------------------------------------- /DynamicProgram/lint397-longest-increasing-continuous-subsequence.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: lint397-longest-increasing-continuous-subsequence 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # problem 9 | [lint397-longest-increasing-continuous-subsequence](http://www.lintcode.com/en/problem/longest-increasing-continuous-subsequence/) 10 | # solution 11 | ```cpp 12 | int longestIncreasingContinuousSubsequence(vector& A) { 13 | if (A.empty()) 14 | return 0; 15 | // Write your code here 16 | int left = 1, maxleft = 1, right = 1, maxright = 1; 17 | for (int i = 1; i < A.size(); i++) 18 | { 19 | if (A[i] >= A[i-1]) 20 | { 21 | left+=1; 22 | right = 1; 23 | } 24 | else 25 | { 26 | left = 1; 27 | right += 1; 28 | } 29 | maxleft = max(maxleft, left); 30 | maxright = max(maxright, right); 31 | } 32 | return max(maxleft,maxright); 33 | } 34 | ``` -------------------------------------------------------------------------------- /DynamicProgram/lint42-maximum-subarray-ii.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: lint42-maximum-subarray-ii 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # problem 9 | [lint42-maximum-subarray-ii](http://www.lintcode.com/en/problem/maximum-subarray-ii/) 10 | 11 | # solution 12 | 13 | ## solution1 动态规划 14 | ```cpp 15 | int maxTwoSubArrays(vector nums) { 16 | // write your code here 17 | //先找前半部分的最大值,再找后半部分的最大值; 18 | if (nums.empty()) 19 | return 0; 20 | vector maxsumf(nums.size(), 0); 21 | vector maxsumb(nums.size(), 0); 22 | int sum = 0, minSum = 0, maxsum = INT_MIN;//maxSum算的是maxsumf的最大值; 23 | for (int i = 0; i < nums.size() ; i++) 24 | { 25 | minSum = min(minSum, sum); 26 | sum += nums[i]; 27 | maxsum = max(maxsum, sum - minSum); 28 | maxsumf[i] = maxsum; 29 | } 30 | sum = 0;minSum = 0;maxsum = INT_MIN; 31 | for (int i = nums.size()-1; i>=0;i--) 32 | { 33 | minSum = min(minSum, sum); 34 | sum+=nums[i]; 35 | maxsum = max(maxsum, sum - minSum); 36 | maxsumb[i] = maxsum; 37 | } 38 | //下面开始计算两者的和; 39 | maxsum = INT_MIN; 40 | for (int i = 0; i < nums.size() - 1; i++) 41 | { 42 | maxsum = max(maxsum, maxsumf[i] + maxsumb[i+1]); 43 | } 44 | return maxsum; 45 | } 46 | ``` 47 | 48 | ## solution2. 贪心法 49 | ```cpp 50 | 51 | ``` 52 | 53 | # reference 54 | [九章算法](https://www.jiuzhang.com/solution/maximum-subarray-ii/) -------------------------------------------------------------------------------- /DynamicProgram/lint77-longest-common-subsequence.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: lint77-longest-common-subsequence 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | # problem 8 | 9 | [lint77-longest-common-subsequence](http://www.lintcode.com/en/problem/longest-common-subsequence/) 10 | 11 | # solution 12 | 13 | ```cpp 14 | int longestCommonSubsequence(string A, string B) { 15 | // write your code here 16 | if (A.empty() || B.empty()) 17 | return 0; 18 | vector > nums(B.size()+1, vector(A.size() + 1,0)); 19 | for (int i = 0; i < B.size(); i++) 20 | for (int j = 0; j < A.size(); j++) 21 | if (A[j] == B[i]) 22 | nums[i+1][j+1] = nums[i][j] + 1; 23 | else 24 | nums[i+1][j+1] = max(nums[i+1][j], nums[i][j+1]);//使用std空间里的max函数 25 | return nums[B.size()][A.size()]; 26 | } 27 | ``` -------------------------------------------------------------------------------- /DynamicProgram/lint92-backpack.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: lint92-backpack 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # problem 9 | 10 | [lint92-backpack](http://www.lintcode.com/en/problem/backpack/) 11 | # solution 12 | ## solution1. 使用二维数组的背包模板来做 13 | 这里物品下表从0开始,而容量是从1开始算的。所以物品下标j表示的是前j个物品的总价值。而容量下标i表示的是容量为i时的价值。 14 | ``` 15 | int backPack(int m, vector A) { 16 | // write your code here 17 | if (A.empty() || m ==0) 18 | return 0; 19 | vector > result = vector >(m+1, vector(A.size()+1, 0) ); 20 | //然后进行双循环 21 | for (int i = 0; i < m+1; i++)//物品重量累加 22 | for (int j = 0; j < A.size(); j++)//物品数目累加 23 | if (A[j] <= i) 24 | result[i][j+1] = result[i][j] > result[i-A[j]][j] + A[j]?result[i][j]: result[i-A[j]][j] + A[j]; 25 | else 26 | result[i][j+1] = result[i][j]; 27 | return result[m][A.size()]; 28 | 29 | } 30 | ``` 31 | 32 | ### code analysis 33 | 代码会超内存 34 | 35 | ## solution2.一维数组 36 | ``` 37 | int backPack(int m, vector A) { 38 | // write your code here 39 | if (A.empty() || m ==0) 40 | return 0; 41 | vector result = vector(m+1, 0); 42 | //然后进行双循环 43 | for (int j = 0; j < A.size(); j++)//物品数目累加 44 | for (int i = m; i >0; i--)//物品重量累加 45 | if (A[j] <= i) 46 | result[i] = result[i-A[j]] + A[j] > result[i] ? result[i-A[j]] + A[j] :result[i] ; 47 | return result[m]; 48 | 49 | } 50 | ``` 51 | 52 | # reference 53 | 54 | [背包九讲](http://love-oriented.com/pack/pack2rc.pdf) 55 | -------------------------------------------------------------------------------- /DynamicProgram/readme.md: -------------------------------------------------------------------------------- 1 | 这些是动态规划的题目 2 | 3 | # 背包问题 4 | [背包九讲](http://love-oriented.com/pack/pack2rc.pdf) 5 | 6 | ## 0-1背包初始化 7 | 8 | 我们看到的求最优解的背包问题题目中,事实上有两种不太相同的问法。有的题目要求“恰好装满背包”时的最优解,有的题目则并没有要求必须把背包装满。一种区别这两种问法的实现方法是在初始化的时候有所不同。 9 | 如果是第一种问法,要求恰好装满背包,那么在初始化时除了 F[0] 为 0,其它F[1..V ] 均设为 −∞,这样就可以保证最终得到的 F[V ] 是一种恰好装满背包的最优解。 10 | 11 | 如果并没有要求必须把背包装满,而是只希望价格尽量大,初始化时应该将 F[0..V ]全部设为 0。 12 | 13 | ## 完全背包问题 14 | ``` 15 | F[0..V ] ←0 16 | for i ← 1 to N 17 | for v ← Ci to V 18 | F[v] ← max(F[v], F[v − Ci] + Wi) 19 | 20 | ``` -------------------------------------------------------------------------------- /String/05-Longest-Palindromic-Substring.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 05-Longest-Palindromic-Substring 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | [Leetcode/String/lint200-Longest-Palindromic-Substring.md](https://github.com/DragonFive/Leetcode/blob/master/String/lint200-Longest-Palindromic-Substring.md) 9 | 10 | # 解法 11 | ```cpp 12 | string longestPalindrome(string& s) 13 | { 14 | // Write your code here 15 | if (s.empty()) 16 | return s; 17 | string res; 18 | int len = s.length(); 19 | for (int i = 0; i < len; i++) 20 | { 21 | string temp; 22 | temp = findPalindrome(s, i, i); 23 | if (temp.size() > res.size())res = temp; 24 | temp = findPalindrome(s, i, i+1); 25 | if (temp.size() > res.size())res = temp; 26 | } 27 | return res; 28 | } 29 | string findPalindrome(string& s, int m, int n) 30 | { 31 | while (m >= 0 && n < s.size() && s[m] == s[n]) 32 | { 33 | m--; 34 | n++; 35 | } 36 | return s.substr(m + 1, n - m - 1); 37 | } 38 | ``` -------------------------------------------------------------------------------- /String/125-valid-pal.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 125-valid-pal 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # 题目来源 9 | 10 | [125 valid palindrome](https://leetcode.com/problems/valid-palindrome/) 11 | 12 | ## lintcode相似题目 13 | 14 | 15 | 16 | [415 valid palindrome](http://www.lintcode.com/en/problem/valid-palindrome/) 17 | 18 | # 解法 19 | 20 | ```cpp 21 | bool isPalindrome(string s) { 22 | int start = 0, end = s.length() - 1; 23 | while (end > start) 24 | { 25 | if (!isalnum(s[start]) ) 26 | { 27 | start++; 28 | continue; 29 | } 30 | if (!isalnum(s[end]) ) 31 | { 32 | end--; 33 | continue; 34 | } 35 | if( tolower(s[start]) != tolower(s[end]) ) 36 | return false; 37 | start++; 38 | end--; 39 | } 40 | return true; 41 | } 42 | ``` 43 | -------------------------------------------------------------------------------- /String/172-Remove-Element.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 172-Remove-Element 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # source 9 | [27 Remove Element](https://leetcode.com/problems/remove-element/) 10 | 11 | ## similiar problem 12 | 13 | [lintcode 172 Remove Element](http://www.lintcode.com/en/problem/remove-element/) 14 | 15 | # solution 16 | ## 使用STL容器 17 | 18 | 需要记住避免一些方法的坑 remove和erase都有各自的坑,remove其实并不会真的把数据删掉,erase删完之后的iterator也没有用了。 19 | 20 | 注意时间复杂度是O(n^2) 21 | ```cpp 22 | int removeElement(vector &A, int elem) { 23 | // write your code here 24 | A.erase(remove(A.begin(),A.end(),elem),A.end()); 25 | return A.size(); 26 | } 27 | ``` 28 | 29 | 或者 30 | ```cpp 31 | int removeElement(vector &A, int elem) { 32 | // write your code here 33 | vector::iterator it = A.begin(); 34 | for (; it != A.end();) 35 | if (*it == elem) 36 | it = A.erase(it); 37 | else 38 | it++; 39 | return A.size(); 40 | } 41 | ``` 42 | ## 两根指针法 43 | 44 | **覆盖法** 45 | ```cpp 46 | int removeElement(vector &A, int elem) { 47 | int n = A.size(); 48 | for (int i = 0; i < n; i++) 49 | if (A[i] == elem) 50 | { 51 | A[i] = A[n - 1]; 52 | i--; 53 | n--; 54 | } 55 | } 56 | ``` 57 | 58 | **不同移动法** 59 | ```cpp 60 | int removeElement(vector &A, int elem) { 61 | int next = 0; 62 | for (int i = 0; i < A.size(); i++) 63 | if (A[i] != elem) 64 | { 65 | A[start++] = A[i]; 66 | } 67 | return start; 68 | } 69 | ``` 70 | 71 | # reference 72 | [STL Vector remove()和erase()的使用](http://blog.csdn.net/yockie/article/details/7859330) 73 | 74 | 75 | [九章算法 remove element解题](http://www.jiuzhang.com/solutions/remove-element/) -------------------------------------------------------------------------------- /String/28-implement-strstr.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 28-implement-strstr 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # 问题描述 9 | 对于一个给定的 source 字符串和一个 target 字符串,你应该在 source 字符串中找出 target 字符串出现的第一个位置(从0开始)。如果不存在,则返回 -1。 10 | 11 | [Implement strStr() | LeetCode OJ](https://leetcode.com/problems/implement-strstr/) 12 | 13 | [字符串查找 lintcode](http://www.lintcode.com/zh-cn/problem/strstr/) 14 | 15 | # 说明 16 | 在面试中是否需要实现KMP算法? 17 | 18 | 不需要,当这种问题出现在面试中时,面试官很可能只是想要测试一下你的基础应用能力。当然你需要先跟面试官确认清楚要怎么实现这个题。 19 | 20 | # 实现 21 | 22 | ## 使用库函数 23 | 24 | ```cpp 25 | #include 26 | 27 | class Solution { 28 | public: 29 | int strStr(string haystack, string needle) { 30 | int where = haystack.find(needle); 31 | if(where!=haystack.npos) 32 | return where; 33 | else 34 | return -1; 35 | } 36 | }; 37 | ``` 38 | 39 | 40 | ## 暴力匹配法 41 | ```cpp 42 | #include 43 | 44 | class Solution { 45 | public: 46 | int strStr(string s, string t) 47 | { 48 | int i=0; 49 | for(;i chNums; 21 | vector charPr; 22 | int len = preN.length(); 23 | for (int i = 0; i < len; i++) 24 | { 25 | if (charPr.empty() || charPr[charPr.size() - 1] != preN[i]) 26 | { 27 | charPr.push_back(preN[i]); 28 | chNums.push_back(0); 29 | } 30 | chNums[chNums.size() - 1] ++; 31 | } 32 | string retStr; 33 | int lenNums = chNums.size(); 34 | for(int i = 0; i < lenNums; i++) 35 | { 36 | retStr+=chNums[i] + '0' - 0; 37 | retStr+=charPr[i]; 38 | } 39 | return retStr; 40 | } 41 | ``` -------------------------------------------------------------------------------- /String/44-Wildcard-Matching.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 44-Wildcard-Matching 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # source 9 | 10 | [leetcode 44 Wildcard-Matching](https://leetcode.com/problems/wildcard-matching/) 11 | 12 | 13 | ## similiar problem 14 | 15 | [lintcode Wildcard-Matching ](http://www.lintcode.com/en/problem/wildcard-matching/#) 16 | 17 | # solution 18 | 19 | ## my poor solution 20 | ```cpp 21 | bool isMatch(string m, string n) 22 | { 23 | // write your code here 24 | // 找* 起点 25 | char * begins = (char *)m.c_str(), *beginp = (char *)n.c_str(); 26 | while (*beginp != '*' && *beginp != '\0' && *begins != '\0') 27 | if (*beginp != *begins && *beginp != '?') 28 | return false; 29 | else 30 | { 31 | beginp++; begins++; 32 | } 33 | if (*beginp == '\0' && *begins == '\0') 34 | return true; 35 | if (*beginp == '\0' || *begins == '\0' && *beginp != '*') 36 | return false; 37 | while (*beginp == '*') 38 | beginp++; 39 | while (*beginp != '\0' && *begins != '\0') 40 | { 41 | //下面找到下一个*的位置 42 | char * endp = beginp; 43 | while (*endp != '*' && *endp != '\0') 44 | endp++; 45 | // 从beginp到endp 46 | //分情况讨论如果 *endp == '*'走下面 47 | if (*endp == '*') 48 | { 49 | char *finds = findSubStr(begins, beginp, endp); 50 | if (finds == NULL) 51 | return false; 52 | begins = finds + (endp - beginp); 53 | beginp = endp; 54 | while (*beginp == '*') 55 | beginp++; 56 | } 57 | else 58 | { 59 | //右对齐进行比较 60 | char * ends = begins; 61 | while (*ends != '\0') 62 | ends++; 63 | while ((*ends == *endp || *endp == '?') && ends >= begins && endp >= beginp) 64 | { 65 | ends--; 66 | endp--; 67 | } 68 | if (endp < beginp) 69 | return true; 70 | else 71 | return false; 72 | 73 | } 74 | } 75 | if (*begins == '\0' && *beginp != '\0') 76 | return false; 77 | else 78 | return true; 79 | } 80 | char * findSubStr(char *begins, char *beginp, char *endp) 81 | { 82 | char * s = begins, *p = beginp; 83 | while (*s != '\0') 84 | { 85 | while ( *p != '\0' && *s != '\0' && (*p == *s || *p == '?')) 86 | { 87 | p++; s++; 88 | } 89 | if (p == endp) 90 | return begins; 91 | if (*s == '\0') 92 | return NULL; 93 | p = beginp; 94 | s = ++begins; 95 | } 96 | return NULL; 97 | } 98 | ``` 99 | 100 | ## elegant solution 101 | 102 | [Linear runtime and constant space solution](https://discuss.leetcode.com/topic/3040/linear-runtime-and-constant-space-solution) 103 | 104 | 挨个元素讨论法 105 | ```cpp 106 | bool isMatch(const char *s, const char *p) { 107 | const char* star=NULL; 108 | const char* ss=s; 109 | while (*s){ 110 | //advancing both pointers when (both characters match) or ('?' found in pattern) 111 | //note that *p will not advance beyond its length 112 | if ((*p=='?')||(*p==*s)){s++;p++;continue;} 113 | 114 | // * found in pattern, track index of *, only advancing pattern pointer 115 | if (*p=='*'){star=p++; ss=s;continue;} 116 | 117 | //current characters didn't match, last pattern pointer was *, current pattern pointer is not * 118 | //only advancing pattern pointer 119 | if (star){ p = star+1; s=++ss;continue;} 120 | 121 | //current pattern pointer is not star, last patter pointer was not * 122 | //characters do not match 123 | return false; 124 | } 125 | 126 | //check for remaining characters in pattern 127 | while (*p=='*'){p++;} 128 | 129 | return !*p; 130 | } 131 | ``` 132 | 133 | -------------------------------------------------------------------------------- /String/49-group-anagrams.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 49-group-anagrams 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | 题目连接 9 | [Group Anagrams | LeetCode OJ](https://leetcode.com/problems/anagrams/) 10 | # 解法 11 | 12 | ```cpp 13 | vector> groupAnagrams(vector& strs) { 14 | // write your code here 15 | vector> result; 16 | typedef multimap strStrHash; 17 | strStrHash multiHash;//第一是是排序后的结果,第二个是对应的字符串; 18 | //先把所有的字符串排序然后放入一对多的map里面; 19 | for (int i = 0; i < strs.size(); i++) 20 | { 21 | string str = strs[i]; 22 | sort(str.begin(),str.end()); 23 | multiHash.insert(make_pair(str,strs[i])); 24 | } 25 | //把一个键有不少于两个值的值输出 26 | strStrHash::iterator hashIter; 27 | for (hashIter = multiHash.begin(); hashIter != multiHash.end(); ) 28 | { 29 | string tempKey = hashIter->first; 30 | vector *tempVecStr = new vector(); 31 | for (; hashIter != multiHash.upper_bound(tempKey); hashIter++) 32 | tempVecStr->push_back(hashIter->second); 33 | result.push_back(*tempVecStr); 34 | } 35 | return result; 36 | } 37 | ``` 38 | 39 | # 类似题目 40 | [Leetcode/lintcode-group-anagrams.md at master · DragonFive/Leetcode](https://github.com/DragonFive/Leetcode/blob/master/String/lintcode-group-anagrams.md) -------------------------------------------------------------------------------- /String/58-length-of-last-word.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 58-length-of-last-word 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | 9 | # source 10 | 11 | [58. Length of Last Word](https://leetcode.com/problems/length-of-last-word/) 12 | 13 | ## similiar problem in lintcode 14 | [422 Length of Last Word](http://www.lintcode.com/en/problem/length-of-last-word/) 15 | 16 | # solution 17 | 18 | ```cpp 19 | int lengthOfLastWord(string& s) { 20 | // Write your code here 21 | if (s.empty()) 22 | return 0; 23 | int len = s.length(); 24 | vector numWord(len + 1, 0); 25 | for (int i = 0; i < len; i++) 26 | if (isalpha(s[i])) 27 | numWord[i + 1] = numWord[i] + 1; 28 | for (int j = len; j > 0; j--) 29 | if (numWord[j] != 0) 30 | return numWord[j]; 31 | return 0; 32 | 33 | } 34 | ``` -------------------------------------------------------------------------------- /String/lint08-rotate-string.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: lint08-rotate-string 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # 题目来源 9 | 10 | [lintcode 8. rotate string](http://www.lintcode.com/en/problem/rotate-string/) 11 | 12 | # 解法 13 | 14 | ## 暴力求解法 15 | 16 | ```cpp 17 | void rotateString(string &str, int offset){ 18 | // wirte your code here 19 | // 交换的方法 20 | if (str.empty()) 21 | return; 22 | int len = str.length(); 23 | offset = offset % len; 24 | if (offset == 0) 25 | return; 26 | for (int i = len - offset; i < len; i++) 27 | { 28 | int yuzhi = i - (len - offset); 29 | for (int j = i; j > yuzhi; j--) 30 | swap(str, j, j - 1); 31 | } 32 | } 33 | void swap(string &str, int i, int j) 34 | { 35 | char temp = str[i]; 36 | str[i] = str[j]; 37 | str[j] = temp; 38 | } 39 | ``` 40 | 41 | ## 三次翻转法 42 | 常见的翻转法应用题,仔细观察规律可知翻转的分割点在从数组末尾数起的offset位置。先翻转前半部分,随后翻转后半部分,最后整体翻转。 43 | 44 | 三次翻转法 需要注意的是分段点在哪里。最先要知道的是如何翻转一个字符串 45 | ```cpp 46 | void rotateString(string &str,int offset) 47 | { 48 | //wirte your code here 49 | if (str.empty()) 50 | return; 51 | int len = str.size(); 52 | offset = offset % len; 53 | if (offset == 0) 54 | return; 55 | reverseStr(str, 0, len - offset - 1); 56 | reverseStr(str, len - offset, len - 1); 57 | reverseStr(str, 0, len - 1); 58 | } 59 | void reverseStr(string &str, int start, int end) 60 | { 61 | while(end > start) 62 | { 63 | char temp = str[start]; 64 | str[start] = str[end]; 65 | str[end] = temp; 66 | start++; 67 | end--; 68 | } 69 | } 70 | ``` 71 | 72 | 翻转一次时间复杂度近似为 O(n), 原地交换的空间复杂度为 O(1), 非原地交换的空间复杂度为 O(n). 总共翻转3次,所以总的时间复杂度为O(n), 空间复杂度为 O(1) 或者 O(n). -------------------------------------------------------------------------------- /String/lint138-Subarray-Sum.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: lint138-Subarray-Sum 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | # source 8 | 9 | [ lintcode 138-Subarray-Sum](http://www.lintcode.com/en/problem/subarray-sum/) 10 | 11 | ## similiar problem 12 | 13 | [geeks for geeks, Find if there is a subarray with 0 sum](http://www.geeksforgeeks.org/find-if-there-is-a-subarray-with-0-sum/) 14 | 15 | [lintcode139 Subarray Sum Closest](http://www.lintcode.com/en/problem/subarray-sum-closest/) 16 | 17 | # solution 18 | 可以先把问题转化,f(i) 表示从下标0到下标i求和的结果,那如果f(i) == f(j)就说明在i和j之间的数的和为0。在一串数中检索两个相等的数可以使用哈希表呀。 19 | 20 | **哈希表法** 21 | ```cpp 22 | vector subarraySum(vector nums){ 23 | // write your code here 24 | unordered_map sumInd; 25 | sumInd[0] = 0; 26 | int curSum = 0; 27 | vector result; 28 | for (int i = 0; i < nums.size(); i++) 29 | { 30 | curSum += nums[i]; 31 | if (sumInd.find(curSum) != sumInd.end()) 32 | { 33 | result.push_back(sumInd[curSum]); 34 | result.push_back(i); 35 | break; 36 | } 37 | else 38 | sumInd[curSum] = i + 1; 39 | } 40 | return result; 41 | } 42 | ``` 43 | 44 | **排序法** 45 | 46 | ```cpp 47 | vector subarraySum(vector nums){ 48 | // write your code here 49 | vector result; 50 | if (nums.empty()) 51 | return result; 52 | int numSum = nums.size(); 53 | vector > sum_index(numSum + 1); //和-下标对; 54 | int lastSum = 0; 55 | //先统计sum和index键值对; 56 | for (int i = 0; i < numSum; i++) 57 | { 58 | lastSum = lastSum + nums[i]; 59 | sum_index[i+1].first = lastSum; 60 | sum_index[i+1].second = i + 1; 61 | } 62 | //接下来排序然后看看相邻的两个是否一样; 63 | sort(sum_index.begin(), sum_index.end()); 64 | for (int i = 1; i < numSum + 1; i ++) 65 | if (sum_index[i].first == sum_index[i - 1].first) 66 | { 67 | result.push_back(sum_index[i - 1].second); 68 | result.push_back(sum_index[i].second - 1); 69 | break; 70 | } 71 | return result; 72 | } 73 | 74 | ``` 75 | 76 | # extention 77 | [geeks for geeks find subarray with given sum](http://www.geeksforgeeks.org/find-subarray-with-given-sum/) 78 | 79 | 80 | [lintcode139 Subarray Sum Closest](http://www.lintcode.com/en/problem/subarray-sum-closest/) 81 | 82 | 83 | [stack overflow How to find the subarray that has sum closest to zero or a certain value](http://stackoverflow.com/questions/16388930/how-to-find-the-subarray-that-has-sum-closest-to-zero-or-a-certain-value-t-in-o) 84 | -------------------------------------------------------------------------------- /String/lint158-anagrams.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: lintcode-anagrams 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | # 题目来源 8 | 9 | [ lintcode Two Strings Are Anagrams](http://www.lintcode.com/en/problem/two-strings-are-anagrams/) 10 | 11 | # 解法 12 | ## 使用哈希表统计词频 13 | 14 | ### 第一种方法使用c++的map集合来做: 15 | ```cpp 16 | 17 | bool anagram(string s, string t) { 18 | // write your code here 19 | if (s.size() != t.size()) 20 | return false; 21 | 22 | map maps, mapt; 23 | for (string::size_type ids = 0; ids < s.size(); ids++) 24 | { 25 | if (maps.find(s[ids]) == maps.end()) 26 | maps[s[ids]] = 1; 27 | else 28 | maps[s[ids]] ++; 29 | } 30 | for (string::size_type idt = 0; idt < s.size(); idt++) 31 | { 32 | if (mapt.find(t[idt]) == mapt.end()) 33 | mapt[t[idt]] = 1; 34 | else 35 | mapt[t[idt]] ++; 36 | } 37 | if (maps!=mapt) 38 | return false; 39 | return true; 40 | } 41 | ``` 42 | 43 | ### 第二种方法使用数组对每个字符进行统计 44 | 45 | ```cpp 46 | bool anagram(string s, string t) { 47 | // write your code here 48 | if (s.size() != t.size()) 49 | return false; 50 | 51 | int charNum[256] = {0};//初始化一个全0的数组; 52 | for(int i = 0;i < s.length();i++) 53 | { 54 | charNum[s[i]]++; 55 | charNum[t[i]]--; 56 | } 57 | for(int i = 0;i < s.length();i++) 58 | if(charNum[s[i]] != 0) 59 | return false; 60 | return true; 61 | } 62 | ``` 63 | 64 | ## 使用排序比较法 65 | ```cpp 66 | bool anagram(string s, string t) { 67 | // write your code here 68 | sort(s.begin(),s.end()); 69 | sort(t.begin(),t.end()); 70 | if(s != t) 71 | return false; 72 | return true; 73 | } 74 | ``` 75 | 76 | -------------------------------------------------------------------------------- /String/lint171-group-anagrams.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: lintcode-group-anagrams 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # 题目来源 9 | [Anagrams](http://www.lintcode.com/en/problem/anagrams/) 10 | # 解法 11 | ## 双层循环法 12 | 13 | ```cpp 14 | vector anagrams(vector &strs) { 15 | // write your code here 16 | vector result; 17 | const int strs_size = strs.size(); 18 | int *appended = new int[strs_size];//数组的大小一定要是常量; 除非它是动态划分的;这种链表其实可以用vector替代 19 | //vector visited(strs.size(), false); 初始化很方便; 20 | memset(appended, 0, sizeof(int)*strs_size); 21 | for (int i = 0; i < strs.size()-1; i++) 22 | { 23 | if (appended[i]) 24 | continue; 25 | const int charNums = 26; 26 | int charNum[charNums] = {0}; 27 | //先统计自己; 28 | for (int j = 0; j < strs[i].length(); j++) 29 | charNum[strs[i][j] - 'a']++; 30 | //然后与其它元素进行比较; 31 | for (int j = i+1; j < strs.size(); j++) 32 | { 33 | //判断是否访问过; 34 | if (appended[j]) 35 | continue; 36 | //首先判断长度是否一致 37 | if (strs[j].length() != strs[i].length()) 38 | continue; 39 | //其实上面的两个可以替换为 if (appended[j] || strs[j].length() != strs[i].length()) 40 | //统计这个里面的元素 41 | int charNumB[charNums] = {0}; 42 | for (int k = 0; k < strs[j].length(); k++) 43 | charNumB[strs[j][k] - 'a']++; 44 | //比较两个是否一样; 45 | int k = 0; 46 | for (; k < charNums; k++) 47 | if (charNum[k] != charNumB[k]) 48 | break; 49 | if (k != charNums) 50 | continue; 51 | //到这里说明碰到一个一样的; 52 | if (!appended[i])//一定要注意相同的字符串的情况,和前面的相同字符统计一样; 53 | result.push_back(strs[i]); 54 | appended[i] = 1; 55 | appended[j] = 1; 56 | result.push_back(strs[j]); 57 | } 58 | } 59 | return result; 60 | } 61 | ``` 62 | 63 | ## 排序和hashmap法 64 | 下面的multimap用的非常巧,即用到了一对多的红黑树 又用到了自动排序 65 | ```cpp 66 | vector anagrams(vector &strs) { 67 | // write your code here 68 | vector result; 69 | typedef multimap strStrHash; 70 | strStrHash multiHash;//第一是是排序后的结果,第二个是对应的字符串; 71 | //先把所有的字符串排序然后放入一对多的map里面; 72 | for (int i = 0; i < strs.size(); i++) 73 | { 74 | string str = strs[i]; 75 | sort(str.begin(),str.end()); 76 | multiHash.insert(make_pair(str,strs[i])); 77 | } 78 | //把一个键有不少于两个值的值输出 79 | strStrHash::iterator hashIter; 80 | for (hashIter = multiHash.begin(); hashIter != multiHash.end(); hashIter++) 81 | if (multiHash.count(hashIter->first) > 1) 82 | result.push_back(hashIter->second); 83 | return result; 84 | } 85 | ``` 86 | 87 | ## leetcode类似题目 88 | [49-group-anagrams.md](https://github.com/DragonFive/Leetcode/blob/master/String/49-group-anagrams.md) 89 | ## 参考资料 90 | 91 | [C++ 标准模板库STL multimap 使用方法与应用介绍(一) - 王世晖的学习记录 - 博客频道 - CSDN.NET](http://blog.csdn.net/wangshihui512/article/details/8925145) 92 | 93 | [c++中map与unordered_map的区别 - wolfrevoda的专栏 - 博客频道 - CSDN.NET](http://blog.csdn.net/batuwuhanpei/article/details/50727227) 94 | 95 | -------------------------------------------------------------------------------- /String/lint192-Wildcard-Matching.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: lint192-Wildcard-Matching 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | # source 8 | [lintcode Wildcard-Matching ](http://www.lintcode.com/en/problem/wildcard-matching/#) 9 | 10 | 相似题目 11 | 12 | [leetcode 44 Wildcard-Matching](https://leetcode.com/problems/wildcard-matching/) 13 | # solution 14 | 15 | ```cpp 16 | bool isMatch(string m, string n) 17 | { 18 | // write your code here 19 | // 找* 起点 20 | char * begins = (char *)m.c_str(), *beginp = (char *)n.c_str(); 21 | while (*beginp != '*' && *beginp != '\0' && *begins != '\0') 22 | if (*beginp != *begins && *beginp != '?') 23 | return false; 24 | else 25 | { 26 | beginp++; begins++; 27 | } 28 | if (*beginp == '\0' && *begins == '\0') 29 | return true; 30 | if (*beginp == '\0' || *begins == '\0' && *beginp != '*') 31 | return false; 32 | while (*beginp == '*') 33 | beginp++; 34 | while (*beginp != '\0' && *begins != '\0') 35 | { 36 | //下面找到下一个*的位置 37 | char * endp = beginp; 38 | while (*endp != '*' && *endp != '\0') 39 | endp++; 40 | // 从beginp到endp 41 | //分情况讨论如果 *endp == '*'走下面 42 | if (*endp == '*') 43 | { 44 | char *finds = findSubStr(begins, beginp, endp); 45 | if (finds == NULL) 46 | return false; 47 | begins = finds + (endp - beginp); 48 | beginp = endp; 49 | while (*beginp == '*') 50 | beginp++; 51 | } 52 | else 53 | { 54 | //右对齐进行比较 55 | char * ends = begins; 56 | while (*ends != '\0') 57 | ends++; 58 | while ((*ends == *endp || *endp == '?') && ends >= begins && endp >= beginp) 59 | { 60 | ends--; 61 | endp--; 62 | } 63 | if (endp < beginp) 64 | return true; 65 | else 66 | return false; 67 | 68 | } 69 | } 70 | if (*begins == '\0' && *beginp != '\0') 71 | return false; 72 | else 73 | return true; 74 | } 75 | char * findSubStr(char *begins, char *beginp, char *endp) 76 | { 77 | char * s = begins, *p = beginp; 78 | while (*s != '\0') 79 | { 80 | while ( *p != '\0' && *s != '\0' && (*p == *s || *p == '?')) 81 | { 82 | p++; s++; 83 | } 84 | if (p == endp) 85 | return begins; 86 | if (*s == '\0') 87 | return NULL; 88 | p = beginp; 89 | s = ++begins; 90 | } 91 | return NULL; 92 | } 93 | ``` -------------------------------------------------------------------------------- /String/lint200-Longest-Palindromic-Substring.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: lint200-Longest-Palindromic-Substring 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | # 题目来源 8 | [lint200-Longest-Palindromic-Substring](http://www.lintcode.com/en/problem/longest-palindromic-substring/) 9 | ## 相似题目 10 | 11 | [leetcode 5. Longest Palindromic Substring](https://leetcode.com/problems/longest-palindromic-substring/) 12 | # 解法 13 | 14 | ## 寻找最长公共字串(错误的做法) 15 | 16 | 时间复杂度为O(n^2) 17 | ```cpp 18 | string longestPalindrome(string& s) 19 | { 20 | // Write your code here 21 | if (s.empty()) 22 | return s; 23 | string t = s; 24 | std::reverse(t.begin(), t.end()); 25 | int len = s.length(); 26 | vector > lenVec = vector >(len + 1, vector(len + 1, 0)); 27 | for (int i = 0; i < len; i++) 28 | for (int j = 0; j < len; j++) 29 | if (s[i] == t[j]) 30 | lenVec[i + 1][j + 1] = lenVec[i][j] + 1; 31 | int maxLen = 0, endIdx = 0; 32 | for (int i = 0; i <= len; i++) 33 | for (int j = 0; j <= len; j++) 34 | if (lenVec[i][j] > maxLen ) 35 | { 36 | maxLen = lenVec[i][j]; 37 | endIdx = i - 1; 38 | } 39 | return s.substr(endIdx - maxLen + 1, maxLen); 40 | } 41 | ``` 42 | **注意** 上面的做法是错误的 43 | [Longest Palindromic Substring Part I](http://articles.leetcode.com/longest-palindromic-substring-part-i) 44 | 里面有解释 45 | 比如 S = “abacdfgdcaba”, 则它翻转之后为S’ = “abacdgfdcaba” 计算结果为 “abacd”,显然这个并不是回文序列 46 | 47 | 不过我们依然可以修正它,虽然在中间过程中子问题算法的是最长公共字串,但最后可以根据题目的要求在这些字串里面找到最大的字串 48 | ### 修正后的代码为 49 | 需要保证两个串其实在坐标上是一个串 50 | 时间复杂度O(N2) 空间复杂度 O(N2) 51 | ```cpp 52 | string longestPalindrome(string& s) 53 | { 54 | // Write your code here 55 | if (s.empty()) 56 | return s; 57 | string t = s; 58 | std::reverse(t.begin(), t.end()); 59 | int len = s.length(); 60 | vector > lenVec = vector >(len + 1, vector(len + 1, 0)); 61 | for (int i = 0; i < len; i++) 62 | for (int j = 0; j < len; j++) 63 | if (s[i] == t[j]) 64 | lenVec[i + 1][j + 1] = lenVec[i][j] + 1; 65 | int maxLen = 0, endIdx = 0; 66 | for (int i = 0; i <= len; i++) 67 | for (int j = 0; j <= len; j++) 68 | if (lenVec[i][j] > maxLen && ( i - len + j == lenVec[i][j] )) 69 | { 70 | maxLen = lenVec[i][j]; 71 | endIdx = i - 1; 72 | } 73 | return s.substr(endIdx - maxLen + 1, maxLen); 74 | } 75 | 76 | ``` 77 | 78 | 79 | ## 两端拓展法 80 | 这里认为遍历到的一个位置是回文字的中心,然后去找它的边界。这里的子问题是以该位置为中心的回文数的长度。 81 | 这个算法的时间复杂度是 O(n^2) 空间复杂度是O(1) 82 | 83 | ```cpp 84 | string longestPalindrome(string& s) 85 | { 86 | // Write your code here 87 | if (s.empty()) 88 | return s; 89 | string res; 90 | int len = s.length(); 91 | for (int i = 0; i < len; i++) 92 | { 93 | string temp; 94 | temp = findPalindrome(s, i, i); 95 | if (temp.size() > res.size())res = temp; 96 | temp = findPalindrome(s, i, i+1); 97 | if (temp.size() > res.size())res = temp; 98 | } 99 | return res; 100 | } 101 | string findPalindrome(string& s, int m, int n) 102 | { 103 | while (m >= 0 && n < s.size() && s[m] == s[n]) 104 | { 105 | m--; 106 | n++; 107 | } 108 | return s.substr(m + 1, n - m - 1); 109 | } 110 | ``` 111 | 112 | 113 | ## 参考资料 114 | 115 | [Longest Palindromic Substring Part I](http://articles.leetcode.com/longest-palindromic-substring-part-i) 116 | 117 | [Longest Palindromic Substring Part II](http://articles.leetcode.com/longest-palindromic-substring-part-ii) 118 | 119 | 120 | 121 | 122 | 123 | -------------------------------------------------------------------------------- /String/lint212-Space-Replacement.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: lint212-Space-Replacement 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # 题目来源 9 | 10 | [lintcode 212-Space-Replacement](http://www.lintcode.com/en/problem/space-replacement/) 11 | 12 | 水题 13 | 14 | # 解法 15 | 16 | ```cpp 17 | int replaceBlank(char string[], int length) { 18 | // Write your code here 19 | // 先计算空格的个数 20 | int newLength = length; 21 | for (int i = 0; i < length; i++) 22 | if (string[i] == ' ') 23 | newLength += 2; 24 | //然后从后往前改变字符串 25 | int i = length - 1, j = newLength - 1; 26 | while (j > i) 27 | { 28 | if (string[i] == ' ') 29 | { 30 | string[j] = '0'; 31 | string[j-1] = '2'; 32 | string[j-2] = '%'; 33 | j -= 3; 34 | } 35 | else 36 | { 37 | string[j] = string[i]; 38 | j--; 39 | } 40 | i--; 41 | } 42 | return newLength; 43 | } 44 | ``` -------------------------------------------------------------------------------- /String/lint39-Recover-Rotated-Sorted-Array.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: lint39-Recover-Rotated-Sorted-Array 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # source 9 | [lintcode 39 Recover Rotated Sorted Array](http://www.lintcode.com/en/problem/recover-rotated-sorted-array/) 10 | ## similiar problem 11 | 12 | [lintcode 8. rotate string](http://www.lintcode.com/en/problem/rotate-string/) 13 | 14 | 15 | # solution 16 | 三步翻转法,也可以认为是两根指针 17 | ```cpp 18 | void recoverRotatedSortedArray(vector &nums) { 19 | // write your code here 20 | if (nums.empty()) 21 | return; 22 | //先找到旋转的位置; 23 | int i = 0; 24 | for (; i < nums.size(); i++) 25 | if (nums[i] > nums[i + 1]) 26 | break; 27 | if (i == nums.size()) 28 | return; 29 | reverseArray(nums, 0, i); 30 | reverseArray(nums, i + 1, nums.size() - 1); 31 | reverseArray(nums, 0, nums.size() - 1); 32 | } 33 | void reverseArray(vector &nums, int begin, int end) 34 | { 35 | while (begin < end) 36 | { 37 | int temp = nums[begin]; 38 | nums[begin] = nums[end]; 39 | nums[end] = temp; 40 | begin++;end--; 41 | } 42 | } 43 | ``` 44 | -------------------------------------------------------------------------------- /String/lint415-valid-pal.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: lint415-valid-pal 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | # 题目来源 7 | 8 | [415 valid palindrome](http://www.lintcode.com/en/problem/valid-palindrome/) 9 | 10 | ## leedcode相似题目 11 | 12 | [125 valid palindrome](https://leetcode.com/problems/valid-palindrome/) 13 | 14 | # 解法 15 | 字符串的回文判断问题,由于字符串可随机访问,故逐个比较首尾字符是否相等最为便利,即常见的『两根指针』技法。此题忽略大小写,并只考虑字母和数字字符 16 | ## 两根指针法 17 | 判断链表是否有环的方法是快慢指针法 18 | 19 | ```cpp 20 | bool isPalindrome(string& s) { 21 | // Write your code here 22 | int len = s.length(); 23 | int start = 0, end = len - 1; 24 | while (end >= start) 25 | { 26 | while (!(isdigit(s[start]) || isalpha(s[start]) ) ) 27 | start++; 28 | while (!(isdigit(s[end]) || isalpha(s[end]) ) ) 29 | end--; 30 | if (end >= start && (s[end] - s[start]) % ('A' - 'a') != 0) 31 | return false; 32 | start++; 33 | end--; 34 | } 35 | return true; 36 | } 37 | ``` 38 | 39 | # 启示 40 | 需要记住c语言的一些字符串处理api: tolower 把字符转化为小写, isalnum 判断一个字符是否是字母或者数字 , isdigit判断字符是否是数字 isalpha 判断是否是字母 41 | 42 | # 引申到回文链表 43 | 44 | [geeksforgeeks 如何判断一个链表是否是回文链表](http://www.geeksforgeeks.org/function-to-check-if-a-singly-linked-list-is-palindrome/) 45 | 46 | 题目中用到了数组的随机访问,所以可以使用两根指针的方式分别向后和向前比较。但如果是链表的话就不能往前返回了,需要用新的思路 47 | 48 | 1. 使用一个stack 49 | 2. 先找到队列的中间,然后对后一半进行翻转,比较前后两半的队列,如果一样把后一半再翻转回来 50 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /String/lint50-Product-Array-Exclude-itself.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: lint50-Product-Array-Exclude-itself 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | # source 8 | 9 | [lintcode 50 Product of Array Exclude Itself]() 10 | # solution 11 | 12 | ## rude solution 13 | 14 | ```cpp 15 | vector productExcludeItself(vector &nums) { 16 | // write your code here 17 | vector result; 18 | if (nums.empty() || nums.size() < 2) 19 | { 20 | result.push_back(1); 21 | return result; 22 | } 23 | for (int i = 0; i < nums.size(); i++) 24 | { 25 | long long product = 1; 26 | for (int j = 0; j < nums.size(); j++) 27 | if (j != i) 28 | product *= nums[j]; 29 | result.push_back(product); 30 | } 31 | return result; 32 | } 33 | ``` 34 | 35 | 36 | ## divide and conquer 37 | 左右分治法,其实应该算是递推法 38 | 39 | ```cpp 40 | vector productExcludeItself(vector &nums) { 41 | // write your code here 42 | const int numsSize = nums.size(); 43 | vector result(numsSize, 1); //先分配空间; 44 | if (nums.empty() || numsSize == 1) 45 | return result; 46 | vector left(numsSize, 1); 47 | vector right(numsSize, 1); 48 | //开始计算左边; 49 | for (int i = 1; i < numsSize; i++) 50 | left[i] = left[i - 1] * nums[i - 1]; 51 | //再计算右边; 52 | for (int i = numsSize - 2; i >= 0; i--) 53 | right[i] = right[i + 1] * nums[i + 1]; 54 | //然后把两者合并; 55 | for (int i = 0; i < numsSize; i++) 56 | result[i] = left[i] * right[i]; 57 | return result; 58 | } 59 | ``` 60 | -------------------------------------------------------------------------------- /String/lint53-reverseWord.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: lint53-reverseWord 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | # 题目来源 8 | 9 | [53 Reverse Words in a String](http://www.lintcode.com/en/problem/reverse-words-in-a-string/#) 10 | 11 | 12 | # 解法 13 | 注意两种意外 14 | 1. 串为空 15 | 2. 串内都是空格 16 | ```cpp 17 | string reverseWords(string s) { 18 | // write your code here 19 | if (s.empty() ) 20 | return s; 21 | vector strVec; 22 | stringstream strStr(s); 23 | string temp, result; 24 | while(strStr>>temp) 25 | strVec.push_back(temp); 26 | if (strVec.size() < 2) 27 | return s; 28 | for (int i = strVec.size() - 1; i > 0; i--) 29 | { 30 | result += strVec[i] + " "; 31 | } 32 | result += strVec[0]; 33 | return result; 34 | } 35 | ``` 36 | -------------------------------------------------------------------------------- /String/lint55-compare-string.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: lintcode-compare-string 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # 题目来源 9 | [Compare Strings](http://www.lintcode.com/en/problem/compare-strings/#) 10 | # 哈希表法 11 | ## 使用数组 12 | 需要注意的是数组的大小,以及各个元素的转换关系 13 | ```cpp 14 | bool compareStrings(string s, string t) { 15 | // write your code here 16 | 17 | const int charNum = 26; 18 | int charContain[charNum] = {0}; 19 | for(int i = 0;i < s.length();i++) 20 | charContain[s[i] - 'A']++; 21 | for(int i = 0;i < t.length();i++) 22 | charContain[t[i] - 'A']--; 23 | for(int i = 0;i < t.length();i++) 24 | if(charContain[t[i] - 'A'] < 0) 25 | return false; 26 | return true; 27 | } 28 | ``` 29 | -------------------------------------------------------------------------------- /String/lint79-LCS.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: lint79-LCS 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | # 题目来源 8 | [Longest Common Substring](http://www.lintcode.com/en/problem/longest-common-substring/#) 9 | 10 | # 解法 11 | 12 | ## 动态规划 13 | ### 下面是节省空间但逻辑比较复杂的代码 14 | 动态规划注意初始化,和状态的转移; 时间复杂度$O(n^2)$ 15 | ```cpp 16 | int longestCommonSubstring(string &A, string &B) { 17 | // write your code here 18 | int subIndexA, subIndexB, coLen, i = 0; 19 | //先初始化各个元素 20 | for (; i < B.length(); i++) 21 | { 22 | if (A.find(B[i]) != string::npos) 23 | { 24 | subIndexA = A.find(B[i]); 25 | subIndexB = i; 26 | coLen = 1; 27 | break; 28 | } 29 | } 30 | if (i == B.length()) 31 | return 0; 32 | //i表示待考察的B的下标; 33 | for (i = subIndexB + 1; i < B.length(); i++) 34 | { 35 | //使用动态规划的办法B的长度不断地增长; 36 | //如果当前的下标正好在之前的后一个 则判断是否相等 37 | if ( subIndexB + coLen == i && A[subIndexA + coLen] == B[i]) 38 | coLen++; 39 | else 40 | { 41 | //就看从i往前看,是否有长度为coLen的其它字串呢; 42 | int tempIndex = A.find(B.substr(i - coLen, coLen + 1), 0); 43 | if ( tempIndex != string::npos) 44 | { 45 | subIndexA = tempIndex; 46 | coLen++; 47 | subIndexB = i - coLen + 1; 48 | } 49 | else 50 | { 51 | tempIndex = A.find(B.substr(i - coLen + 1, coLen), 0); 52 | if ( tempIndex != string::npos) 53 | { 54 | subIndexA = tempIndex; 55 | subIndexB = i - coLen + 1; 56 | } 57 | } 58 | } 59 | } 60 | return coLen; 61 | } 62 | ``` 63 | 64 | ### 下面是正统的动态规划的代码 65 | 66 | 二维数组表示的是以i,j结尾的且其字符相等的字串LCS,如果不相等则为0,不做修改,很是方便啊 67 | 注意这里面二维数组直接使用vector的vector很是方便呢 68 | 69 | ```cpp 70 | int longestCommonSubstring(string &A, string &B) { 71 | if (A.empty() || B.empty()) 72 | return 0; 73 | int lenA = A.length(); 74 | int lenB = B.length(); 75 | //下面的动态二维数组保存的是以i,j结尾的子串的长度; 76 | vector> lcsVec(lenA + 1, vector(lenB + 1, 0)); 77 | for (int i = 0; i < lenA; i++) 78 | { 79 | for (int j = 0; j < lenB; j++) 80 | { 81 | //把i,j的结果保存在i+1,j+1里面便于初始化; 82 | if (B[j] == A[i] ) 83 | lcsVec[i + 1][j + 1] = lcsVec[i][j] + 1; 84 | } 85 | } 86 | //下面找到最大的lcs; 87 | int maxLcs = 0; 88 | for (int i = 0; i < lenA + 1; i++) 89 | for (int j = 0; j < lenB + 1; j++) 90 | if (lcsVec[i][j] > maxLcs) 91 | maxLcs = lcsVec[i][j]; 92 | return maxLcs; 93 | } 94 | ``` -------------------------------------------------------------------------------- /binaryTree/102-binary-tree-level-order-traversal.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 102-binary-tree-level-order-traversal 3 | tags: 在河之洲,算法,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # problem 9 | [102-binary-tree-level-order-traversal](https://leetcode.com/problems/binary-tree-level-order-traversal/#/description) 10 | # solution 11 | 用两个队列 12 | ```cpp 13 | vector> levelOrder(TreeNode* root) { 14 | queue q1; 15 | vector> result; 16 | if (root == NULL) 17 | return result; 18 | q1.push(root); 19 | while (!q1.empty()) 20 | { 21 | queue q2; 22 | vector ret; 23 | while (!q1.empty()) 24 | { 25 | TreeNode * cur = q1.front(); 26 | ret.push_back(cur->val); 27 | q1.pop(); 28 | if (cur->left) 29 | q2.push(cur->left); 30 | if (cur->right) 31 | q2.push(cur->right); 32 | } 33 | result.push_back(ret); 34 | q1 = q2; 35 | } 36 | return result; 37 | } 38 | 39 | ``` 40 | 41 | 只用一个队列 42 | vector> levelOrder(TreeNode* root) { 43 | queue q1; 44 | vector> result; 45 | if (root == NULL) 46 | return result; 47 | q1.push(root); 48 | int qsize = 1; 49 | while (!q1.empty()) 50 | { 51 | vector ret; 52 | for (int i = 0; i < qsize; i++) 53 | { 54 | TreeNode * cur = q1.front(); 55 | ret.push_back(cur->val); 56 | q1.pop(); 57 | if (cur->left) 58 | q1.push(cur->left); 59 | if (cur->right) 60 | q1.push(cur->right); 61 | } 62 | qsize = q1.size(); 63 | result.push_back(ret); 64 | } 65 | return result; 66 | } -------------------------------------------------------------------------------- /binaryTree/103-binary-tree-zigzag-level-order-traversal.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 103-binary-tree-zigzag-level-order-traversal 3 | tags: 在河之洲,算法,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | # problem 8 | [103-binary-tree-zigzag-level-order-traversal](https://leetcode.com/problems/binary-tree-zigzag-level-order-traversal/#/description) 9 | 10 | # solution 11 | 双栈交叉换序法 12 | ```cpp 13 | vector> zigzagLevelOrder(TreeNode* root) { 14 | stack q,s; 15 | vector> res; 16 | if (root == NULL) 17 | return res; 18 | q.push(root); 19 | while (!q.empty()) 20 | { 21 | vector r; 22 | while(!q.empty()) 23 | { 24 | TreeNode *tmp = q.top(); 25 | r.push_back(tmp->val); 26 | q.pop(); 27 | if (tmp->left) 28 | s.push(tmp->left); 29 | if (tmp->right) 30 | s.push(tmp->right); 31 | } 32 | if (!r.empty()) 33 | res.push_back(r); 34 | vector t; 35 | while(!s.empty()) 36 | { 37 | TreeNode *tmp = s.top(); 38 | s.pop(); 39 | t.push_back(tmp->val); 40 | if (tmp->right) 41 | q.push(tmp->right); 42 | if (tmp->left) 43 | q.push(tmp->left); 44 | 45 | } 46 | if (!t.empty()) 47 | res.push_back(t); 48 | } 49 | return res; 50 | } 51 | 52 | ``` 53 | -------------------------------------------------------------------------------- /binaryTree/104-maximum-depth-of-binary-tree.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 104-maximum-depth-of-binary-tree 3 | tags: 在河之洲,算法,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # problem 9 | [104-maximum-depth-of-binary-tree](https://leetcode.com/problems/maximum-depth-of-binary-tree/#/description) 10 | 11 | # solution 12 | 13 | 递归法: 14 | ```cpp 15 | int maxDepth(TreeNode* root) { 16 | if (root == NULL) 17 | return 0; 18 | int leftDepth = maxDepth(root->left); 19 | int rightDepth = maxDepth(root->right); 20 | return leftDepth>rightDepth?leftDepth+1:rightDepth+1; 21 | } 22 | 23 | ``` 24 | 25 | 广度优先遍历 用队列 26 | ```cpp 27 | int maxDepth(TreeNode* root) { 28 | int maxDepth = 0; 29 | if (root == NULL) 30 | return 0; 31 | queue st; 32 | st.push(root); 33 | while (!st.empty()) 34 | { 35 | int qsize = st.size(); 36 | maxDepth++; 37 | while (qsize--) 38 | { 39 | TreeNode * fa = st.front(); 40 | st.pop(); 41 | if (fa->left||fa->right) 42 | { 43 | if (fa->left) 44 | st.push(fa->left); 45 | if (fa->right) 46 | st.push(fa->right); 47 | } 48 | } 49 | } 50 | return maxDepth; 51 | } 52 | ``` 53 | 54 | 55 | -------------------------------------------------------------------------------- /binaryTree/105-construct-binary-tree-from-preorder-and-inorder-traversal.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 105-construct-binary-tree-from-preorder-and-inorder-traversal 3 | tags: 在河之洲,算法,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | # problem 8 | [105-construct-binary-tree-from-preorder-and-inorder-traversal](https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/#/description) 9 | 10 | # solution 11 | 递归 12 | ```cpp 13 | typedef vector::iterator vi; 14 | TreeNode* buildTree(vector& preorder, vector& inorder) { 15 | if (preorder.empty()) 16 | return NULL; 17 | return helper(preorder.begin(),preorder.end()-1,inorder.begin(),inorder.end()-1); 18 | } 19 | TreeNode *helper(vi b1, vi e1,vi b2,vi e2) 20 | { 21 | if (b1 == e1) 22 | { 23 | TreeNode *root = new TreeNode(*b1); 24 | return root; 25 | } 26 | //找到第一个的根节点; 27 | int val = *b1; 28 | vi i = b2; 29 | for(; i != e2+1; i ++) 30 | { 31 | if (*i == val) 32 | break; 33 | } 34 | TreeNode *root = new TreeNode(val); 35 | if (i != b2) 36 | root->left = helper(b1+1,b1+(i-b2),b2,i-1); 37 | if (i != e2) 38 | root->right= helper(b1+(i-b2)+1,e1,i+1,e2); 39 | return root; 40 | } 41 | 42 | ``` 43 | 44 | # similiar problem 45 | [72-construct-binary-tree-from-inorder-and-postorder-traversal](http://www.lintcode.com/en/problem/construct-binary-tree-from-inorder-and-postorder-traversal/#) 46 | # solution 47 | 48 | ```cpp 49 | typedef vector::iterator vi; 50 | TreeNode *buildTree(vector &inorder, vector &postorder) { 51 | // write your code here 52 | if (postorder.empty()) 53 | return NULL; 54 | return helper(postorder.begin(),postorder.end()-1,inorder.begin(),inorder.end()-1); 55 | } 56 | TreeNode *helper(vi b1, vi e1,vi b2,vi e2) 57 | { 58 | if (b1 == e1) 59 | { 60 | TreeNode *root = new TreeNode(*b1); 61 | return root; 62 | } 63 | //找到第一个的根节点; 64 | int val = *e1; 65 | vi i = b2; 66 | for(; i != e2+1; i ++) 67 | { 68 | if (*i == val) 69 | break; 70 | } 71 | TreeNode *root = new TreeNode(val); 72 | if (i != b2) 73 | root->left = helper(b1,b1+(i-b2)-1,b2,i-1); 74 | if (i != e2) 75 | root->right= helper(b1+(i-b2),e1-1,i+1,e2); 76 | return root; 77 | } 78 | ``` 79 | 80 | -------------------------------------------------------------------------------- /binaryTree/110-balanced-binary-tree.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 110-balanced-binary-tree 3 | tags: 在河之洲,算法,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # problem 9 | [110-balanced-binary-tree](https://leetcode.com/problems/balanced-binary-tree/#/description) 10 | 11 | # solution 12 | 递归法 13 | ```cpp 14 | bool isBalanced(TreeNode* root) { 15 | if (helper(root) == -1) 16 | return false; 17 | return true; 18 | } 19 | int helper(TreeNode *root) 20 | { 21 | if (root == NULL) 22 | return 0; 23 | int leftDepth = helper(root->left ); 24 | int rightDepth = helper(root->right); 25 | if (leftDepth == -1 || rightDepth == -1) 26 | return -1; 27 | if (leftDepth == rightDepth || rightDepth == leftDepth+1 || leftDepth == rightDepth+1 ) 28 | return leftDepth>rightDepth?leftDepth+1:rightDepth+1; 29 | return -1; 30 | } 31 | ``` -------------------------------------------------------------------------------- /binaryTree/144-binary-tree-preorder-traversal.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 144-binary-tree-preorder-traversal 3 | tags: 在河之洲,算法,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # problem 9 | [144-binary-tree-preorder-traversal](https://leetcode.com/problems/binary-tree-preorder-traversal/#/description) 10 | # solution 11 | 用递归的方式进行先序遍历 12 | 13 | ```cpp 14 | vector preorderTraversal(TreeNode* root) { 15 | vector result; 16 | preorderVisit(root, result); 17 | return result; 18 | } 19 | void preorderVisit(TreeNode *node, vector &ret) 20 | { 21 | if (node!=NULL) 22 | { 23 | ret.push_back(node->val); 24 | preorderVisit(node->left,ret); 25 | preorderVisit(node->right,ret); 26 | } 27 | } 28 | ``` 29 | 30 | 31 | 借助栈结构的迭代法 32 | 33 | ```cpp 34 | vector preorderTraversal(TreeNode* root) { 35 | vector result; 36 | if (root == NULL) 37 | return result; 38 | stack toVisit; 39 | toVisit.push(root); 40 | while (!toVisit.empty()) 41 | { 42 | TreeNode *tmp = toVisit.top(); 43 | result.push_back(tmp->val); 44 | toVisit.pop(); 45 | if (tmp->right) 46 | toVisit.push(tmp->right); 47 | if (tmp->left) 48 | toVisit.push(tmp->left); 49 | } 50 | return result; 51 | 52 | } 53 | 54 | ``` -------------------------------------------------------------------------------- /binaryTree/145-binary-tree-postorder-traversal.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 145-binary-tree-postorder-traversal 3 | tags: 在河之洲,算法,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | [TOC] 7 | 8 | # problem 9 | [145-binary-tree-postorder-traversal](https://leetcode.com/problems/binary-tree-postorder-traversal/#/description) 10 | 11 | # solution 12 | ## 递归法 13 | ```cpp 14 | vector postorderTraversal(TreeNode* root) { 15 | vector result; 16 | if (root == NULL) 17 | return result; 18 | posterVisit(root,result); 19 | return result; 20 | } 21 | void posterVisit(TreeNode *root, vector &ret) 22 | { 23 | if (root) 24 | { 25 | posterVisit(root->left ,ret); 26 | posterVisit(root->right,ret); 27 | ret.push_back(root->val); 28 | } 29 | } 30 | ``` 31 | 32 | ## 迭代法 + 反序法 33 | ```cpp 34 | vector postorderTraversal(TreeNode* root) { 35 | vector result; 36 | if (root == NULL) 37 | return result; 38 | stack st; 39 | st.push(root); 40 | TreeNode *cur = root; 41 | while (!st.empty()) 42 | { 43 | cur = st.top(); 44 | result.push_back(cur->val); 45 | st.pop(); 46 | if (cur->left) 47 | st.push(cur->left); 48 | if (cur->right) 49 | st.push(cur->right); 50 | } 51 | //下面对result,进行reverse; 52 | reverse(result.begin(),result.end()); 53 | return result; 54 | } 55 | ``` 56 | 57 | ## 迭代法 记录孩子访问过 58 | 59 | ```cpp 60 | vector postorderTraversal(TreeNode* root) { 61 | vector result; 62 | if (root == NULL) 63 | return result; 64 | stack st; 65 | TreeNode *cur = root; 66 | TreeNode *pre = NULL; 67 | st.push(root); 68 | while (!st.empty()) 69 | { 70 | if (!cur->left && !cur->right || pre != NULL && (pre == cur->left || pre == cur->right) )//无左右孩子,或者都访问过; 71 | {//则访问当前节点; 72 | st.pop(); 73 | result.push_back(cur->val); 74 | pre = cur; 75 | if (!st.empty()) 76 | cur = st.top(); 77 | } 78 | else 79 | { 80 | if (cur->right) 81 | { 82 | st.push(cur->right); 83 | } 84 | if (cur->left) 85 | { 86 | st.push(cur->left); 87 | } 88 | cur = st.top(); 89 | } 90 | } 91 | return result; 92 | } 93 | ``` -------------------------------------------------------------------------------- /binaryTree/94-binary-tree-inorder-traversal.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 94-binary-tree-inorder-traversal 3 | tags: 在河之洲,算法,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # problem 9 | [94-binary-tree-inorder-traversal](https://leetcode.com/problems/binary-tree-inorder-traversal/#/description) 10 | 11 | 12 | # solution 13 | 14 | ```cpp 15 | vector inorderTraversal(TreeNode* root) { 16 | vector result; 17 | inorderVisit(root,result); 18 | return result; 19 | } 20 | void inorderVisit(TreeNode*node,vector &ret) 21 | { 22 | if(node) 23 | { 24 | inorderVisit(node->left,ret); 25 | ret.push_back(node->val); 26 | inorderVisit(node->right,ret); 27 | } 28 | } 29 | ``` 30 | 31 | 迭代法 辅助栈 32 | ```cpp 33 | vector inorderTraversal(TreeNode* root) { 34 | vector result; 35 | if (root == NULL) 36 | return result; 37 | stack st; 38 | st.push(root); 39 | TreeNode *cur = root; 40 | while (!st.empty()) 41 | { 42 | while (cur->left) 43 | { 44 | st.push(cur->left); 45 | cur = cur->left; 46 | } 47 | st.pop(); 48 | result.push_back(cur->val); 49 | //访问右节点; 50 | while (cur->right == NULL && !st.empty()) 51 | { 52 | cur = st.top(); 53 | st.pop(); 54 | result.push_back(cur->val); 55 | } 56 | if (cur->right) 57 | { 58 | st.push(cur->right); 59 | cur = cur->right; 60 | } 61 | } 62 | return result; 63 | } 64 | ``` 65 | 66 | -------------------------------------------------------------------------------- /binaryTree/lint245-subtree.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: lint245-subtree 3 | tags: 在河之洲,算法,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | # problem 8 | 9 | [lint245-subtree](http://www.lintcode.com/en/problem/subtree/#) 10 | 11 | # solution 12 | 13 | ```cpp 14 | bool isSubtree(TreeNode *T1, TreeNode *T2) { 15 | // write your code here 16 | //先找到root; 17 | if (T2 == NULL) 18 | return true; 19 | if (T1 == NULL) 20 | return false; 21 | if (sameTree(T1,T2)) 22 | return true; 23 | return isSubtree(T1->left,T2) | isSubtree(T1->right,T2); 24 | } 25 | 26 | bool sameTree(TreeNode *T1, TreeNode *T2) 27 | { 28 | if (T1 == NULL && T2 == NULL) 29 | return true; 30 | if (T1 == NULL || T2 == NULL) 31 | return false; 32 | if (T1->val != T2->val) 33 | return false; 34 | if (sameTree(T1->left,T2->left) && sameTree(T1->right,T2->right)) 35 | return true; 36 | return false; 37 | } 38 | ``` 39 | -------------------------------------------------------------------------------- /binaryTree/lint88-lowest-common-ancestor.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: lint88-lowest-common-ancestor 3 | tags: 在河之洲,算法,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | # problem 8 | 9 | [lint88-lowest-common-ancestor](http://www.lintcode.com/en/problem/lowest-common-ancestor/) 10 | # solution 11 | 先序递归法;自低向上 12 | ```cpp 13 | TreeNode *lowestCommonAncestor(TreeNode *root, TreeNode *A, TreeNode *B) { 14 | // write your code here 15 | bool findans = false; 16 | return findChild(root,A,B,findans); 17 | } 18 | TreeNode * findChild(TreeNode *root, TreeNode *A, TreeNode *B, bool &findAns) 19 | { 20 | if (root == NULL) 21 | return NULL; 22 | bool findRoot = false; 23 | if (root == A || root == B) 24 | { 25 | findAns = true; 26 | if (A==B) 27 | { 28 | return root; 29 | } 30 | findRoot = true; 31 | 32 | } 33 | bool leftAns = false, rightAns = false; 34 | TreeNode* leftRes = findChild(root->left,A,B,leftAns ) ; 35 | TreeNode* rightRes = findChild(root->right,A,B,rightAns) ; 36 | if (leftRes!=NULL || rightRes!=NULL) 37 | { 38 | findAns = true; 39 | return leftRes==NULL?rightRes:leftRes; 40 | } 41 | if (leftAns || rightAns ) 42 | { 43 | findAns = true; 44 | if (findRoot || leftAns&&rightAns) 45 | return root; 46 | } 47 | return NULL; 48 | } 49 | ``` -------------------------------------------------------------------------------- /binaryTree/readme.md: -------------------------------------------------------------------------------- 1 | 二叉树的一些操作 2 | 3 | # 前 中 后遍历 4 | 迭代法的循环情况是,给出访问当前节点的条件,然后访问当前节点,退栈,更新当前指针(后序要更新pre指针),如果不满足当前条件就push进子节点; -------------------------------------------------------------------------------- /bitMani/2017-3-7-lint82single-number.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 2017-3-7-lint82single-number 3 | tags: 在河之洲,算法,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # problem 9 | [82single-number/](http://www.lintcode.com/en/problem/single-number/) 10 | 11 | # solution 12 | 13 | ```cpp 14 | int singleNumber(vector &A) { 15 | // write your code here 16 | if (A.empty()) 17 | return 0; 18 | int result = A[0]; 19 | for (int i = 1; i < A.size(); i++) 20 | { 21 | result = result ^ A[i]; 22 | } 23 | return result; 24 | } 25 | ``` -------------------------------------------------------------------------------- /bitMani/2017-3-9-lint181-flip-bits.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 2017-3-9-lint181-flip-bits 3 | tags: 在河之洲,算法,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # problem 9 | 10 | [lint181-flip-bits](http://www.lintcode.com/en/problem/flip-bits/) 11 | # solution 12 | 13 | ```cpp 14 | int bitSwapRequired(int a, int b) { 15 | // write your code here 16 | int c = a ^ b; 17 | int sum = 0; 18 | for (int i = 0 ; i < 8 * sizeof(int); i++) 19 | { 20 | sum += ( c >> i ) & 1; 21 | } 22 | return sum; 23 | } 24 | ``` 25 | 26 | -------------------------------------------------------------------------------- /bitMani/96-Unique-Binary-Search-Trees.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 96-Unique-Binary-Search-Trees 3 | tags: 在河之洲,算法,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # problem 9 | [96-Unique-Binary-Search-Trees](https://leetcode.com/problems/unique-binary-search-trees/#/description) 10 | 11 | # solution 12 | 13 | ```cpp 14 | int numTrees(int n) { 15 | 16 | if (n <=2) 17 | return n; 18 | int sum = 0; 19 | sum = 2*numTrees(n-1); 20 | for (int i = 1; i < n - 1; i++) 21 | { 22 | sum = sum + numTrees(i) * numTrees(n -1 - i); 23 | } 24 | return sum; 25 | 26 | ``` 27 | 28 | # upgrade 29 | 这其实是一个卡特兰数,1,1,2,5,14,42 30 | `!$ \frac{1}{n+1}C_{n!}^{(2n)!} $` 31 | 32 | 其实应该使用正规的正态规划来做,使用状态转移方程。 33 | `!$ count[n] = \frac{4n-2}{n+1}*count[n-1] $` 34 | 35 | ```cpp 36 | int numTrees(int n) { 37 | long long nums[n+1]; 38 | memset(nums,0,sizeof(int)*(n+1)); 39 | nums[0] = 1; 40 | for (int i = 1; i <= n; i++) 41 | { 42 | nums[i] = nums[i-1]*(4*i-2)/(i+1); 43 | } 44 | return nums[n]; 45 | } 46 | ``` 47 | 48 | 使用这种时空复杂度都为O(n)的方法的前提是要知道它是卡特兰数。 49 | 50 | 如果不知道还是乖乖地使用一般的方法吧。 51 | `!$count[i] = \sum_{j=1}^{i-1}count[j]*count[j-1-i]$` 52 | 53 | ```cpp 54 | int numTrees(int n) { 55 | int nums[n+1]; 56 | memset(nums,0,sizeof(int)*(n+1)); 57 | nums[0] = 1; 58 | for (int i = 1; i <= n; i++) 59 | for (int j = 0; j < i; j++) 60 | { 61 | nums[i] += nums[j] * nums[i - 1 - j] ; 62 | } 63 | return nums[n]; 64 | } 65 | ``` 66 | 67 | -------------------------------------------------------------------------------- /bitMani/readme.md: -------------------------------------------------------------------------------- 1 | 位操作 2 | -------------------------------------------------------------------------------- /code_interview/360_2.md: -------------------------------------------------------------------------------- 1 | 视频面试,只是让我介绍简历 2 | -------------------------------------------------------------------------------- /code_interview/baidu_123.md: -------------------------------------------------------------------------------- 1 | 2017年8月10号百度IDL实验室面试经历。在百度科技园2号楼面试,在地铁16号线马连洼站出来口一路碰到的共享单车都是坏的,只好步行边走边问来到公司,没想到面的是IDL实验室。 2 | 3 | # 一面 4 | 是一个小员工面的,比较顺利,介绍了做的项目。描述了一下 googLenet和resnet的网络结构,做了两个题目 5 | 6 | 1. 写一个你熟悉的排序算法 7 | 8 | 害怕装逼遭雷劈,保险起见,我就写了冒泡排序 9 | 10 | 2. 在一个数组里找到所有的内组成三角形的三个数 11 | 12 | 挺简单 13 | 14 | 15 | # 二面 16 | 17 | 上面那个员工的leader面的,比较虐心的面试,刚开始开心地暖场让我放松了警惕,没想到这是噩梦的开始。 18 | 19 | 问MDNet为什么效果好,是怎么做输入的,问GoTurn,问FasterRCNN为什么快,问MobileNet为什么快,我竟然都没回答到点上,结果就很不好 20 | 21 | 22 | # 三面 23 | 比较和蔼,是上面那个leader的经理面的,问模型压缩优化有哪些方法,愿不愿意做paddle paddle, 是不是一定要做cv 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /code_interview/didi.cpp: -------------------------------------------------------------------------------- 1 | int GetUglyNumber_Solution2(int index) 2 | { 3 | if(index <= 0) 4 | return 0; 5 | 6 | int *pUglyNumbers = new int[index]; 7 | pUglyNumbers[0] = 1; 8 | int nextUglyIndex = 1; 9 | 10 | int *pMultiply2 = pUglyNumbers; 11 | int *pMultiply3 = pUglyNumbers; 12 | int *pMultiply5 = pUglyNumbers; 13 | 14 | while(nextUglyIndex < index) 15 | { 16 | int min = Min(*pMultiply2 * 2, *pMultiply3 * 3, *pMultiply5 * 5); 17 | pUglyNumbers[nextUglyIndex] = min; 18 | 19 | while(*pMultiply2 * 2 <= pUglyNumbers[nextUglyIndex]) 20 | ++pMultiply2; 21 | while(*pMultiply3 * 3 <= pUglyNumbers[nextUglyIndex]) 22 | ++pMultiply3; 23 | while(*pMultiply5 * 5 <= pUglyNumbers[nextUglyIndex]) 24 | ++pMultiply5; 25 | 26 | ++nextUglyIndex; 27 | } 28 | 29 | int ugly = pUglyNumbers[nextUglyIndex - 1]; 30 | delete[] pUglyNumbers; 31 | return ugly; 32 | } 33 | 34 | int Min(int number1, int number2, int number3) 35 | { 36 | int min = (number1 < number2) ? number1 : number2; 37 | min = (min < number3) ? min : number3; 38 | 39 | return min; 40 | } 41 | -------------------------------------------------------------------------------- /code_interview/disifanshi_23.md: -------------------------------------------------------------------------------- 1 | 第四范式在8月8日完成一面,在8月15日完成二面; 2 | 3 | 一面第一题是上台阶问题,刚开始用动态规划的递归的方法,后来想到可以用斐波那契额数列的循环的方法;第二题暂时想不起来了 4 | 5 | 二面三面都是高工面试,问了简历上面的很多问题。二面是算法面,三面是工程面,不知道为什么二面那个人总是说我做得太工程。 6 | 7 | 看来还是要对算法真的拿来用一用,可以自己实现一下哈 8 | -------------------------------------------------------------------------------- /code_interview/huanjushidai_1.md: -------------------------------------------------------------------------------- 1 | 2017年8月20日,欢聚时代1面 2 | 3 | 4 | 问了简历,希望早点过去实习 5 | -------------------------------------------------------------------------------- /code_interview/hypereal_1.md: -------------------------------------------------------------------------------- 1 | 2017年8月19日,hypereal笔试 2 | 3 | 1. 自己实现String类 4 | 5 | 2. 自己实现shared_ptr智能指针 6 | 7 | 8 | 3. 已知能等概率输出[0,3)的rand3函数,求实现rand5函数等概率输出[0,5) 9 | 10 | [随机数生成器](http://blog.csdn.net/yiqiangeliyou/article/details/46823595) 11 | 12 | 4. vector list, set, unordered_set,dequeue等的基本数据结构和操作的时间复杂度 13 | 14 | 15 | 16 | 5. 求菲波那切数列的第n个值 17 | 18 | 19 | 6. 矩阵中如果有一个元素为0,就将其所在行和列置0 20 | 21 | 22 | 7. 小矩阵A,大矩阵B求A在B中的位置。 23 | -------------------------------------------------------------------------------- /code_interview/kuaishou_1.md: -------------------------------------------------------------------------------- 1 | 快手有两个编程问题: 2 | 3 | 1. 给一个字符串和一个index,如何把index前面的部分挪到字符串末尾。 4 | 5 | 反转字符串 6 | 7 | 2. int a = 512; printf("%s",a); 8 | 9 | 结果会报segmentfault; 10 | 11 | 12 | -------------------------------------------------------------------------------- /code_interview/nvidia_1.md: -------------------------------------------------------------------------------- 1 | 我投的是英伟达的deep learning applycation software engineer, 一面是一个大叔打电话过来面的,介绍流程大致是 2 | online interview-> face to face interview-> american interview(也可能没有这一步)。,今天是一面。 3 | 4 | 一面一共有6道题目。 5 | 6 | 1. 不使用中间变量交换a和b的值。 7 | 暖场套路题,使用异或 加减法 两种方法都可以。 8 | 2. CNN的dropout有什么用,googLeNet这种没有dropout也可以是为什么? 9 | 10 | 3. 解释一下SVM(问题就是这么随意,最后纠结在核函数上面) 11 | 12 | 3.5. 突然开始问简历 13 | 14 | 15 | 4. outlier detection的方法有哪些? 16 | 17 | 18 | 5. 矩阵乘法怎么做呢?比如卷积操作是怎么计算的 19 | 20 | 21 | 6. 稀疏矩阵的存储方式有哪些,其中COO如何进一步压缩,如何使用并行和多线程的方式加速 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /code_interview/nvidia_23456.md: -------------------------------------------------------------------------------- 1 | 2017年8月21日,在朝阳区金台夕照站,不用出地铁站,进金融中心到1楼在前台办个临时证件,需要带身份证。我由于没带身份证所以是有人领我上去然后送我下来的。 2 | 3 | 从下午一点面到5点,NVIDIA的人都很Nice,每一面都会问我要不要喝水和上厕所。 4 | 5 | # 二面 6 | 7 | 二面说是我电话一面那个人。问的主要是机器学习的问题,涉及最大似然估计,LR的目标函数和损失函数,凸优化,还有就是一些距离公式,KNN,贝叶斯公式等 8 | 9 | [还有一个扑克起到大小王的概率问题](https://www.zhihu.com/question/28115076) 10 | 11 | # 三面 12 | 13 | 是个高瘦的人,问的比较快,都是比较简单的问题没什么印象了 14 | 15 | 16 | # 四面 17 | 18 | 是经理面,问了拿到的offer, 和做过的项目,有没有用caffe做模型的流程 19 | 20 | # 五面 21 | 22 | 这个比较顺利,最开始问 一个数组中有很多个数,但只有一个数是奇数的,求这个数是谁,我用异或来做,他问时间复杂度,我说O(n),让用并行,我就画了一个O(log n)的两种方法,问哪种方法数据处理比较快,我蒙了第二种对了。 23 | 24 | 然后问一个单链表如何在O(1)时间内删除一个元素。 25 | 26 | # 六面 27 | 28 | BP算法的反向传播,权值怎么更新,如何计算一个数的二进制里有多少个1,如何一行代码判断一个数是不是2 的幂。一个矩形中间有一个圆形的洞,如何把这个图案分成两块。 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /code_interview/pinduoduo_2.md: -------------------------------------------------------------------------------- 1 | 拼多多二面是一个非常难的题目,我在牛客网上看到好多人都以为是DP问题,结果做错了,其实是一个NP-hard问题。结果我自然也没做出来。 2 | ## 时间 3 | 4 | 大约是在7月26号面试的 5 | 6 | ## 题目 7 | 8 | 迷宫问题。一个二维矩阵,每个元素都是一个正数,从左上走到右下,只能向右走或者向下走,输入一个k,求路径和距离k最近的那个路径和。 9 | 10 | 11 | 最后想到的方法是使用全盘遍历的方法。 12 | -------------------------------------------------------------------------------- /code_interview/pinduoduo_3.md: -------------------------------------------------------------------------------- 1 | 有k个有序的数组,请找到一个最小的数字范围。使得这k个有序数组中,每个数组都至少有一个数字在该范围中 2 | 3 | [ 求k个数组包含每个数组至少一个元素的最小范围(待字闺中,备忘)](http://blog.csdn.net/wdxin1322/article/details/12970913) 4 | -------------------------------------------------------------------------------- /code_interview/readme.md: -------------------------------------------------------------------------------- 1 | 这里是面试中遇到的比较有意义的题目集锦 2 | 3 | 4 | BAT 5 | 6 | 360 7 | 8 | 第四范式 9 | 10 | 英伟达NVDIA 11 | 12 | 商汤科技 13 | 14 | 拼多多 15 | 16 | ULSee 17 | 18 | 华为诺亚方舟 19 | 20 | 21 | 欢聚时代yy语音 22 | 23 | 24 | hypereal 25 | 26 | 27 | -------------------------------------------------------------------------------- /code_interview/tencent.md: -------------------------------------------------------------------------------- 1 | [走格子/棋盘问题 有多少条路径可走](http://blog.csdn.net/yusiguyuan/article/details/12875415) 2 | 3 | 4 | 两个有序数组找公共元素 5 | -------------------------------------------------------------------------------- /code_interview/ulsee_2.md: -------------------------------------------------------------------------------- 1 | ulsee是我拿到的第一个offer,offer是在8月7号给的,二面是CTO面试,在8月6号。 2 | 3 | 大部分时间都在问简历和个人规划,问了两个题目 4 | 5 | ## 题目 6 | 7 | 1. 一行代码求两个矩阵的相交的面积 8 | 9 | 10 | 11 | 2. min_x (Ax-b)^2 s.t. 0 2 | using namespace std; 3 | /* 4 | n个骰子各个点数和出现的概率 5 | */ 6 | //n 为骰子个数 7 | int FindSum(int n) 8 | { 9 | int** array=NULL; 10 | array = new int*[n*6+1]; 11 | int i,j; 12 | for(i=0;i<6*n+1;i++) 13 | array[i] = new int[n+1]; 14 | for(j=0;j<=n;j++) 15 | { 16 | for(i=0;i<=n*6;i++) 17 | array[i][j] =0; 18 | 19 | } 20 | 21 | for(j=1;j<=n;j++) 22 | { 23 | for(i =j;i<=6*j;i++) 24 | { 25 | if(j == 1 || i == j || i == 6*j) 26 | array[i][j] = 1; 27 | else 28 | { 29 | int k = i-1; 30 | for(k = 1;k<=6;k++) 31 | if(i-k>= j-1) 32 | array[i][j] += array[i-k][j-1]; 33 | } 34 | } 35 | } 36 | 37 | for(j=1;j<=n;j++) 38 | { 39 | for(i=j;i<=6*j;i++) 40 | cout< &dq, int num) 14 | { 15 | while (!dq.empty() && num > dq.back()) 16 | dq.pop_back(); 17 | dq.push_back(num); 18 | } 19 | void pop(deque &dq, int num) 20 | { 21 | if (!dq.empty() && num == dq.front()) 22 | dq.pop_front(); 23 | } 24 | 25 | vector maxSlidingWindow(vector& nums, int k) { 26 | vector result; 27 | if (nums.empty() || nums.size() dq; 30 | for (int i = 0; i < k; i++) 31 | push(dq,nums[i]); 32 | 33 | result.push_back(dq.front()); 34 | for (int i = k; i < nums.size(); i++) 35 | { 36 | pop(dq,nums[i-k]); 37 | push(dq,nums[i]); 38 | result.push_back(dq.front()); 39 | } 40 | return result; 41 | 42 | } 43 | ``` 44 | 45 | 46 | # reference 47 | 48 | [九章算法](http://www.jiuzhang.com/solutions/sliding-window-maximum/) 49 | -------------------------------------------------------------------------------- /data-structure/lint12-min-stack.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: lint12-min-stack 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # problem 9 | 10 | [lint12-min-stack](http://www.lintcode.com/en/problem/min-stack/) 11 | # solution 12 | ```cpp 13 | class MinStack { 14 | public: 15 | stack stack1; 16 | stack stack2;//栈也只有在这种情况下,才能记录最值; 17 | MinStack() { 18 | // do initialization if necessary 19 | 20 | } 21 | 22 | void push(int number) { 23 | // write your code here 24 | stack1.push(number); 25 | if (stack2.empty() || number <= stack2.top()) 26 | stack2.push(number); 27 | } 28 | 29 | int pop() { 30 | // write your code here 31 | int top = stack1.top(); 32 | stack1.pop(); 33 | if (top == stack2.top()) 34 | stack2.pop(); 35 | return top; 36 | } 37 | 38 | int min() { 39 | // write your code here 40 | return stack2.top(); 41 | } 42 | }; 43 | 44 | 45 | ``` 46 | 47 | # reference 48 | [min_stack](https://algorithm.yuanbin.me/zh-hans/data_structure/min_stack.html) -------------------------------------------------------------------------------- /data-structure/lint40-implement-queue-by-two-stacks.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: lint40-implement-queue-by-two-stacks 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # problem 9 | [lint40-implement-queue-by-two-stacks](http://www.lintcode.com/en/problem/implement-queue-by-two-stacks/) 10 | # solution 11 | ```cpp 12 | class MyQueue { 13 | public: 14 | stack stack1; 15 | stack stack2; 16 | 17 | MyQueue() { 18 | // do intialization if necessary 19 | } 20 | 21 | void push(int element) { 22 | // write your code here 23 | stack1.push(element); 24 | } 25 | 26 | int pop() { 27 | // write your code here 28 | int temp = top(); 29 | stack2.pop(); 30 | return temp; 31 | } 32 | 33 | int top() { 34 | // write your code here 35 | if (stack2.size() == 0) 36 | { 37 | while(!stack1.empty()) 38 | { 39 | stack2.push(stack1.top() ); 40 | stack1.pop(); 41 | } 42 | } 43 | int temp = stack2.top(); 44 | return temp; 45 | } 46 | }; 47 | ``` -------------------------------------------------------------------------------- /data-structure/reame.md: -------------------------------------------------------------------------------- 1 | 这一部分是数据结构的题目 2 | 3 | # 双栈解决问题 4 | [lint12-min-stack](https://github.com/DragonFive/Leetcode/blob/master/data-structure/lint12-min-stack.md) 5 | 6 | [lint40-implement-queue-by-two-stacks](https://github.com/DragonFive/Leetcode/blob/master/data-structure/lint40-implement-queue-by-two-stacks.md) -------------------------------------------------------------------------------- /exhaustiveSearch/131-palindrome-partitioning.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 131-palindrome-partitioning 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # problem 9 | [131-palindrome-partitioning](https://leetcode.com/problems/palindrome-partitioning/#/description) 10 | 11 | # solution 12 | ``` 13 | vector> partition(string s) { 14 | vector> result; 15 | if (s.empty()) 16 | return result; 17 | if (s.size() == 1) 18 | { 19 | vector vec; 20 | vec.push_back(s); 21 | result.push_back(vec); 22 | return result; 23 | } 24 | //下面开始分端; 25 | for (int i = 1; i <= s.size(); i++) 26 | { 27 | if (!isPalindrome(s.substr(0, i)) ) 28 | continue; 29 | vector vec; 30 | vec.push_back(s.substr(0, i)); 31 | if (i == s.size()) 32 | { 33 | result.push_back(vec); 34 | break; 35 | } 36 | vector> rightStr = partition(s.substr(i, s.size()-i)); 37 | for (int j = 0; j < rightStr.size(); j++) 38 | { 39 | //合并当前的vec,与其中的每一个vector; 40 | vector vec2; 41 | vec2.insert(vec2.end(), vec.begin(),vec.end()); 42 | vec2.insert(vec2.end(), rightStr[j].begin(), rightStr[j].end()); 43 | result.push_back(vec2); 44 | } 45 | } 46 | return result; 47 | } 48 | bool isPalindrome(string s) 49 | { 50 | for (int i =0; i < s.size()/2 + 1; i++) 51 | { 52 | if (s[i] != s[s.size() - i - 1]) 53 | return false; 54 | } 55 | return true; 56 | } 57 | ``` 58 | 59 | # reference 60 | -------------------------------------------------------------------------------- /exhaustiveSearch/31-next-permutation.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 31-next-permutation 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # problem 9 | 10 | [31-next-permutation](https://leetcode.com/problems/next-permutation/#/description) 11 | # solution 12 | 13 | ``` 14 | void nextPermutation(vector& nums) { 15 | if (nums.empty() || nums.size() == 1) 16 | return; 17 | //找到最长降序后缀; 18 | int i = nums.size() - 2; 19 | for (; i >=0; i--) 20 | if (nums[i] < nums[i+1]) 21 | break; 22 | if (i == -1) 23 | { 24 | //重新排列,然后继续; 25 | sort(nums.begin(), nums.end()); 26 | return; 27 | } 28 | //找到第一个比哨兵大的元素; 29 | int j = nums.size() - 1; 30 | for (; j > i; j--) 31 | if (nums[j] > nums[i]) 32 | break; 33 | //交换 34 | int temp = nums[i]; 35 | nums[i] = nums[j]; 36 | nums[j] = temp; 37 | //reverse; 38 | reverse(nums.begin() + i +1, nums.end()); 39 | 40 | 41 | } 42 | ``` 43 | 44 | # reference -------------------------------------------------------------------------------- /exhaustiveSearch/39-combination-sum.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 39-combination-sum 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # problem 9 | [39-combination-sum](https://leetcode.com/problems/combination-sum/#/description) 10 | 11 | # solution 12 | ``` 13 | vector> combinationSum(vector& candidates, int target) { 14 | vector > result; 15 | if (candidates.empty()) 16 | return result; 17 | vector list; 18 | dfs(candidates, target, list, result, 0, 0); 19 | return result; 20 | } 21 | void dfs(vector &cand, int target, vector &list, vector > &res, int start, int sums) 22 | { 23 | if (sums == target) 24 | { 25 | res.push_back(list); 26 | return; 27 | } 28 | if (sums > target) 29 | return; 30 | for (int i = start; i < cand.size(); i++) 31 | { 32 | list.push_back(cand[i]); 33 | sums += cand[i]; 34 | dfs(cand, target, list, res, i, sums); 35 | sums -= cand[i]; 36 | list.pop_back(); 37 | } 38 | return; 39 | } 40 | ``` -------------------------------------------------------------------------------- /exhaustiveSearch/40-combination-sum-ii.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 40-combination-sum-ii 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # problem 9 | [40-combination-sum-ii](https://leetcode.com/problems/combination-sum-ii/#/description) 10 | # solution 11 | ``` 12 | vector> combinationSum2(vector& candidates, int target) { 13 | vector > result; 14 | if (candidates.empty()) 15 | return result; 16 | vector list; 17 | sort(candidates.begin(), candidates.end()); 18 | dfs(candidates, target, list, result, 0, 0); 19 | return result; 20 | } 21 | void dfs(vector &cand, int target, vector &list, vector > &res, int pos, int sums) 22 | { 23 | if (sums == target) 24 | { 25 | res.push_back(list); 26 | return; 27 | } 28 | if (sums > target || pos >= cand.size()) 29 | return; 30 | for (int i = pos; i < cand.size();) 31 | { 32 | 33 | list.push_back(cand[i]); 34 | sums += cand[i]; 35 | dfs(cand, target, list, res, i+1, sums); 36 | sums -= cand[i]; 37 | list.pop_back(); 38 | i++; 39 | while (cand[i] == cand[i-1] && i < cand.size()) 40 | i++; 41 | } 42 | } 43 | ``` 44 | 45 | # reference 46 | -------------------------------------------------------------------------------- /exhaustiveSearch/47-permutations-ii.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 47-permutations-ii 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # problem 9 | 10 | [47-permutations-ii(https://leetcode.com/problems/permutations-ii/#/description) 11 | 12 | # solution 13 | ## 回溯法+剪枝 14 | ``` 15 | vector> permuteUnique(vector& nums) { 16 | vector> result; 17 | if (nums.empty()) 18 | return result; 19 | vector visited(nums.size(), false); 20 | vector list; 21 | 22 | sort(nums.begin(),nums.end()); 23 | backTracking(nums, list, visited, result); 24 | return result; 25 | } 26 | void backTracking(vector &nums, vector &list, vector &visited, vector> &result) 27 | { 28 | if (list.size() == nums.size()) 29 | { 30 | result.push_back(list); 31 | return; 32 | } 33 | for (int i = 0; i < nums.size(); i++) 34 | { 35 | //下面进行剪枝干; 36 | if (visited[i] || (i!=0 && nums[i] == nums[i-1] && !visited[i-1])) 37 | continue; 38 | visited[i] = true; 39 | list.push_back(nums[i]); 40 | backTracking(nums, list, visited, result); 41 | list.pop_back(); 42 | visited[i] = false; 43 | } 44 | } 45 | ``` 46 | ## 字典序法 47 | 参见46-permutations 48 | # reference -------------------------------------------------------------------------------- /exhaustiveSearch/51-previous-permutation.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: lint-51-previous-permutation 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # problem 9 | [51-previous-permutation](http://www.lintcode.com/en/problem/previous-permutation/) 10 | 11 | # solution 12 | 13 | ``` 14 | vector previousPermuation(vector &nums) { 15 | // write your code here 16 | vector res = nums; 17 | if (nums.empty() || nums.size() == 1) 18 | return res; 19 | 20 | int i = res.size() - 2; 21 | for (; i >= 0; i--) 22 | if (res[i] > res[i+1]) 23 | break; 24 | if (i == -1) 25 | { 26 | reverse(res.begin(), res.end()); 27 | return res; 28 | } 29 | //找到置换元素; 30 | int j = res.size() -1 ; 31 | for (; j > i; j--) 32 | if (res[j] < res[i]) 33 | break; 34 | //jiaohuan 35 | int temp = res[i]; 36 | res[i] = res[j]; 37 | res[j] = temp; 38 | 39 | //reverse; 40 | reverse(res.begin()+i+1, res.end()); 41 | return res; 42 | } 43 | ``` 44 | 45 | # reference 46 | -------------------------------------------------------------------------------- /exhaustiveSearch/60-permutation-sequence.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 60-permutation-sequence 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # problem 9 | [60-permutation-sequence](https://leetcode.com/problems/permutation-sequence/#/description) 10 | 11 | ## similiar problem 12 | 13 | [lint197-Permutatio- Index.md](https://github.com/DragonFive/Leetcode/blob/master/exhaustiveSearch/lint197-Permutatio-%20Index.md) 14 | 15 | [lint198-permutation-index-ii](https://github.com/DragonFive/Leetcode/blob/master/exhaustiveSearch/lint198-permutation-index-ii.md) 16 | 17 | # solution 18 | 19 | ``` 20 | string getPermutation(int n, int k) { 21 | //首先缓存所有的结果 22 | vector factorial = vector(n+1, 1); 23 | for (int i = 1; i < n+1; i++) 24 | factorial[i] = factorial[i-1]*i; 25 | 26 | vector perm; 27 | vector nums; 28 | for (int i = 1; i < n+1; i++) 29 | nums.push_back(i); 30 | //然后循环计算每一个位置上的数值 31 | for (int i = 0; i < n; i++) 32 | { 33 | int rank = (k - 1) / factorial[n -i - 1]; 34 | k = (k - 1) % factorial[n - i - 1] + 1; 35 | //找到第rank个元素; 36 | perm.push_back(nums[rank]); 37 | nums.erase(nums.begin() + rank); 38 | } 39 | stringstream result; 40 | copy(perm.begin(), perm.end(), ostream_iterator(result,"")); 41 | return result.str(); 42 | } 43 | ``` 44 | ## code analysis 45 | ``` 46 | stringstream result; 47 | copy(perm.begin(), perm.end(), ostream_iterator(result,"")); 48 | ``` 49 | 很聪明的做法, ostream_iteator是输出迭代器,构造函数第一个参数是指向一个输出到stream 如cout等,第二个参数表示两个元素之间到分界。 50 | [ostream_iterator](http://www.cplusplus.com/reference/iterator/ostream_iterator/ostream_iterator/) 51 | # reference 52 | 53 | [Permutation Sequence 解题报告](http://blog.sina.com.cn/s/blog_eb52001d0102v1ss.html) 54 | 55 | [stackoverflow-how-to-transform-a-vectorint-into-a-string](http://stackoverflow.com/questions/2518979/how-to-transform-a-vectorint-into-a-string) 56 | -------------------------------------------------------------------------------- /exhaustiveSearch/77-combinations.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 77-combinations 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # problem 9 | 10 | [77-combinations](https://leetcode.com/problems/combinations/#/description) 11 | 12 | 13 | # solution 14 | ## 使用返回+全盘便利的方法 这种方法其实只是在二岔树的时候比较好用 15 | ``` 16 | vector > combine(int n, int k) { 17 | //要么循环,要么递归,可以先用递归. 18 | return helper(1, n, k); 19 | } 20 | vector > helper(int start, int n, int k) 21 | { 22 | vector > result; 23 | if (start > n || k <= 0) 24 | return result; 25 | if (start == n && k == 1) 26 | { 27 | vector vec; 28 | vec.push_back(start); 29 | result.push_back(vec); 30 | return result; 31 | } 32 | for (int j = start; j <= n - k + 1; j++) 33 | { 34 | vector > rightRes = helper(j + 1, n, k - 1); 35 | if (rightRes.empty()) 36 | { 37 | vector vec; 38 | vec.push_back(j); 39 | result.push_back(vec); 40 | } 41 | for (int i = 0; i < rightRes.size(); i++) 42 | { 43 | vector vec; 44 | vec.push_back(j); 45 | vec.insert(vec.end(), rightRes[i].begin(), rightRes[i].end()); 46 | result.push_back(vec); 47 | } 48 | } 49 | return result; 50 | } 51 | ``` 52 | 53 | ## 使用subset的模板 54 | 55 | ``` 56 | vector > combine(int n, int k) { 57 | //要么循环,要么递归,可以先用递归. 58 | vector > result; 59 | if (k == 0 || n < k) 60 | return result; 61 | vector list; 62 | dfs(1, n, k, list, result); 63 | return result; 64 | } 65 | void dfs(int start, int n, int k, vector &list, vector > &res) 66 | { 67 | if (list.size() == k) 68 | { 69 | res.push_back(list); 70 | return; 71 | } 72 | //下面开始访问当前的节点; 73 | for (int i = start; i <= n - k + list.size() + 1; i++) 74 | { 75 | list.push_back(i); 76 | dfs( i + 1, n, k, list, res ); 77 | list.pop_back(); 78 | } 79 | return; 80 | } 81 | ``` 82 | 83 | # reference 84 | 85 | 86 | [combinations](https://algorithm.yuanbin.me/zh-hans/exhaustive_search/combinations.html) -------------------------------------------------------------------------------- /exhaustiveSearch/79-word-search.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 79-word-search 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # problem 9 | 10 | [79-word-search](https://leetcode.com/problems/word-search/#/description) 11 | # solution 12 | 13 | ``` 14 | bool exist(vector>& board, string word) { 15 | if (board.empty()) 16 | return false; 17 | if (word.empty()) 18 | return true; 19 | vector > visited(board.size() , vector(board[0].size(), false) ); 20 | //寻找下一个可能的点; 21 | for (int i = 0; i < board.size(); i++) 22 | { 23 | for (int j = 0; j < board[0].size(); j++) 24 | { 25 | if (dfs(board, word, i, j ,visited, 0)) 26 | return true; 27 | } 28 | } 29 | return false; 30 | 31 | } 32 | bool dfs(vector>& board, string word, int row, int col, vector > &visited, int ind) 33 | { 34 | 35 | //从row和col找第一个元素,找不到就返回false; 36 | if (visited[row][col] == false && board[row][col] == word[ind]) 37 | { 38 | if (word.size() - 1 == ind) 39 | return true; 40 | visited[row][col] = true; 41 | //下面开始递归; 42 | if (col > 0 && dfs(board, word, row, col-1, visited, ind+1) ) 43 | return true; 44 | if (col < board[0].size()-1 && dfs(board, word, row, col+1, visited, ind+1) ) 45 | return true; 46 | if (row > 0 && dfs(board, word, row-1, col, visited, ind+1) ) 47 | return true; 48 | if (row < board.size()-1 && dfs(board, word, row+1, col, visited, ind+1) ) 49 | return true; 50 | visited[row][col] = false; 51 | } 52 | return false; 53 | 54 | } 55 | ``` 56 | 57 | # reference -------------------------------------------------------------------------------- /exhaustiveSearch/90-subsets-ii.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 90-subsets-ii 3 | tags: 在河之洲,算法,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | # problem 8 | 9 | [90-subsets-ii](https://leetcode.com/problems/subsets-ii/#/description) 10 | 求一个集合的不重复的子集。 11 | 本题是[78-subsets](https://github.com/DragonFive/Leetcode/blob/master/exhaustiveSearch/78-subsets.md)的变形。 12 | 13 | # solution 14 | ``` 15 | vector> subsetsWithDup(vector& nums) { 16 | vector> result; 17 | if (nums.empty()) 18 | return result; 19 | set> tmp; 20 | vector list; 21 | sort(nums.begin(),nums.end()); 22 | dfs(nums, result, 0, list, tmp); 23 | return result; 24 | } 25 | void dfs(vector & nums, vector> & result, int k, vector &list, set> &tmp) 26 | { 27 | //判断list,是否已经有了; 28 | if (tmp.find(list) != tmp.end()) 29 | return; 30 | result.push_back(list); 31 | tmp.insert(list); 32 | for (int i = k ; i < nums.size(); i++) 33 | { 34 | list.push_back(nums[i]); 35 | dfs(nums, result, i+1, list, tmp); 36 | list.pop_back(); 37 | } 38 | } 39 | ``` 40 | -------------------------------------------------------------------------------- /exhaustiveSearch/95-unique-binary-search-trees-ii.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 95-unique-binary-search-trees-ii 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | # problem 7 | [95-unique-binary-search-trees-ii](https://leetcode.com/problems/unique-binary-search-trees-ii/#/description) 8 | ## similiar problem 9 | 10 | [96-Unique-Binary-Search-Trees](https://github.com/DragonFive/Leetcode/blob/master/bitMani/96-Unique-Binary-Search-Trees.md) 11 | 12 | # solution 13 | 14 | ``` 15 | vector generateTrees(int n) { 16 | vector result; 17 | if (n == 0) 18 | return result; 19 | return helper(1, n); 20 | } 21 | vector helper(int start, int end) 22 | { 23 | vector result; 24 | if (start > end) 25 | { 26 | result.push_back(NULL); 27 | return result; 28 | } 29 | for (int i = start; i <= end; i++) 30 | { 31 | //把每个节点当作根节点来用一用; 32 | vector leftTree = helper(start, i-1); 33 | vector rightTree = helper(i+1, end); 34 | //把左右子树进行配对 35 | for (int j = 0; j < leftTree.size(); j++) 36 | { 37 | for (int k =0; k < rightTree.size(); k++) 38 | { 39 | TreeNode *root = new TreeNode(i); 40 | root->left = leftTree[j]; 41 | root->right = rightTree[k]; 42 | result.push_back(root); 43 | } 44 | } 45 | } 46 | return result; 47 | } 48 | ``` 49 | 50 | # reference 51 | [unique_binary_search_trees_ii](https://algorithm.yuanbin.me/zh-hans/exhaustive_search/unique_binary_search_trees_ii.html) -------------------------------------------------------------------------------- /exhaustiveSearch/lint197-Permutatio- Index.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: lint197-Permutatio- Index 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | # source 8 | 9 | [lint197-Permutatio- Index](http://www.lintcode.com/en/problem/permutation-index/) 10 | 11 | 12 | 13 | # solution 14 | ``` 15 | long long permutationIndex(vector& A) { 16 | // Write your code here 17 | if (A.empty()) 18 | return 0; 19 | long long factor = 1; 20 | //遍历所有的位数; 21 | long long result = 1; 22 | for (int i = A.size() - 1; i >= 0; i--) 23 | { 24 | long long rank = 0; 25 | for (int j = i + 1; j < A.size(); j++) 26 | if (A[i] > A[j]) 27 | rank++ ; 28 | result += rank * factor; 29 | factor *= (A.size() - i); 30 | } 31 | return result; 32 | } 33 | ``` 34 | ## code analysis 35 | 36 | 双重for循环,时间复杂度位 $ O(n^2) $ ,空间复杂度位$ O(1) $ . 37 | 38 | 39 | # reference 40 | 41 | [permutation_index](https://algorithm.yuanbin.me/zh-hans/exhaustive_search/permutation_index.html) -------------------------------------------------------------------------------- /exhaustiveSearch/lint198-permutation-index-ii.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: lint198-permutation-index-ii 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # source 9 | [lint198-permutation-index-ii](http://www.lintcode.com/en/problem/permutation-index-ii/) 10 | 这里需要考虑重复元素,有无重复元素最大的区别在于原来的1!, 2!, 3!...等需要除以重复元素个数的阶乘,颇有点高中排列组合题的味道。 11 | [lint197-permutation-index](https://github.com/DragonFive/Leetcode/blob/master/exhaustiveSearch/lint197-Permutatio-%20Index.md) 12 | # solution 13 | 14 | ``` 15 | long long permutationIndexII(vector& A) { 16 | // Write your code here 17 | if (A.empty()) 18 | return 0; 19 | long long result = 1, factor = 1, res = 1; 20 | unordered_map sameNum; 21 | for (long long i = A.size() -1 ; i >= 0 ; i--) 22 | { 23 | long long rank = 0; 24 | for (long long j = i+1; j < A.size(); j++) 25 | { 26 | if (A[i] > A[j]) 27 | rank++; 28 | } 29 | for (long long j = i+1; j < A.size(); j++) 30 | //同时要记录有多少个重复到数字出现; 31 | if (A[i] == A[j]) 32 | { 33 | if (sameNum.find(A[i]) == sameNum.end() ) 34 | { 35 | sameNum[A[i]] = 2; 36 | res *= 2; 37 | } 38 | else 39 | res *= (++sameNum[A[i]]); 40 | break; 41 | } 42 | result += rank * factor / res; 43 | factor *= (A.size() - i); 44 | 45 | } 46 | return result; 47 | } 48 | ``` 49 | # reference 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /exhaustiveSearch/readme.md: -------------------------------------------------------------------------------- 1 | 2 | # Exhaustive Search - 穷竭搜索 3 | 4 | 常用的求解工具:递归、栈、队列 5 | 常用的求解办法:DFS(回溯法)、BFS 6 | 7 | ## DFS 8 | DFS从某个**状态**开始,根据特定的规则**转移状态**,直至无法转移(节点为空),然后回退到之前一步状态,继续按照指定规则转移状态,直至遍历完所有状态。 9 | 以深度优先方式搜索解空间,并在搜索过程中用**剪枝函数**避免无效搜索。 10 | 11 | **回溯法**包含了多类问题,模板类似。 12 | **排列组合模板->搜索问题** 13 | 14 | ## BFS 15 | 16 | BFS 从某个状态开始,搜索所有可以到达的状态,转移顺序为:初始状态->只需一次转移就可到达的所有状态->只需两次转移就可到达的所有状态->...,所以对于同一个状态,BFS 只搜索一次,故**时间复杂度**为 $ O(states \times transfer\_methods)$. BFS 通常**配合队列**一起使用,搜索时先将状态加入到队列中,然后从队列顶端不断取出状态,再把从该状态可转移到的状态中尚未访问过的部分加入队列,直到队列为空或已找到解。因此 BFS 适合用于『由近及远』的搜索,比较适合用于**求解最短路径、最少操作**之类的问题 17 | 18 | -------------------------------------------------------------------------------- /graph/lint127-topological-sorting.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: lint127-topological-sorting 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # problem 9 | [lint127-topological-sorting](http://www.lintcode.com/en/problem/topological-sorting/#) 10 | 11 | 这个问题最大的点在于图可能有两个根节点。 12 | 13 | # solution 14 | ```cpp 15 | vector topSort(vector graph) { 16 | // write your code here 17 | vector result; 18 | if (graph.empty()) 19 | return result; 20 | //统计入度,找到没有指向的点作为根; 21 | unordered_map in_degree; 22 | for (int i = 0; i < graph.size();i++) 23 | { 24 | int neighbor_size = graph[i]->neighbors.size(); 25 | for (int j = 0; j < neighbor_size; j++) 26 | { 27 | if ( in_degree.find(graph[i]->neighbors[j]) == in_degree.end() ) 28 | in_degree[graph[i]->neighbors[j]] = 1; 29 | else 30 | in_degree[graph[i]->neighbors[j]] += 1; 31 | } 32 | } 33 | //找到不在map里面的那些点; 34 | queue q; 35 | DirectedGraphNode * root = NULL; 36 | for (int i = 0; i < graph.size(); i++) 37 | { 38 | if (in_degree.find(graph[i]) == in_degree.end()) 39 | { 40 | root = graph[i]; 41 | in_degree[root] = 0; 42 | q.push(root); 43 | } 44 | } 45 | if (root == NULL) 46 | return result; 47 | //下面开始bfs,定各个节点的深度; 48 | 49 | 50 | while (!q.empty()) 51 | { 52 | DirectedGraphNode * cur_node = q.front(); 53 | q.pop(); 54 | result.push_back(cur_node); 55 | //访问cur_node的所有邻居;并且push; 56 | int nghb_size = cur_node->neighbors.size(); 57 | for (int i = 0; i < nghb_size; i++) 58 | { 59 | 60 | in_degree[cur_node->neighbors[i] ] -= 1; 61 | if (in_degree[cur_node->neighbors[i] ] == 0) 62 | q.push(cur_node->neighbors[i]); 63 | } 64 | } 65 | return result; 66 | } 67 | ``` 68 | 69 | # reference 70 | 71 | [C++ STL中Map的按Key排序和按Value排序](http://blog.csdn.net/iicy266/article/details/11906189) 72 | 73 | [拓扑排序](https://algorithm.yuanbin.me/zh-hans/graph/topological_sorting.html) -------------------------------------------------------------------------------- /graph/lint127-word-ladder.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: lint127-word-ladder 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # problem 9 | [lint127-word-ladder](https://leetcode.com/problems/word-ladder/#/description) 10 | 11 | # solution 12 | 13 | ## dfs 14 | ```cpp 15 | int ladderLength(string beginWord, string endWord, vector& wordList) { 16 | if (wordList.empty()) 17 | return -1; 18 | if (beginWord == endWord) 19 | return 0; 20 | //下面开始计算步数; 21 | vector visited(wordList.size(), false); 22 | //先去掉字典中与beginWord一样的元素; 23 | for (int i = 0 ; i < wordList.size(); i++) 24 | if (beginWord == wordList[i]) 25 | visited[i] = true; 26 | int len = dfs(beginWord, endWord, visited, wordList); 27 | if (len > wordList.size()+1) 28 | return 0; 29 | return len; 30 | 31 | } 32 | 33 | int dfs(string beginWord, string endWord, vector &visited, vector& wordList) 34 | { 35 | if (beginWord == endWord) 36 | return 1; 37 | //遍历wordList中没有visited过的元素; 38 | int res = wordList.size()+1; 39 | for (int i = 0; i < wordList.size(); i++) 40 | { 41 | if (visited[i] == true) 42 | continue; 43 | //判断一步可达; 44 | int diff = 0; 45 | for (int j = 0; j < beginWord.length(); j++) 46 | if (beginWord[j] != wordList[i][j]) 47 | diff++; 48 | if (diff != 1) 49 | continue; 50 | visited[i] = true; 51 | res = min(res, dfs(wordList[i], endWord, visited, wordList)); 52 | visited[i] = false; 53 | } 54 | return res+1; 55 | } 56 | ``` 57 | 58 | ### code analysis 59 | 深度优先搜索,需要剪枝防止图中环的存在,但这里还是出现了超时 60 | 61 | 62 | ## bfs 63 | 64 | ```cpp 65 | int ladderLength(string beginWord, string endWord, vector& wordList) { 66 | if (wordList.empty()) 67 | return -1; 68 | if (beginWord == endWord) 69 | return 0; 70 | vector visited(wordList.size(), false); 71 | //先去掉字典中与beginWord一样的元素; 72 | for (int i = 0 ; i < wordList.size();i++) 73 | if (wordList[i] == beginWord) 74 | visited[i] = true; 75 | int len = bfs(beginWord, endWord, visited, wordList); 76 | if (len > wordList.size()+1) 77 | return 0; 78 | return len; 79 | 80 | } 81 | 82 | int bfs(string beginWord, string endWord, vector &visited, vector& wordList) 83 | { 84 | if (beginWord == endWord) 85 | return 1; 86 | //遍历wordList中没有visited过的元素; 87 | int res = 0; 88 | queue q; 89 | q.push(beginWord); 90 | while (!q.empty()) 91 | { 92 | int len = q.size(); 93 | 94 | for (int i = 0 ; i < len; i++) 95 | { 96 | string beginWord = q.front(); 97 | q.pop(); 98 | if (beginWord == endWord) 99 | { 100 | return res+1; 101 | } 102 | //把这个节点的所有后续节点加入里面; 103 | for (int j = 0 ; j < wordList.size(); j++) 104 | { 105 | if (visited[j] == true) 106 | continue; 107 | int diff = 0; 108 | for (int k = 0; k < beginWord.length(); k++) 109 | if (beginWord[k] != wordList[j][k]) 110 | diff++; 111 | if (diff != 1) 112 | continue; 113 | q.push(wordList[j]); 114 | visited[j] = true; 115 | } 116 | } 117 | res++; 118 | } 119 | 120 | return 0; 121 | } 122 | ``` 123 | -------------------------------------------------------------------------------- /graph/lint176-route-between-two-nodes-in-graph.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: lint176-route-between-two-nodes-in-graph 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # problem 9 | [lint176-route-between-two-nodes-in-graph](http://www.lintcode.com/en/problem/route-between-two-nodes-in-graph/) 10 | 11 | # solution 12 | 13 | ## dfs 14 | 图的问题为避免环的存在需要标记一个节点是否访问过。 15 | 16 | ```cpp 17 | bool hasRoute(vector graph, 18 | DirectedGraphNode* s, DirectedGraphNode* t) { 19 | // write your code here 20 | if (graph.empty()) 21 | return false; 22 | unordered_set visited;//记录某个点有没有visited过; 23 | return dfs(graph,visited,s,t); 24 | } 25 | bool dfs(vector graph,unordered_set visited, 26 | DirectedGraphNode* s, DirectedGraphNode* t){ 27 | if (s == t) 28 | return true; 29 | vector ng = s->neighbors; 30 | visited.insert(s); 31 | int i = 0; 32 | for (; i < ng.size(); i++) 33 | { 34 | if (visited.find(ng[i])!=visited.end())//访问过当前节点; 35 | continue; 36 | if (dfs(graph, visited, ng[i], t) == true) 37 | break; 38 | } 39 | if (i == ng.size()) 40 | return false; 41 | else 42 | return true; 43 | } 44 | ``` 45 | ### code analysis 46 | 时间复杂度为O(V+E), 空间复杂度为O(V). 但是因为使用来递归来处理,所以会爆栈,可以尝试使用栈结构来处理。估计内存使用量差不多 47 | 48 | 49 | ## bfs 50 | 除了深搜处理邻居节点,我们也可以采用 BFS 结合队列处理,优点是不会爆栈,缺点是空间复杂度稍高和实现复杂点。 51 | 52 | 53 | ```cpp 54 | bool hasRoute(vector graph, 55 | DirectedGraphNode* s, DirectedGraphNode* t) { 56 | // write your code here 57 | if (graph.empty()) 58 | return false; 59 | unordered_set visited;//记录某个点有没有visited过; 60 | 61 | //vector ng = s->neighbors; 62 | 63 | queue nodeq; 64 | nodeq.push(s); 65 | while (!nodeq.empty()) 66 | { 67 | DirectedGraphNode* pos = nodeq.front(); 68 | nodeq.pop(); 69 | visited.insert(pos); 70 | if (pos == t) 71 | return true; 72 | vector ng = pos->neighbors; 73 | for (int i = 0; i < ng.size(); i++) 74 | { 75 | if (visited.find(ng[i]) != visited.end() ) 76 | continue; 77 | nodeq.push(ng[i]); 78 | } 79 | } 80 | return false; 81 | 82 | } 83 | ``` 84 | 85 | -------------------------------------------------------------------------------- /graph/readme.md: -------------------------------------------------------------------------------- 1 | **图搜索的问题** 2 | 3 | 检测图中两点是否通路,图搜索的简单问题,DFS 或者 BFS 均可,注意检查是否有环即可。这里使用哈希表记录节点是否被处理较为方便 4 | 5 | 6 | **拓扑排序** 7 | 8 | [拓扑排序](https://algorithm.yuanbin.me/zh-hans/graph/topological_sorting.html) -------------------------------------------------------------------------------- /improve_sort_algorithm/improve_fast_sort.md: -------------------------------------------------------------------------------- 1 | # 代码 2 | 3 | ```cpp 4 | 5 | #include 6 | #include 7 | using namespace std; 8 | 9 | //交换操作 10 | void Swap(int &a,int &b) 11 | { 12 | int temp = a; 13 | a = b; 14 | b = temp; 15 | } 16 | 17 | //标准的快排方法 18 | int partion(int a[],int left,int right)//首先进行分区操作 19 | { 20 | int flag = a[left];//将首元素当作标杆,选择最右边元素最为标杆时代码会有略微不同 21 | int j = left; 22 | for (int i = left+1; i <= right; ++i)//首先忽略首元素 23 | { 24 | if (a[i] < flag) 25 | { 26 | j++; 27 | if ( j != i) 28 | { 29 | Swap(a[i],a[j]);//将标杆数一直往右移动,遇到比标杆数小的就交换到从头开始的位置上 30 | } 31 | } 32 | } 33 | Swap(a[j],a[left]);//j位置的元素和首元素互换,即可保证标杆元素左边为小于等于,右边为大于等于 34 | return j; 35 | } 36 | 37 | //取区间内随机数的函数 38 | int Rand(int low, int high) 39 | { 40 | int size = high - low + 1; 41 | return low + rand()%size; 42 | } 43 | int partion1(int a[],int left,int right)//首先进行分区操作 44 | { 45 | Swap(a[Rand(left,right)],a[left]);//随机选择区间的一个数,将其与首元素进行交换 46 | int flag = a[left];//将首元素当作标杆 47 | int j = left; 48 | for (int i = left+1; i <= right; ++i)//首先忽略首元素 49 | { 50 | if (a[i] < flag) 51 | { 52 | j++; 53 | if ( j != i) 54 | { 55 | Swap(a[i],a[j]);//将标杆数一直往右移动,遇到比标杆数小的就交换到从头开始的位置上 56 | } 57 | } 58 | } 59 | Swap(a[j],a[left]);//j位置的元素和首元素互换,即可保证标杆元素左边为小于等于,右边为大于等于 60 | return j; 61 | } 62 | 63 | //标准递归版本的快速排序 64 | void Fast_sort(int a[],int left,int right) 65 | { 66 | if (left < right) 67 | { 68 | int index = partion1(a,left,right);//partion也可以 69 | Fast_sort(a,left,index-1); 70 | Fast_sort(a,index+1,right); 71 | } 72 | } 73 | 74 | int main(int argc, char **argv) 75 | { 76 | int a[10] = {12,45,748,12,56,3,89,4,48,2}; 77 | 78 | Fast_sort(a,0,9); 79 | for (size_t i = 0; i != 10; ++i) 80 | { 81 | cout< twoSum(vector &nums, int target) { 21 | // write your code here 22 | unordered_map numsIndexMap; 23 | const int size = nums.size(); 24 | vector ret; 25 | // 建立哈希表 26 | for (int i = 0; i < size; ++i) 27 | { 28 | numsIndexMap[nums[i]] = i + 1; 29 | } 30 | // 寻找配对 31 | for (int i = 0; i < size; i++) 32 | if (numsIndexMap.find(target - nums[i]) != numsIndexMap.end() && i != numsIndexMap[target - nums[i]]) 33 | { 34 | ret.push_back(i + 1); 35 | ret.push_back(numsIndexMap[target - nums[i]]); 36 | break; 37 | } 38 | return ret; 39 | 40 | } 41 | ``` 42 | 43 | 其实上面先建哈希表再用的方式并不好 44 | 45 | ```cpp 46 | vector twoSum(vector &nums, int target) { 47 | // write your code here 48 | unordered_map numsIndexMap; 49 | const int size = nums.size(); 50 | vector ret; 51 | // 建立哈希表 52 | for (int i = 0; i < size; i++) 53 | { 54 | if (numsIndexMap.find(target - nums[i]) != numsIndexMap.end()) 55 | { 56 | ret.push_back(numsIndexMap[target - nums[i] ] ); 57 | ret.push_back(i); 58 | break; 59 | } 60 | else 61 | { 62 | numsIndexMap[nums[i] ] = i; 63 | } 64 | } 65 | return ret; 66 | 67 | } 68 | 69 | ``` 70 | 71 | 也可以使用先排序然后使用两根指针的方法,但是这种方法的空间复杂度其实是比较大的 72 | 73 | -------------------------------------------------------------------------------- /integer-arr/16-3Sum-Closest.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 16-3Sum-Closest 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | # problem 8 | 9 | 10 | [16. 3Sum Closest](https://leetcode.com/problems/3sum-closest/) 11 | 12 | 13 | ## similar problem 14 | 15 | [lintcode 57 3Sum Closest](http://www.lintcode.com/en/problem/3sum-closest/) 16 | 17 | 18 | # solution 19 | 20 | ## 排序+两根指针法 21 | 22 | ```cpp 23 | int threeSumClosest(vector& nums, int target) { 24 | if (nums.empty() || nums.size() < 3) 25 | return -1; 26 | sort(nums.begin(), nums.end()); 27 | int result = nums[0] + nums[1] + nums[2]; 28 | const int nums_size = nums.size(); 29 | for (int i = 0; i < nums_size; ) 30 | { 31 | int j = i + 1, k = nums_size - 1; 32 | while (j < k) 33 | { 34 | if (abs(nums[i] + nums[j] + nums[k] - target) < abs(result - target)) 35 | result = nums[i] + nums[j] + nums[k]; 36 | if (result == target) 37 | return target; 38 | if (nums[i] + nums[j] + nums[k] > target) 39 | { 40 | k--; 41 | while (k > 0 && nums[k] == nums[k + 1]) 42 | k--; 43 | } 44 | else 45 | { 46 | j++; 47 | while (j < nums_size -1 && nums[j] == nums[j - 1]) 48 | j++; 49 | } 50 | 51 | } 52 | i++; 53 | while (i < nums_size && nums[i] == nums[i - 1]) 54 | i++; 55 | } 56 | return result; 57 | } 58 | 59 | ``` -------------------------------------------------------------------------------- /integer-arr/215-kth-largest-element-in-an-array.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 215-kth-largest-element-in-an-array 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | # problem 8 | 9 | [215-kth-largest-element-in-an-array](https://leetcode.com/problems/kth-largest-element-in-an-array/) 10 | 11 | ## similiar problem 12 | 13 | 14 | [/lint80-median](https://github.com/DragonFive/Leetcode/blob/master/integer-arr/lint80-median.md) 15 | 16 | [lint5 (5) Kth Largest Element](http://www.lintcode.com/en/problem/kth-largest-element/) 17 | 18 | # solution 19 | 20 | ## 局部快排法 21 | 22 | ```cpp 23 | int findKthLargest(vector& nums, int k) { 24 | int i = 0, j = nums.size() - 1; 25 | while (i < j) 26 | { 27 | int res = getFirstPos(nums, i ,j); 28 | if (res == k) break; 29 | if (res < k) 30 | i = res; 31 | else 32 | j = res - 2; 33 | } 34 | return nums[k - 1]; 35 | } 36 | int getFirstPos(vector& nums, int l, int r) 37 | { 38 | if (l == r) 39 | return l + 1; 40 | int temp = nums[l]; 41 | int i = l, j = r; 42 | while (i <= j ) 43 | { 44 | while (nums[i] >= temp && i < r) i++; 45 | while (nums[j] < temp && j > 0) j--; 46 | if (i <= j) 47 | { 48 | int t = nums[i]; 49 | nums[i++] = nums[j]; 50 | nums[j--] = t; 51 | } 52 | } 53 | int t = nums[i-1]; 54 | nums[i-1] = temp; 55 | nums[l] = t; 56 | return i; 57 | } 58 | ``` 59 | 60 | ## stl的方法 nth_element 61 | 62 | ···cpp 63 | int kthLargestElement(int k, vector nums) { 64 | nth_element(nums.begin(), nums.begin() + k ,nums.end()); 65 | return nums[nums.size() - k]; 66 | } 67 | ``` 68 | 69 | 70 | # 学习资料 71 | 72 | [寻找第K大的数的方法总结](http://www.cnblogs.com/zhjp11/archive/2010/02/26/1674227.html) -------------------------------------------------------------------------------- /integer-arr/26-Remove-Duplicates-from-Sorted-Array.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 26-Remove-Duplicates-from-Sorted-Array 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | # problem 8 | 9 | [26. Remove Duplicates from Sorted Array](https://leetcode.com/problems/remove-duplicates-from-sorted-array/) 10 | 11 | ## similar problem 12 | 13 | [lintcode 100 Remove Duplicates from Sorted Array](http://www.lintcode.com/en/problem/remove-duplicates-from-sorted-array/) 14 | 15 | # solution 16 | 17 | ## 过滤法 18 | ```cpp 19 | int removeDuplicates(vector& nums) { 20 | if (nums.empty() ) 21 | return 0; 22 | const int nums_size = nums.size(); 23 | int replace = -1; 24 | for (int i = 1; i < nums_size; i++) 25 | if (nums[i] == nums[i - 1]) 26 | { 27 | replace = i; 28 | break; 29 | } 30 | if (replace == -1) 31 | return nums_size; 32 | int j = replace + 1; 33 | while (j < nums_size && nums[j] == nums[j - 1]) 34 | j++; 35 | for (; j < nums_size; ) 36 | { 37 | nums[replace] = nums[j]; 38 | replace++; 39 | j++; 40 | while (j < nums_size && nums[j] == nums[j - 1]) 41 | j++; 42 | } 43 | return replace; 44 | } 45 | ``` -------------------------------------------------------------------------------- /integer-arr/41-first-missing-positive.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 41-first-missing-positive 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # source 9 | 10 | [41 first-missing-positive](https://leetcode.com/problems/first-missing-positive/) 11 | 12 | ## similiar problem 13 | [lint189-First-Missing-Positive.md](https://github.com/DragonFive/Leetcode/blob/master/integer-arr/lint189-First-Missing-Positive.md) 14 | 15 | # solution 16 | 17 | ## hash 18 | 19 | ```cpp 20 | int firstMissingPositive(vector A) { 21 | // write your code here 22 | int ret = 1; 23 | vector B(2 * A.size() + 1, false); 24 | for (int i = 0; i < A.size(); i++) 25 | if (A[i] >0) 26 | B[A[i]] = true; 27 | for (int i = 1; i < B.size(); i++) 28 | if (B[i] == false) 29 | return i; 30 | return ret; 31 | } 32 | 33 | ``` 34 | 其实这个答案问题还是蛮多的,比如空间复杂度占得多,题目的挑战性要求是时间复杂度O(n),空间复杂度是常数 35 | 36 | ## bucket sort 37 | 38 | ### 理解 39 | 下面的方法用的是通排序的变种 40 | 41 | 设想我们对给定数组使用桶排序的思想排序,第一个桶放1,第二个桶放2,如果找不到相应的数,则相应的桶的值不变(可能为负值,也可能为其他值)。+ 42 | 43 | 那么怎么才能做到原地排序呢?即若 A[i] = x, 则将 x 放到它该去的地方 - A[x - 1] = x, 同时将原来 A[x - 1地方的值交换给 A[i]. 44 | 排好序后遍历桶,如果不满足 f[i] = i + 1, 那么警察叔叔就是它了!如果都满足条件怎么办?那就返回给定数组大小再加1呗。 45 | 46 | ### 代码 47 | 48 | ```cpp 49 | int firstMissingPositive(vector A) { 50 | // write your code here 51 | const int size = A.size(); 52 | for (int i = 0; i < size; i++) 53 | { 54 | while (A[i] <= size && A[i] > 0 && A[i] != A[A[i] - 1] && A[i] != i + 1) 55 | { 56 | int temp = A[A[i] - 1]; 57 | A[A[i] - 1] = A[i]; 58 | A[i] = temp; 59 | } 60 | } 61 | //下面开始遍历这些内容了; 62 | for (int i = 0; i < size; i++) 63 | if (A[i] != i + 1) 64 | return i + 1; 65 | return size + 1; 66 | } 67 | ``` 68 | 69 | ### 分析 70 | 71 | 核心代码为那几行交换,但是要很好地处理各种边界条件则要下一番功夫了,要能正常的交换,需满足以下几个条件: 72 | A[i] 为正数,负数和零都无法在桶中找到生存空间... 73 | A[i] \leq size 当前索引处的值不能比原数组容量大,大了的话也没用啊,肯定不是缺的第一个正数。 74 | A[i] != i + 1, 都满足条件了还交换个毛线,交换也是自身的值。 75 | A[i] != A[A[i] - 1], 避免欲交换的值和自身相同,否则有重复值时会产生死循环。 76 | 如果满足以上四个条件就可以愉快地交换彼此了,使用while循环处理,此时i并不自增,直到将所有满足条件的索引处理完。 77 | 注意交换的写法,若写成 78 | int temp = A[i]; 79 | A[i] = A[A[i] - 1]; 80 | A[A[i] - 1] = temp; 81 | 这又是满满的 bug :( 因为在第三行中A[i]已不再是之前的值,第二行赋值时已经改变,故源码中的写法比较安全。 82 | 最后遍历桶排序后的数组,若在数组大小范围内找到不满足条件的解,直接返回,否则就意味着原数组给的元素都是从1开始的连续正整数,返回数组大小加1即可。 83 | 84 | 85 | # reference 86 | 87 | [LeetCode: First Missing Positive 解题报告](http://www.cnblogs.com/yuzhangcmu/p/4200096.html) 88 | 89 | [First Missing Positive](https://algorithm.yuanbin.me/zh-hans/integer_array/first_missing_positive.html) 90 | -------------------------------------------------------------------------------- /integer-arr/80-Remove-Duplicates-from-Sorted-Array-II.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 80-remove-duplicates-from-sorted-array-ii 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | # problem 8 | [80/remove-duplicates-from-sorted-array-ii](https://leetcode.com/problems/remove-duplicates-from-sorted-array-ii/) 9 | 10 | ## similiar problem 11 | 12 | [lint 101](http://www.lintcode.com/en/problem/remove-duplicates-from-sorted-array-ii/) 13 | 14 | 15 | # solution 16 | 17 | ## tow point 18 | 19 | ```cpp 20 | int removeDuplicates(vector& nums) { 21 | if (nums.empty()) 22 | return 0; 23 | if (nums.size() <= 2) 24 | return nums.size(); 25 | int left = 0, right = 0, last = -1, count = 0; 26 | last = nums[0];count = 1; left = 1; right = 1; 27 | const int nums_size = nums.size(); 28 | for ( ; right < nums_size; right++) 29 | { 30 | if (nums[right] != last) 31 | count = 0; 32 | if (nums[right] != last || count < 2) 33 | { 34 | nums[left] = nums[right]; 35 | last = nums[left];left++ ;count++; 36 | } 37 | else 38 | count++; 39 | } 40 | return left; 41 | 42 | } 43 | ``` -------------------------------------------------------------------------------- /integer-arr/80-remove-duplicates-from-sorted-array-ii.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 80-remove-duplicates-from-sorted-array-ii 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | # problem 8 | [80/remove-duplicates-from-sorted-array-ii](https://leetcode.com/problems/remove-duplicates-from-sorted-array-ii/) 9 | 10 | ## similiar problem 11 | 12 | [lint 101](http://www.lintcode.com/en/problem/remove-duplicates-from-sorted-array-ii/) 13 | 14 | 15 | # solution 16 | 17 | ## tow point 18 | 19 | ```cpp 20 | int removeDuplicates(vector& nums) { 21 | if (nums.empty()) 22 | return 0; 23 | if (nums.size() <= 2) 24 | return nums.size(); 25 | int left = 0, right = 0, last = -1, count = 0; 26 | last = nums[0];count = 1; left = 1; right = 1; 27 | const int nums_size = nums.size(); 28 | for ( ; right < nums_size; right++) 29 | { 30 | if (nums[right] != last) 31 | count = 0; 32 | if (nums[right] != last || count < 2) 33 | { 34 | nums[left] = nums[right]; 35 | last = nums[left];left++ ;count++; 36 | } 37 | else 38 | count++; 39 | } 40 | return left; 41 | 42 | } 43 | ``` -------------------------------------------------------------------------------- /integer-arr/88-Merge-Sorted-Array.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 88-Merge-Sorted-Array 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # problem 9 | 10 | [88. Merge Sorted Array](https://leetcode.com/problems/merge-sorted-array/) 11 | 12 | ## similiar problem 13 | 14 | [lint6 merge-sorted-array](http://www.lintcode.com/en/problem/merge-sorted-array/) 15 | 16 | # solution 17 | 18 | ```cpp 19 | void merge(vector& nums1, int m, vector& nums2, int n) { 20 | if (nums1.empty() || nums2.empty()) 21 | return; 22 | int j = m - 1 , k = n - 1, i = m + n - 1; 23 | for (; i >= 0; i--) 24 | { 25 | if (j < 0 || k < 0 ) 26 | break; 27 | if (nums1[j] > nums2[k]) 28 | nums1[i] = nums1[j--]; 29 | else 30 | nums1[i] = nums2[k--]; 31 | } 32 | while(k>=0) 33 | { 34 | nums1[i--] = nums2[k--]; 35 | } 36 | } 37 | ``` -------------------------------------------------------------------------------- /integer-arr/images/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DragonFive/code_interview/caf080acf7134c7c2eb526e12c01106be231d032/integer-arr/images/1.jpg -------------------------------------------------------------------------------- /integer-arr/lint189-First-Missing-Positive.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: lint189-First-Missing-Positive 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # source 9 | 10 | [189 First Missing Positive ](http://www.lintcode.com/en/problem/first-missing-positive/) 11 | 12 | 13 | # solution 14 | 15 | ## hash 16 | 17 | ```cpp 18 | int firstMissingPositive(vector A) { 19 | // write your code here 20 | int ret = 1; 21 | vector B(2 * A.size() + 1, false); 22 | for (int i = 0; i < A.size(); i++) 23 | if (A[i] >0) 24 | B[A[i]] = true; 25 | for (int i = 1; i < B.size(); i++) 26 | if (B[i] == false) 27 | return i; 28 | return ret; 29 | } 30 | 31 | ``` 32 | 33 | ## bucket sort 34 | 35 | 36 | -------------------------------------------------------------------------------- /integer-arr/lint31-Partition-Array.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: lint31-Partition-Array 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | # source 8 | [lintcode 31 Partition Array](http://www.lintcode.com/en/problem/partition-array/) 9 | 10 | 11 | # solution 12 | 13 | ## two pointer 14 | ```cpp 15 | int partitionArray(vector &nums, int k) { 16 | // write your code here 17 | // 判断是否为空; 18 | if (nums.empty()) 19 | return 0; 20 | //使用快速排序的方法; 21 | int start = 0, end = nums.size() - 1; 22 | while (start < end) 23 | { 24 | if (nums[start] < k) 25 | { 26 | start++; 27 | continue; 28 | } 29 | if (nums[end] >= k) 30 | { 31 | end--; 32 | continue; 33 | } 34 | //开始交换了; 35 | int temp = nums[start]; 36 | nums[start] = nums[end]; 37 | nums[end] = temp; 38 | start++; end--; 39 | } 40 | if (nums[end] < k) 41 | return end + 1; 42 | return end; 43 | } 44 | ``` 45 | 46 | ## 夹层法 47 | 48 | ```cpp 49 | int partitionArray(vector &nums, int k) { 50 | // write your code here 51 | // 判断是否为空; 52 | if (nums.empty()) 53 | return 0; 54 | // 使用隔间法; 55 | int lower = 0, upper = 0; 56 | while (upper < nums.size()) 57 | { 58 | if (nums[upper] >= k) 59 | upper++; 60 | else 61 | { 62 | int temp = nums[upper]; 63 | nums[upper] = nums[lower]; 64 | nums[lower] = temp; 65 | lower++; upper++; 66 | } 67 | } 68 | return lower; 69 | } 70 | ``` -------------------------------------------------------------------------------- /integer-arr/lint373-Partition-Array-by-Odd-and-Even.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: lint373-Partition-Array-by-Odd-and-Even 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | # resource 8 | 9 | [lint 373 Partition Array by Odd and Even](http://www.lintcode.com/en/problem/partition-array-by-odd-and-even/) 10 | 11 | # answer 12 | 13 | ```cpp 14 | void partitionArray(vector &nums) { 15 | // write your code here 16 | if (nums.empty() || nums.size() == 1) 17 | return; 18 | const int numsSize = nums.size(); 19 | int i = 0, j = numsSize - 1; 20 | while (i < j) 21 | { 22 | while ( nums[i] % 2 == 1 && i < numsSize) i++; 23 | while ( nums[j] % 2 == 0 && j > 0) j--; 24 | if (i < j) 25 | { 26 | int temp = nums[i]; 27 | nums[i] = nums[j]; 28 | nums[j] = temp; 29 | i++; j--; 30 | } 31 | } 32 | return; 33 | } 34 | ``` -------------------------------------------------------------------------------- /integer-arr/lint64-merge-two-sorted-arrays.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: lint64-merge-two-sorted-arrays 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | # source 8 | 9 | [lint64 merge-two-sorted-arrays](http://www.lintcode.com/en/problem/merge-two-sorted-arrays/ 10 | 11 | 12 | # solution 13 | 14 | ```cpp 15 | vector mergeSortedArray(vector &A, vector &B) { 16 | // write your code here 17 | if (A.empty() && B.empty()) 18 | return A; 19 | const int sizeA = A.size(); 20 | const int sizeB = B.size(); 21 | vector result(sizeA + sizeB); 22 | int i = 0, j = 0, k = 0; 23 | for (; i < sizeA + sizeB; ++i) 24 | { 25 | if (j >= sizeA || k >= sizeB) 26 | break; 27 | if (A[j] <= B[k]) 28 | result[i] = A[j++]; 29 | else 30 | result[i] = B[k++]; 31 | } 32 | while (j < sizeA) 33 | result[i++] = A[j++]; 34 | while (k < sizeB) 35 | result[i++] = B[k++]; 36 | return result; 37 | } 38 | ``` -------------------------------------------------------------------------------- /integer-arr/lint80-median.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: lint80-median 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | # source 7 | 8 | [(80) Median](http://www.lintcode.com/en/problem/median/#) 9 | 10 | # solution 11 | 12 | ```cpp 13 | int median(vector &nums) { 14 | // write your code here 15 | const int numsSize = nums.size(); 16 | int posInd = numsSize % 2 == 0 ? (numsSize - 1) / 2 : numsSize / 2; 17 | int left = 0, right = numsSize - 1; 18 | while (true) 19 | { 20 | int pos = getFirstPos(nums, left, right); 21 | if (pos == posInd) 22 | return nums[pos]; 23 | if (pos > posInd) 24 | right = pos - 1; 25 | else 26 | left = pos + 1; 27 | } 28 | } 29 | int getFirstPos(vector &nums, int begin, int endp) 30 | { 31 | if (begin == endp) 32 | return begin; 33 | int start = begin, end = endp; 34 | int temp = nums[start]; 35 | while(start <= end) 36 | { 37 | while (nums[start] <= temp && start <= endp) 38 | start++; 39 | while (nums[end] > temp && end >= begin) 40 | end--; 41 | if (start <= end) 42 | { 43 | int t = nums[start]; 44 | nums[start++] = nums[end]; 45 | nums[end--] = t; 46 | } 47 | } 48 | nums[begin] = nums[start - 1]; 49 | nums[start - 1] = temp; 50 | return start - 1; 51 | } 52 | ``` -------------------------------------------------------------------------------- /integer-arr/offer03_find_element_in_2D_array: -------------------------------------------------------------------------------- 1 | 2 | 3 | # source 4 | [牛客网:二维数组中的查找](https://www.nowcoder.com/practice/abc3fe2ce8e146608e868a70efebf62e?tpId=13&tqId=11154&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking) 5 | 6 | # solutions 7 | ```cpp 8 | class Solution { 9 | public: 10 | bool Find(int target, vector > array) { 11 | //从右下角开始算; 12 | if (array.empty() || array[0].empty()) 13 | return false; 14 | int w = array[0].size(); 15 | int h = array.size(); 16 | int i = 0, j = w - 1; 17 | while ( i >= 0 && i< h && j>=0 && j target){ 21 | j--; 22 | }else{ 23 | i++; 24 | } 25 | } 26 | return false; 27 | } 28 | }; 29 | ``` 30 | -------------------------------------------------------------------------------- /integer-arr/offer04_replace_blank: -------------------------------------------------------------------------------- 1 | 2 | # source 3 | [牛客:空格替换](https://www.nowcoder.com/practice/abc3fe2ce8e146608e868a70efebf62e?tpId=13&tqId=11154&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking) 4 | 5 | # solution 6 | ```cpp 7 | void replaceSpace(char *str,int length) { 8 | if (str == NULL || length == 0) 9 | return ; 10 | //先计算最终的长度; 11 | int len = 0; 12 | for (int i = 0; i < length; i++){ 13 | len++; 14 | if (str[i] == ' ') 15 | len = len + 2; 16 | } 17 | for (int j = len-1, k = length-1; j >= 0 ;j--, k--){ 18 | if (str[k] == ' '){ 19 | str[j--] = '0'; 20 | str[j--] = '2'; 21 | str[j] = '%'; 22 | }else{ 23 | str[j] = str[k]; 24 | } 25 | 26 | 27 | } 28 | return ; 29 | } 30 | ``` 31 | 32 | -------------------------------------------------------------------------------- /integer-arr/offer08_rotate_arr_min_num: -------------------------------------------------------------------------------- 1 | # source 2 | [剑指offer08旋转数组中的最小值](https://www.nowcoder.com/practice/9f3231a991af4f55b95579b44b7a01ba?tpId=13&tqId=11159&rp=1&ru=%2Fta%2Fcoding-interviews&qru=%2Fta%2Fcoding-interviews%2Fquestion-ranking) 3 | 4 | # solution 5 | 二分查找 6 | ```cpp 7 | 8 | int minNumberInRotateArray(vector rotateArray) { 9 | if (rotateArray.empty()) 10 | return 0; 11 | int len = rotateArray.size(); 12 | if (rotateArray[0] < rotateArray[len-1]) 13 | return rotateArray[0]; 14 | //下面使用二分查找法; 15 | int i = -1, j = len; 16 | while (i + 1 < j){ 17 | int mid = i+(j-i)/2; 18 | if (rotateArray[mid] < rotateArray[mid-1]) 19 | return rotateArray[mid]; 20 | if (rotateArray[mid]< rotateArray[0]) 21 | j = mid; 22 | else 23 | i =mid; 24 | } 25 | return 0; 26 | } 27 | ``` 28 | -------------------------------------------------------------------------------- /integer-arr/readme.md: -------------------------------------------------------------------------------- 1 | 整型数组的一些题目 2 | -------------------------------------------------------------------------------- /linked_list/002-add-two-numbers.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 002-add-two-numbers 3 | tags: 在河之洲,算法,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | # problem 8 | [002-add-two-numbers](https://leetcode.com/problems/add-two-numbers/#/description) 9 | 10 | 11 | # solution 12 | 13 | ```cpp 14 | ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) { 15 | if (!l1) 16 | return l2; 17 | if (!l2) 18 | return l1; 19 | ListNode * result = l2; 20 | int res = 0; 21 | ListNode * small = l1; 22 | if (getLen(l1) > getLen(l2)) 23 | { 24 | result = l1; 25 | small = l2; 26 | } 27 | ListNode * big = new ListNode(0); 28 | big->next = result; 29 | while (small) 30 | { 31 | int sum = small->val + big->next->val + res; 32 | big->next->val = sum % 10; 33 | res = sum / 10; 34 | big = big->next; 35 | small = small->next; 36 | } 37 | while (res!=0 && big->next) 38 | { 39 | int sum = big->next->val + res; 40 | big->next->val = sum % 10; 41 | res = sum / 10; 42 | big = big->next; 43 | } 44 | while (res!=0) 45 | { 46 | big->next = new ListNode(0); 47 | big->next->next = NULL; 48 | big->next->val = res % 10; 49 | res = res / 10; 50 | big = big->next; 51 | } 52 | return result; 53 | 54 | 55 | } 56 | int getLen(ListNode *L) 57 | { 58 | int len = 0; 59 | while (L) 60 | { 61 | len++; 62 | L = L->next; 63 | } 64 | return len; 65 | } 66 | 67 | ``` -------------------------------------------------------------------------------- /linked_list/138-copy-list-with-random-pointer.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 138-copy-list-with-random-pointer 3 | tags: 在河之洲,算法,leetcode 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # problem 9 | [138-copy-list-with-random-pointer](https://leetcode.com/problems/copy-list-with-random-pointer/#/description) 10 | 11 | # solution 12 | 使用hash表来存储位置的对应关系,同时赋予链表快速查询和常数级索引的功能 13 | ```cpp 14 | RandomListNode *copyRandomList(RandomListNode *head) { 15 | //先遍历按next,拷贝,并保存两个hash; 16 | if (head == NULL) 17 | return NULL; 18 | unordered_map oldNew; //新老对应map 19 | unordered_map oldRan; //random原来指的位置; 20 | RandomListNode *oldCur = head->next; 21 | RandomListNode *result = new RandomListNode(head->label); 22 | RandomListNode *newCur = result; 23 | //处理好NewCur的random; 24 | if (head->random != NULL) 25 | oldRan[newCur] = head->random; 26 | //处理好新旧对应; 27 | oldNew[head] = newCur; 28 | while (oldCur) 29 | { 30 | newCur->next = new RandomListNode(oldCur->label); 31 | newCur = newCur->next; 32 | //处理好NewCur的random; 33 | if (oldCur->random!=NULL) 34 | oldRan[newCur] = oldCur->random; 35 | //处理好新旧对应; 36 | oldNew[oldCur] = newCur; 37 | oldCur = oldCur->next; 38 | } 39 | //遍历一遍hash表,修改新链表对应的值; 40 | unordered_map::iterator umt = oldRan.begin(); 41 | for (; umt != oldRan.end(); umt++) 42 | { 43 | umt->first->random = oldNew[umt->second]; 44 | } 45 | return result; 46 | } 47 | ``` 48 | 49 | # reference 50 | 51 | [copy_list_with_random_pointer](https://algorithm.yuanbin.me/zh-hans/linked_list/copy_list_with_random_pointer.htm) -------------------------------------------------------------------------------- /linked_list/141-linked-list-cycle.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 141-linked-list-cycle 3 | tags: 在河之洲,算法,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | # problem 8 | [141-linked-list-cycle](https://leetcode.com/problems/linked-list-cycle/#/description) 9 | 10 | 为什么有环的话,快指针一定能遇到满指针呢,因为它们相遇时一定是在环中转圈,而快指针每次比慢指针多走一步,所以两者的正向距离会慢慢变小。 11 | # solution 12 | 方法一:快慢节点相错法 13 | ```cpp 14 | bool hasCycle(ListNode *head) { 15 | if (head == NULL || head->next == NULL) 16 | return false; 17 | ListNode *fast = head->next; 18 | ListNode *slow = head; 19 | while (fast!=slow) 20 | { 21 | if (fast == NULL || fast->next == NULL) 22 | return false; 23 | slow = slow->next; 24 | fast = fast->next->next; 25 | } 26 | return true; 27 | } 28 | ``` 29 | 方法二:同一起点 30 | 31 | ```cpp 32 | bool hasCycle(ListNode *head) { 33 | if (head == NULL) 34 | return false; 35 | ListNode *fast = head; 36 | ListNode *slow = head; 37 | while (fast!=NULL&&fast->next!=NULL) 38 | { 39 | slow = slow->next; 40 | fast = fast->next->next; 41 | if (slow != fast) 42 | return true; 43 | } 44 | return false; 45 | } 46 | ``` 47 | 48 | # 参考资料 49 | [判断链表是否有环,以及环的位置,和两个交叉链表相交的位置](http://www.cnblogs.com/missair/archive/2010/08/05/1793492.html) 50 | -------------------------------------------------------------------------------- /linked_list/142-linked-list-cycle-ii.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 142-linked-list-cycle-ii 3 | tags: 在河之洲,算法,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | # problem 8 | 9 | [142-linked-list-cycle-ii]https://leetcode.com/problems/linked-list-cycle-ii/#/description() 10 | 11 | 扩展问题: 12 | 13 | 判断两个单链表是否相交,如果相交,给出相交的第一个点(两个链表都不存在环)。 14 | 15 | 比较好的方法有两个: 16 | 17 | 一、将其中一个链表首尾相连,检测另外一个链表是否存在环,如果存在,则两个链表相交,而检测出来的依赖环入口即为相交的第一个点。 18 | 19 | 二、如果两个链表相交,那个两个链表从相交点到链表结束都是相同的节点,我们可以先遍历一个链表,直到尾部,再遍历另外一个链表,如果也可以走到同样的结尾点,则两个链表相交。 20 | 21 | 这时我们记下两个链表length,再遍历一次,长链表节点先出发前进(lengthMax-lengthMin)步,之后两个链表同时前进,每次一步,相遇的第一点即为两个链表相交的第一个点。 22 | # solution 23 | 法一:hash法 24 | ```cpp 25 | ListNode *detectCycle(ListNode *head) { 26 | //使用hash来保存每一个位置,如果这个位置再次被访问到,那就是了; 27 | if (head==NULL) 28 | return NULL; 29 | unordered_set hashNode; 30 | ListNode *cur = head; 31 | while (cur) 32 | { 33 | if (hashNode.find(cur) == hashNode.end()) 34 | hashNode.push_back(cur); 35 | else 36 | return cur; 37 | cur = cur->next; 38 | } 39 | return NULL; 40 | 41 | } 42 | ``` 43 | 44 | 法二:数学推导出个公式法 45 | ```cpp 46 | ListNode *detectCycle(ListNode *head) { 47 | //使用hash来保存每一个位置,如果这个位置再次被访问到,那就是了; 48 | if (head==NULL) 49 | return NULL; 50 | //先使用快慢指针找到相交点位置,然后再从起点跑起来 51 | ListNode *fast = head; 52 | ListNode *slow = head; 53 | while (fast!=NULL && fast->next!=NULL) 54 | { 55 | fast = fast->next->next; 56 | slow = slow->next; 57 | if (fast == slow) 58 | break; 59 | } 60 | if (fast == NULL || fast->next==NULL) 61 | return NULL; 62 | fast = head; 63 | while (fast!=slow) 64 | { 65 | fast=fast->next; 66 | slow=slow->next; 67 | } 68 | return slow; 69 | } 70 | ``` 71 | 72 | # 参考资料 73 | 74 | [判断链表是否有环,以及环的位置,和两个交叉链表相交的位置](http://www.cnblogs.com/missair/archive/2010/08/05/1793492.html) -------------------------------------------------------------------------------- /linked_list/143-reorder-list.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 143-reorder-list 3 | tags: 在河之洲,算法,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # problem 9 | 10 | [143-reorder-list](https://leetcode.com/problems/reorder-list/#/description) 11 | 12 | # solution 13 | 反转链表后归并 14 | ```cpp 15 | void reorderList(ListNode* head) { 16 | //如果不足长度就算了; 17 | if (head == NULL || head->next == NULL || head->next->next == NULL) 18 | return; 19 | //先计算反转的位置 20 | int len = 0; 21 | ListNode * cur = head; 22 | while (cur!=NULL) 23 | { 24 | len++; 25 | cur = cur->next; 26 | } 27 | int pos = (len + 3)/2; 28 | //然后对那个玩意进行反转 29 | cur = head; 30 | for (int i = 1; i < pos - 1; i++) 31 | cur = cur->next; 32 | ListNode *large = cur->next; 33 | cur->next = NULL; 34 | ListNode *pre = NULL; 35 | cur = large; 36 | while (cur!=NULL) 37 | { 38 | large = cur->next; 39 | cur->next = pre; 40 | pre =cur; 41 | cur = large; 42 | } 43 | //pre为起点的进入小的 44 | cur = head; 45 | while (pre!=NULL) 46 | { 47 | large = cur->next; 48 | cur->next = pre; 49 | ListNode *tmp = pre->next; 50 | pre->next = large; 51 | pre = tmp; 52 | cur = large; 53 | 54 | } 55 | 56 | } 57 | ``` -------------------------------------------------------------------------------- /linked_list/146-lru-cache.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 146-lru-cache 3 | tags: 在河之洲,算法,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | # problem 8 | [146-lru-cache](https://leetcode.com/problems/lru-cache/#/description) 9 | 10 | # solution 11 | 1. 使用vector管理 12 | ```cpp 13 | struct data{ 14 | int key; 15 | int value; 16 | data(int _key, int _value) :key(_key), value(_value){} 17 | }; 18 | class LRUCache { 19 | public: 20 | vector obj; 21 | int cap; 22 | LRUCache(int capacity) { 23 | cap = capacity; 24 | 25 | } 26 | int get(int key) { 27 | //先找到所在的位置,然后挪到第一个; 28 | int i = getPos(key); 29 | if (i == -1) 30 | return -1; 31 | //把第i个元素挪到第一个; 32 | int tkey = obj[i].key; 33 | int tval = obj[i].value; 34 | obj.erase(obj.begin() + i); 35 | put(tkey, tval); 36 | return tval; 37 | } 38 | int getPos(int key) 39 | { 40 | int osize = obj.size(); 41 | int i = 0; 42 | for (; i < osize; i++) 43 | { 44 | if (obj[i].key == key) 45 | break; 46 | } 47 | if (i >= osize) 48 | return -1; 49 | return i; 50 | } 51 | void put(int key, int value) { 52 | //放在最前头; 53 | int pos = getPos(key); 54 | //检查是否已经有这个数了; 55 | if (pos != -1) 56 | { 57 | //删除它; 58 | obj.erase(obj.begin() + pos); 59 | } 60 | if (obj.size() == cap) 61 | obj.erase(obj.end() - 1); 62 | data d(key, value); 63 | obj.insert(obj.begin(), d); 64 | } 65 | }; 66 | ``` 67 | 68 | 2. 使用hash表 和头尾哑节点 以及双向链表 69 | 70 | ```cpp 71 | struct LinkNode{ 72 | int key; 73 | int value; 74 | LinkNode *next; 75 | LinkNode *pre; 76 | LinkNode(int _key, int _value) :key(_key), value(_value), pre(NULL), next(NULL){} 77 | }; 78 | class LRUCache { 79 | public: 80 | LinkNode *head; 81 | LinkNode *tail;//这个链表也很有意思,根据它的操作,设计确定它在尾部插入,在头部删除冗余; 82 | unordered_map keyLink;//记录了当前的key,以及其对应的节点; 83 | int cap; 84 | LRUCache(int capacity) { 85 | cap = capacity; 86 | head = new LinkNode(0, 0); 87 | tail = new LinkNode(0, 0); 88 | head->next = tail; 89 | tail->pre = head; 90 | } 91 | 92 | int get(int key) { 93 | //如果有这个key,把它在链表中挪到最后. 94 | unordered_map::iterator umt = keyLink.find(key); 95 | if (umt == keyLink.end()) 96 | return -1; 97 | //把这个点挪到首节点; 98 | move2head(umt->second); 99 | //返回其值; 100 | return umt->second->value; 101 | } 102 | void move2head(LinkNode *cur) 103 | { 104 | if (cur == head->next) 105 | return; 106 | LinkNode * pre = cur->pre; 107 | cur->pre = head; 108 | pre->next = cur->next; 109 | cur->next = head->next; 110 | head->next->pre = cur; 111 | head->next = cur; 112 | pre->next->pre = pre; 113 | 114 | } 115 | void put(int key, int value) { 116 | //如果已经有这个值就替换; 117 | unordered_map::iterator umt = keyLink.find(key); 118 | if (umt != keyLink.end()) 119 | { 120 | umt->second->value = value; 121 | move2head(umt->second); 122 | return; 123 | } 124 | //如果不存在,判断是否需要删除节点; 125 | if (keyLink.size() == cap) 126 | { 127 | LinkNode *tmp = tail->pre; 128 | tail->pre = tmp->pre; 129 | tmp->pre->next = tail; 130 | keyLink.erase(tmp->key); 131 | delete tmp; 132 | } 133 | //然后插入新节点; 134 | LinkNode *newNode = new LinkNode(key, value); 135 | newNode->next = head->next; 136 | if (head->next != NULL) 137 | head->next->pre = newNode; 138 | newNode->pre = head; 139 | head->next = newNode; 140 | keyLink[key] = newNode; 141 | } 142 | }; 143 | ``` -------------------------------------------------------------------------------- /linked_list/147-insertion-sort-list.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 147-insertion-sort-list 3 | tags: 在河之洲,算法,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # problem 9 | 10 | [147-insertion-sort-list](https://leetcode.com/problems/insertion-sort-list/#/description) 11 | 12 | # solution 13 | ```cpp 14 | ListNode* insertionSortList(ListNode* head) { 15 | if (head == NULL || head->next == NULL) 16 | return head; 17 | ListNode *dummy = new ListNode(0); 18 | dummy->next = head; 19 | while (head && head->next) 20 | { 21 | ListNode *temp = dummy; 22 | while (head->next->val > temp->next->val && temp != head) 23 | temp = temp->next; 24 | if (temp->next!=head->next) 25 | { 26 | ListNode *x = head->next->next; 27 | head->next->next = temp->next; 28 | temp->next = head->next; 29 | head->next = x; 30 | } 31 | else 32 | { 33 | head = head->next; 34 | } 35 | } 36 | return dummy->next; 37 | 38 | } 39 | 40 | ``` -------------------------------------------------------------------------------- /linked_list/148-sort-list.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 148-sort-list 3 | tags: 在河之洲,算法,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # problem 9 | [148-sort-list](https://leetcode.com/problems/sort-list/#/description) 10 | 11 | # solution 12 | 归并排序 13 | ```cpp 14 | ListNode* sortList(ListNode* head) { 15 | if (head == NULL || head->next == NULL) 16 | return head; 17 | //先算长度 18 | int len = 0; 19 | ListNode *cur = head; 20 | while (cur) 21 | { 22 | len ++; 23 | cur = cur->next; 24 | } 25 | //再partition 26 | cur = head; 27 | for (int i = 1; i < len / 2; i ++) 28 | cur=cur->next; 29 | ListNode *right = cur->next; 30 | cur->next = NULL; 31 | cur = sortList(head); 32 | right = sortList(right); 33 | //再合并; 34 | ListNode *result = NULL; 35 | if (cur->val < right->val) 36 | { 37 | result = cur; 38 | cur = cur->next; 39 | } 40 | else 41 | { 42 | result = right; 43 | right = right->next; 44 | } 45 | ListNode *ret = result; 46 | while (cur!=NULL && right!=NULL) 47 | { 48 | if (cur->val < right->val) 49 | { 50 | result->next = cur; 51 | cur = cur->next; 52 | } 53 | else 54 | { 55 | result->next = right; 56 | right = right->next; 57 | } 58 | result = result->next; 59 | } 60 | if (cur == NULL) 61 | result->next = right; 62 | else 63 | result->next = cur; 64 | return ret; 65 | } 66 | ``` -------------------------------------------------------------------------------- /linked_list/203-remove-linked-list-elements.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 203-remove-linked-list-elements 3 | tags: 在河之洲,算法,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # problem 9 | 10 | [203-remove-linked-list-elements](https://leetcode.com/problems/remove-linked-list-elements/#/description) 11 | # solution 12 | 13 | ```cpp 14 | ListNode* removeElements(ListNode* head, int val) { 15 | if (head == NULL) 16 | return NULL; 17 | ListNode *dummy = new ListNode(0); 18 | dummy->next = head; 19 | ListNode *cur = dummy; 20 | while (cur->next !=NULL) 21 | { 22 | if (cur->next->val == val) 23 | { 24 | ListNode *tmp = cur->next; 25 | cur->next = tmp->next; 26 | delete tmp; 27 | } 28 | else 29 | { 30 | cur = cur->next; 31 | } 32 | } 33 | return dummy->next; 34 | } 35 | ``` -------------------------------------------------------------------------------- /linked_list/206-reverse-linked-list.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 206-reverse-linked-list 3 | tags: 在河之洲,算法,leetcode,easy 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # problem 9 | [](https://leetcode.com/problems/reverse-linked-list/#/description) 10 | 11 | # solution 12 | 13 | ```cpp 14 | ListNode* reverseList(ListNode* head) { 15 | if (head == NULL) 16 | return NULL; 17 | ListNode *pre = head; 18 | ListNode *cur = head->next; 19 | pre->next =NULL; 20 | while (cur) 21 | { 22 | ListNode *tmp = cur->next; 23 | cur->next = pre; 24 | pre = cur; 25 | cur = tmp; 26 | } 27 | return pre; 28 | } 29 | ``` -------------------------------------------------------------------------------- /linked_list/21-merge-two-sorted-lists.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 21-merge-two-sorted-lists 3 | tags: 在河之洲,算法,leetcode,easy 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # problem 9 | [21-merge-two-sorted-lists](https://leetcode.com/problems/merge-two-sorted-lists/#/description) 10 | 11 | # solution 12 | ```cpp 13 | ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) { 14 | if (l1 == NULL) 15 | return l2; 16 | ListNode *cur1 = l1; 17 | ListNode *cur2 = l2; 18 | ListNode *dummy = new ListNode(0); 19 | dummy->next = NULL; 20 | ListNode *result = dummy; 21 | while (cur1 != NULL && cur2 != NULL) 22 | { 23 | if (cur1->val < cur2->val) 24 | { 25 | result->next = cur1; 26 | cur1 = cur1->next; 27 | } 28 | else 29 | { 30 | result->next = cur2; 31 | cur2 = cur2->next; 32 | } 33 | result = result->next; 34 | } 35 | if (cur1 == NULL && cur2 != NULL) 36 | result->next = cur2; 37 | else 38 | result->next = cur1; 39 | return dummy->next; 40 | } 41 | ``` -------------------------------------------------------------------------------- /linked_list/23-merge-k-sorted-lists.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 23-merge-k-sorted-lists 3 | tags: 在河之洲,算法,leetcode,hard 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # problem 9 | [23-merge-k-sorted-lists](https://leetcode.com/problems/merge-k-sorted-lists/#/description) 10 | 11 | # solution 12 | ```cpp 13 | ListNode *mergeKLists(vector &lists) { 14 | // write your code here 15 | ListNode *dummy = new ListNode(0); 16 | dummy->next = NULL; 17 | ListNode *result = dummy; 18 | int size = lists.size(); 19 | int notNull = size; 20 | if (size == 1) 21 | dummy->next = lists[0]; 22 | while (notNull > 1) 23 | { 24 | //先找到最小者;然后赋值; 25 | int min = INT_MAX; 26 | notNull = size; 27 | int minInd = -1; 28 | for (int i = 0; i < size; i++) 29 | { 30 | if (lists[i] == NULL) 31 | notNull --; 32 | else if (lists[i]->val < min) 33 | { 34 | min = lists[i]->val; 35 | minInd = i; 36 | } 37 | } 38 | if (notNull > 0) 39 | { 40 | result->next = lists[minInd]; 41 | lists[minInd] = lists[minInd]->next; 42 | result = result->next; 43 | } 44 | } 45 | return dummy->next; 46 | } 47 | ``` 48 | 49 | # 更强的方法 50 | 51 | [更强的方法](https://algorithm.yuanbin.me/zh-hans/linked_list/merge_k_sorted_lists.html) -------------------------------------------------------------------------------- /linked_list/234-palindrome-linked-list.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 234-palindrome-linked-list 3 | tags: 在河之洲,算法,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # problem 9 | [234-palindrome-linked-list](https://leetcode.com/problems/palindrome-linked-list/#/description) 10 | # solution 11 | 12 | ```cpp 13 | bool isPalindrome(ListNode* head) { 14 | if (head == NULL) 15 | return false; 16 | if (head->next == NULL) 17 | return true; 18 | //先使用快慢链表找到中间节点,然后反转判断; 19 | ListNode *slow = head; 20 | ListNode *fast = head->next; 21 | while (fast != NULL && fast->next != NULL) 22 | { 23 | slow = slow->next; 24 | fast = fast->next->next; 25 | } 26 | //对slow后面的进行反转; 27 | fast = slow->next; 28 | slow->next = NULL; 29 | slow = NULL; 30 | while ( fast != NULL) 31 | { 32 | ListNode *tmp = fast->next; 33 | fast->next = slow; 34 | slow = fast; 35 | fast = tmp; 36 | } 37 | fast = slow; 38 | slow = head; 39 | //下面进行比较 40 | while (fast != NULL) 41 | { 42 | if (fast->val != slow->val) 43 | return false; 44 | fast = fast->next; 45 | slow = slow->next; 46 | } 47 | return true; 48 | 49 | } 50 | 51 | ``` -------------------------------------------------------------------------------- /linked_list/24-swap-nodes-in-pairs.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 24-swap-nodes-in-pairs 3 | tags: 在河之洲,算法,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # problem 9 | [24-swap-nodes-in-pairs](https://leetcode.com/problems/swap-nodes-in-pairs/#/description) 10 | 11 | # solution 12 | 13 | ```cpp 14 | ListNode* swapPairs(ListNode* head) { 15 | if (head == NULL || head->next == NULL) 16 | return head; 17 | ListNode *fast = head->next; 18 | ListNode *slow = new ListNode(0); 19 | slow->next = head; 20 | head = fast; 21 | while (fast) 22 | { 23 | slow->next->next = fast->next; 24 | fast->next = slow->next; 25 | slow->next = fast; 26 | 27 | slow = slow->next->next; 28 | if (fast->next->next == NULL) 29 | break; 30 | fast = fast->next->next->next; 31 | } 32 | return head; 33 | } 34 | ``` -------------------------------------------------------------------------------- /linked_list/61-rotate-list.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 61-rotate-list 3 | tags: 在河之洲,算法,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 使用双指针来找到特定的位置; 8 | # problem 9 | [61-rotate-list](https://leetcode.com/problems/rotate-list/#/description) 10 | # solution 11 | 12 | ```cpp 13 | ListNode* rotateRight(ListNode* head, int k) { 14 | if (head == NULL || head->next == NULL || k == 0) 15 | return head; 16 | //计算长度并找到最后一个点和应该断的点 17 | ListNode *tail = head; 18 | ListNode *place = head; 19 | int len = 0; 20 | while (tail) 21 | { 22 | tail=tail->next; 23 | len++; 24 | } 25 | k = k % len; 26 | if (k == 0) 27 | return head; 28 | tail = head; 29 | while (k-- && tail!=NULL) 30 | tail = tail->next; 31 | while (tail->next) 32 | { 33 | tail = tail->next; 34 | place = place->next; 35 | } 36 | //找到应该断的点; 37 | ListNode *tmp = place->next; 38 | place->next = NULL; 39 | tail->next = head; 40 | head = tmp; 41 | return head; 42 | } 43 | ``` -------------------------------------------------------------------------------- /linked_list/82-remove-duplicates-from-sorted-list-ii.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 82-remove-duplicates-from-sorted-list-ii 3 | tags: 在河之洲,算法,leetcode 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | # problem 8 | [82-remove-duplicates-from-sorted-list-ii](https://leetcode.com/problems/remove-duplicates-from-sorted-list-ii/#/description) 9 | # solution 10 | 11 | ```cpp 12 | ListNode* deleteDuplicates(ListNode* head) { 13 | if (head == NULL) 14 | return head; 15 | ListNode *pre = head; 16 | bool dup = false; 17 | ListNode *cur = pre->next; 18 | ListNode * pref = pre; 19 | while (cur) 20 | { 21 | if (pre->val == cur->val) 22 | { 23 | if (pre == head) 24 | head = cur; 25 | else 26 | pref->next = cur;//修改pre前面的next; 27 | delete pre; 28 | pre = cur; 29 | cur = cur->next; 30 | dup = true; 31 | } 32 | else if (dup) 33 | { 34 | if (pre == head) 35 | { 36 | head = cur; 37 | } 38 | else 39 | pref->next = cur; 40 | delete pre; 41 | pre = cur; 42 | cur = cur->next; 43 | dup = false; 44 | } 45 | else 46 | { 47 | pref = pre; 48 | pre = cur; 49 | cur = cur->next; 50 | } 51 | } 52 | if (dup) 53 | { 54 | if (pre == head) 55 | { 56 | head = NULL; 57 | } 58 | else 59 | pref->next = NULL; 60 | delete pre; 61 | pre = NULL; 62 | } 63 | return head; 64 | } 65 | ``` 66 | 67 | 68 | # 使用哑节点 69 | 对于首节点有变换可能的,一定要注意使用哑节点。 70 | ```cpp 71 | ListNode* deleteDuplicates(ListNode* head) { 72 | if (head == NULL) 73 | return head; 74 | ListNode *dummy = new ListNode(0); 75 | dummy->next = head; 76 | ListNode * cur = dummy; 77 | while (cur->next) 78 | { 79 | //按数据段进行搜索,而不是按单个数据搜索,运用了上下文信息,与 80 | if (cur->next->next!=NULL && cur->next->val == cur->next->next->val) 81 | { 82 | int preval = cur->next->val; 83 | //删除这个数据段,等于val的所有节点; 84 | while (cur->next!=NULL && cur->next->val == preval) 85 | { 86 | ListNode * tmp = cur->next; 87 | cur->next = tmp->next; 88 | delete tmp; 89 | tmp = NULL; 90 | } 91 | } 92 | else 93 | cur = cur->next; 94 | } 95 | return dummy->next; 96 | } 97 | ``` -------------------------------------------------------------------------------- /linked_list/83-remove-duplicates-from-sorted-list.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 83-remove-duplicates-from-sorted-list 3 | tags: 在河之洲,算法,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | # problem 8 | 9 | [83-remove-duplicates-from-sorted-list](https://leetcode.com/problems/remove-duplicates-from-sorted-list/#/description) 10 | 11 | # solution 12 | 13 | ```cpp 14 | ListNode* deleteDuplicates(ListNode* head) { 15 | if (head == NULL) 16 | return head; 17 | ListNode *pre = head; 18 | while (pre->next) 19 | { 20 | ListNode * cur = pre->next; 21 | if (cur->val == pre->val)//删掉当前内存; 22 | { 23 | pre->next = cur->next; 24 | delete cur; 25 | cur = pre->next; 26 | } 27 | else 28 | pre = cur; 29 | } 30 | return head; 31 | } 32 | ``` -------------------------------------------------------------------------------- /linked_list/86-partition-list.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 86-partition-list 3 | tags: 在河之洲,算法,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | # problem 8 | [86-partition-list](https://leetcode.com/problems/partition-list/#/description) 9 | 10 | 11 | # solution 12 | 13 | ```cpp 14 | ListNode* partition(ListNode* head, int x) { 15 | if (!head) 16 | return NULL; 17 | //先找到尾结点; 18 | ListNode * tail = head; 19 | int count = 1; 20 | while (tail->next) 21 | { 22 | tail = tail->next; 23 | count++; 24 | } 25 | ListNode * dummy = new ListNode(0); 26 | dummy->next = head; 27 | //考察每一个节点; 28 | ListNode * cur = dummy; 29 | while (count) 30 | { 31 | //这里需要注意的是最后一个节点,其实是不用考察的点; 32 | if (cur->next->val >= x && cur->next != tail) 33 | { 34 | ListNode * tmp = cur->next; 35 | cur->next = tmp->next; 36 | tmp->next = NULL; 37 | tail->next = tmp; 38 | tail = tmp; 39 | } 40 | else 41 | cur = cur->next; 42 | count--; 43 | } 44 | return dummy->next; 45 | 46 | } 47 | ``` -------------------------------------------------------------------------------- /linked_list/92-reverse-linked-list-ii.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 92-reverse-linked-list-ii 3 | tags: 在河之洲,算法,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # problem 9 | 10 | [92-reverse-linked-list-ii](https://leetcode.com/problems/reverse-linked-list-ii/#/description) 11 | 12 | 需要注意的是哑节点 13 | # solution 14 | ```cpp 15 | ListNode* reverseBetween(ListNode* head, int m, int n) { 16 | if (head == NULL) 17 | return NULL; 18 | if (m == n) 19 | return head; 20 | ListNode *dummy = new ListNode(0); 21 | dummy->next = head; 22 | ListNode *pre = dummy; 23 | ListNode *cur = head; 24 | ListNode *pm = head; 25 | int i = 1; 26 | while (i < m) 27 | { 28 | pre = cur; 29 | cur = cur->next; 30 | i++; 31 | } 32 | pm = cur; 33 | //然后下面开始反转了; 34 | ListNode * fa = cur; 35 | cur = cur->next; 36 | i++; 37 | while (i < n) 38 | { 39 | ListNode *tmp = cur->next; 40 | cur->next = fa; 41 | fa = cur; 42 | cur = tmp; 43 | i++; 44 | } 45 | ListNode *tmp = cur->next; 46 | cur->next = fa; 47 | pre->next = cur; 48 | pm->next = tmp; 49 | return dummy->next; 50 | } 51 | ``` -------------------------------------------------------------------------------- /linked_list/gfg-remove-duplicates-from-an-unsorted-linked-list.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: gfg-remove-duplicates-from-an-unsorted-linked-list 3 | tags: 在河之洲,算法,geeksforgeeks 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | # problem 8 | [gfg-remove-duplicates-from-an-unsorted-linked-list](http://www.geeksforgeeks.org/remove-duplicates-from-an-unsorted-linked-list/) 9 | 10 | # solution 11 | unordered_set也是hash 12 | ```cpp 13 | void removeDuplicates(struct Node *start) 14 | { 15 | // Hash to store seen values 16 | unordered_set seen; 17 | 18 | /* Pick elements one by one */ 19 | struct Node *curr = start; 20 | struct Node *prev = NULL; 21 | while (curr != NULL) 22 | { 23 | // If current value is seen before 24 | if (seen.find(curr->data) != seen.end()) 25 | { 26 | prev->next = curr->next; 27 | delete (curr); 28 | } 29 | else 30 | { 31 | seen.insert(curr->data); 32 | prev = curr; 33 | } 34 | curr = prev->next; 35 | } 36 | } 37 | ``` 38 | 39 | 使用Map来做 40 | ```cpp 41 | ListNode *deleteDuplicates(ListNode *head) { 42 | if (head == NULL) return NULL; 43 | 44 | // C++ 11 use unordered_map 45 | // unordered_map hash; 46 | map hash; 47 | hash[head->val] = true; 48 | ListNode *curr = head; 49 | while (curr->next != NULL) { 50 | if (hash.find(curr->next->val) != hash.end()) { 51 | ListNode *temp = curr->next; 52 | curr->next = curr->next->next; 53 | delete temp; 54 | } else { 55 | hash[curr->next->val] = true; 56 | curr = curr->next; 57 | } 58 | } 59 | 60 | return head; 61 | } 62 | ``` -------------------------------------------------------------------------------- /linked_list/gfg-sum-of-two-linked-lists.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: gfg-sum-of-two-linked-lists 3 | tags: 在河之洲,算法,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | # problem 8 | [sum-of-two-linked-lists](http://www.geeksforgeeks.org/sum-of-two-linked-lists/) 9 | 10 | # solution 11 | 12 | ```cpp 13 | 14 | 15 | 16 | ``` -------------------------------------------------------------------------------- /linked_list/lint174-remove-nth-node-from-end-of-list.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: lint174-remove-nth-node-from-end-of-list 3 | tags: 在河之洲,算法,lintcode 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | # problem 8 | [lint174-remove-nth-node-from-end-of-list](http://www.lintcode.com/en/problem/remove-nth-node-from-end-of-list/) 9 | # solution 10 | 11 | ```cpp 12 | ListNode *removeNthFromEnd(ListNode *head, int n) { 13 | // write your code here 14 | if (!head) 15 | return NULL; 16 | //先计算位置; 17 | int nodeNum = 0; 18 | ListNode *cur = head; 19 | while (cur) 20 | { 21 | nodeNum++; 22 | cur = cur->next; 23 | } 24 | ListNode *dummy = new ListNode(0); 25 | dummy->next = head; 26 | cur = dummy; 27 | while(nodeNum != n) 28 | { 29 | cur = cur->next; 30 | nodeNum--; 31 | } 32 | ListNode * tmp = cur->next; 33 | cur->next = tmp->next; 34 | delete tmp; 35 | return dummy->next; 36 | } 37 | ``` -------------------------------------------------------------------------------- /linked_list/readme: -------------------------------------------------------------------------------- 1 | 一些操作链表的题目 2 | 3 | 链表的常见操作有 快慢指针,以及借助hash stack等结构 4 | 5 | unoredered_map的常见方法: 6 | 7 | 查找与新建 8 | ``` 9 | [], 返回key对应元素的引用,如果key不存在会新建一个并返回,可用于左值和右值。 10 | at(key), 返回对应的value的引用,但是如果key不存在就抛异常。 11 | find(),返回key对应元素的iterator,如果Key不存在就返回end(); 12 | 13 | ``` 14 | 插入删除 15 | 16 | ``` 17 | insert 可以insert一个别的数组的区间 18 | erase 可以按key 按位置和按区间删除 19 | ``` 20 | 21 | 22 | 在遍历删除和遍历交换的时候需要注意指针所指对象的改变 23 | 24 | [203-remove-linked-list-elements](https://github.com/DragonFive/Leetcode/blob/master/linked_list/203-remove-linked-list-elements.md) 25 | 26 | [147-insertion-sort-list](https://github.com/DragonFive/Leetcode/blob/master/linked_list/147-insertion-sort-list.md) -------------------------------------------------------------------------------- /search/153-find-minimum-in-rotated-sorted-array.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 153-find-minimum-in-rotated-sorted-array 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | # problem 8 | [153-find-minimum-in-rotated-sorted-array](https://leetcode.com/problems/find-minimum-in-rotated-sorted-array/?tab=Description) 9 | ## similiar problem 10 | 11 | [33-search-in-rotated-sorted-array.md](https://github.com/DragonFive/Leetcode/blob/master/search/33-search-in-rotated-sorted-array.md) 12 | 13 | [81-search-in-rotated-sorted-array-ii.md](https://github.com/DragonFive/Leetcode/blob/master/search/81-search-in-rotated-sorted-array-ii.md) 14 | 15 | # solution 16 | 起点比较法 17 | ```cpp 18 | int findMin(vector& nums) { 19 | int i = 0, j = nums.size() - 1; 20 | if (nums.size() == 1 || nums[0] < nums[j]) 21 | return nums[0]; 22 | while ( i + 1 < j ) 23 | { 24 | int k = i + (j - i) / 2; 25 | if (nums[i] < nums[k]) 26 | {//说明左边是有序序列;最小值在右边; 27 | i = k; 28 | } 29 | else 30 | j = k; 31 | } 32 | return nums[j]; 33 | } 34 | ``` 35 | 36 | 经过修正变成 37 | ```cpp 38 | int findMin(vector& nums) { 39 | int i = 0, j = nums.size() - 1; 40 | 41 | while ( i + 1 < j ) 42 | { 43 | int k = i + (j - i) / 2; 44 | if (nums[i] < nums[k]) 45 | {//说明左边是有序序列;最小值在右边;或者本来就有序 46 | if (nums[i] < nums[j]) 47 | return nums[i]; 48 | else 49 | i = k; 50 | } 51 | else 52 | j = k; 53 | } 54 | if (nums[i] < nums[j]) 55 | return nums[i]; 56 | return nums[j]; 57 | } 58 | ``` -------------------------------------------------------------------------------- /search/154-find-minimum-in-rotated-sorted-array-ii.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 154-find-minimum-in-rotated-sorted-array-ii 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | # problem 8 | 9 | [154-find-minimum-in-rotated-sorted-array-ii](https://leetcode.com/problems/find-minimum-in-rotated-sorted-array-ii/?tab=Description) 10 | 11 | ## similiar problem 12 | 13 | [33-search-in-rotated-sorted-array.md](https://github.com/DragonFive/Leetcode/blob/master/search/33-search-in-rotated-sorted-array.md) 14 | 15 | [81-search-in-rotated-sorted-array-ii.md](https://github.com/DragonFive/Leetcode/blob/master/search/81-search-in-rotated-sorted-array-ii.md) 16 | 17 | # solution 18 | 19 | ```cpp 20 | int findMin(vector& nums) { 21 | int i = 0, j = nums.size() - 1; 22 | while ( i + 1 < j ) 23 | { 24 | int k = i + (j - i) / 2; 25 | if (nums[i] < nums[k]) 26 | {//说明左边是有序序列;最小值在右边;或者本来就是有序序列 27 | if (nums[i] < nums[j]) 28 | return nums[i]; 29 | else 30 | i = k; 31 | } 32 | else if (nums[i] > nums[k]) 33 | j = k; 34 | else 35 | i++; 36 | } 37 | if (nums[i] < nums[j]) 38 | return nums[i]; 39 | return nums[j]; 40 | } 41 | ``` -------------------------------------------------------------------------------- /search/2017-3-7-lint183-wood-cut.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 2017-3-7-lint183-wood-cut 3 | tags: 在河之洲,算法,lintcode 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # problem 9 | [lintcode183 wood cut](http://www.lintcode.com/en/problem/wood-cut/) 10 | 11 | # solution 12 | 注意两点 13 | 1. 注意边界条件 14 | 2. 取的是最大值而不是最小值. 15 | ```cpp 16 | int woodCut(vector L, int k) { 17 | // write your code here 18 | //先找到L里面最短的; 19 | // write your code here 20 | //先找到L里面最短的; 21 | if (L.empty()) 22 | return 0; 23 | int maxLen = 0; 24 | for (int i = 0; i < L.size(); i++) 25 | if (L[i] > maxLen) 26 | maxLen = L[i]; 27 | //再进行切分; 28 | int i = 1, j = maxLen; 29 | while (i + 1 < j) 30 | { 31 | int m = i + (j - i) / 2; 32 | int num = getCutNum(L, m); 33 | if (num < k) 34 | j = m; 35 | else 36 | i = m; 37 | } 38 | if (j != maxLen && i != 1) 39 | return i; 40 | if (j == maxLen) 41 | if (getCutNum(L, j) >= k) 42 | return j; 43 | else 44 | return i; 45 | else if (getCutNum(L, 1) >= k) 46 | return 1; 47 | else 48 | return 0; 49 | 50 | 51 | } 52 | int getCutNum(vector L, int len) 53 | { 54 | int num = 0; 55 | for (int i = 0 ; i < L.size(); i++) 56 | num += L[i] / len; 57 | return num; 58 | } 59 | 60 | ``` -------------------------------------------------------------------------------- /search/240-search-a-2d-matrix2.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 240-search-a-2d-matrix2 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | # problem 8 | [240-search-a-2d-matrix2](https://leetcode.com/problems/search-a-2d-matrix-ii/?tab=Description) 9 | ## similiar problem 10 | 11 | [74-search-a-2d-matrix](https://github.com/DragonFive/Leetcode/blob/master/search/74-search-a-2d-matrix.md) 12 | 13 | # solution 14 | 逐层遍历法 15 | 时间复杂度为O(mlogn) 16 | ```cpp 17 | bool searchMatrix(vector>& matrix, int target) { 18 | if (matrix.empty() || matrix[0].empty()) 19 | return false; 20 | int rows = matrix.size(); 21 | int cols = matrix[0].size(); 22 | for (int i = 0; i < rows; i++) 23 | { 24 | if (matrix[i][0] > target) 25 | break; 26 | if (matrix[i][cols - 1] < target) 27 | continue; 28 | if (searchRow(matrix[i], target)) 29 | return true; 30 | } 31 | return false; 32 | } 33 | bool searchRow(vector &row, int target) 34 | { 35 | if (row.empty()) 36 | return false; 37 | const int len = row.size(); 38 | int i = -1, j = len; 39 | while (i + 1 < j) 40 | { 41 | int k = i + (j - i) / 2; 42 | if (row[k] < target) 43 | i = k; 44 | else 45 | j = k; 46 | } 47 | if (j != len && row[j] == target) 48 | return true; 49 | return false; 50 | } 51 | ``` 52 | 53 | ## 自右上到左下法 54 | 时间复杂度O(m+n) 55 | ```cpp 56 | bool searchMatrix(vector>& matrix, int target) { 57 | if ( matrix.empty() || matrix[0].empty() ) 58 | return false; 59 | int rows = matrix.size(), cols = matrix[0].size(); 60 | int i = 0, j = cols -1; 61 | while ( i < rows && j >=0 ) 62 | { 63 | if ( matrix[i][j] == target) 64 | return true; 65 | if ( matrix[i][j] < target ) 66 | i += 1; 67 | else 68 | j -=1; 69 | } 70 | return false; 71 | } 72 | ``` 73 | -------------------------------------------------------------------------------- /search/33-search-in-rotated-sorted-array.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 33-search-in-rotated-sorted-array 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | # problem 8 | 9 | [33-search-in-rotated-sorted-array](https://leetcode.com/problems/search-in-rotated-sorted-array/?tab=Description) 10 | ## similiar problem 11 | 12 | [lint62 Search in Rotated Sorted Array](http://www.lintcode.com/en/problem/search-in-rotated-sorted-array/) 13 | 14 | # solution 15 | 16 | ```cpp 17 | int search(vector& nums, int target) { 18 | //先找到中间点; 19 | if (nums.empty()) 20 | return -1; 21 | int i = 0, j = nums.size() - 1; 22 | if ( nums[i] > nums[j]) 23 | { 24 | while ( i + 1 < j) 25 | { 26 | int k = i + (j - i) / 2; 27 | if (nums[k] > nums[0]) 28 | i = k; 29 | else 30 | j = k; 31 | } 32 | } 33 | else 34 | i = j; 35 | if (target >= nums[0])//左边 36 | { 37 | return binSearch(nums, 0, i, target); 38 | } 39 | else//右边 40 | { 41 | return binSearch(nums, j, nums.size()-1, target); 42 | } 43 | 44 | } 45 | int binSearch(vector& nums, int start, int end, int target) 46 | { 47 | if (start == end && nums[start] != target) 48 | return -1; 49 | int mid = start + (end - start) / 2; 50 | if (nums[mid] == target) 51 | return mid; 52 | if (nums[mid] < target) 53 | return binSearch(nums, mid + 1, end, target); 54 | else 55 | return binSearch(nums, start, mid, target); 56 | } 57 | ``` 58 | 59 | 开头比较法 60 | 61 | ```cpp 62 | int search(vector& nums, int target) { 63 | //先找到中间点; 64 | if (nums.empty()) 65 | return -1; 66 | int i = 0, j = nums.size() - 1; 67 | while ( i + 1 < j ) 68 | { 69 | int k = i + (j - i) / 2; 70 | if ( target == nums[k]) 71 | return k; 72 | if ( nums[i] < nums[k] ) 73 | { 74 | if ( nums[i] <= target && nums[k] >= target) 75 | j = k; 76 | else 77 | i = k; 78 | } 79 | else 80 | { 81 | if (nums[k] <= target && nums[j] >= target) 82 | i = k; 83 | else 84 | j = k; 85 | } 86 | 87 | } 88 | if (nums[i] == target) 89 | return i; 90 | if (nums[j] == target) 91 | return j; 92 | return -1; 93 | } 94 | ``` -------------------------------------------------------------------------------- /search/34-search-for-range.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 34-search-for-range 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | # problem 8 | 9 | [34-search-for-range](https://leetcode.com/problems/search-for-a-range/?tab=Description) 10 | 11 | ## similiar problem 12 | 13 | [lintv61 search for a range](http://www.lintcode.com/en/problem/search-for-a-range/) 14 | 15 | # solution 16 | 17 | ## ordinary solution 18 | ```cpp 19 | vector searchRange(vector& nums, int target) { 20 | //先findFirst 21 | vector ret; 22 | if (nums.empty()) 23 | { 24 | ret.push_back(-1); 25 | ret.push_back(-1); 26 | return ret; 27 | } 28 | int len = nums.size(); 29 | 30 | int i = 0, j = len - 1; 31 | while ( i <= j) 32 | { 33 | int k = i + (j - i)/2; 34 | if ( nums[k] == target) 35 | { 36 | int t = k; 37 | while (k > 0 && nums[k - 1] == target) 38 | k--; 39 | ret.push_back(k); 40 | while (t < len -1 && nums[t + 1] == target) 41 | t ++; 42 | ret.push_back(t); 43 | return ret; 44 | } 45 | if ( nums[k] > target) 46 | j = k - 1; 47 | else 48 | i = k + 1; 49 | } 50 | ret.push_back(-1); 51 | ret.push_back(-1); 52 | return ret; 53 | } 54 | ``` 55 | 56 | ## 真正的求上下界的方法 57 | 58 | ```cpp 59 | vector searchRange(vector& nums, int target) { 60 | //先findFirst 61 | vector ret(2, -1); 62 | if (nums.empty()) 63 | return ret; 64 | int len = nums.size(); 65 | 66 | int i = -1, j = len; 67 | while ( i + 1 < j ) 68 | { 69 | int k = i + (j - i)/2; 70 | if ( nums[k] < target) 71 | i = k; 72 | else 73 | j = k; 74 | } 75 | if (j < len && nums[j] != target || j == len && nums[i] != target) 76 | return ret; 77 | ret[0] = j; 78 | i = j - 1, j = len; 79 | while (i + 1 < j) 80 | { 81 | int k = i + (j - i)/2; 82 | if (nums[k] > target) 83 | j = k; 84 | else 85 | i = k; 86 | } 87 | ret[1] = i; 88 | return ret; 89 | } 90 | ``` 91 | -------------------------------------------------------------------------------- /search/74-search-a-2d-matrix.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 74-search-a-2d-matrix 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | # problem 8 | 9 | [74 search a 2d matrix](https://leetcode.com/problems/search-a-2d-matrix/?tab=Description) 10 | 11 | # solution 12 | ## 折半查找法 13 | 时间复杂度为O(logmn)=O(logm+logn) 14 | ```cpp 15 | bool searchMatrix(vector>& matrix, int target) { 16 | if (matrix.empty()) 17 | return false; 18 | int rows = matrix.size(); 19 | int cols = matrix[0].size(); 20 | int i = -1, j = rows * cols; 21 | while (i + 1 < j) 22 | { 23 | int mid = i + (j - i)/2; 24 | if (matrix[mid / cols][mid % cols] < target) 25 | i = mid; 26 | else 27 | j = mid; 28 | } 29 | if ( j < rows * cols && matrix[j / cols][j % cols] == target) 30 | return true; 31 | return false; 32 | } 33 | ``` 34 | 35 | ## 从右上到左下 36 | 时间复杂度为O(m+n) 37 | ```cpp 38 | bool searchMatrix(vector>& matrix, int target) { 39 | if ( matrix.empty() || matrix[0].empty() ) 40 | return false; 41 | int rows = matrix.size(), cols = matrix[0].size(); 42 | int i = 0, j = cols -1; 43 | while ( i < rows && j >=0 ) 44 | { 45 | if ( matrix[i][j] == target) 46 | return true; 47 | if ( matrix[i][j] < target ) 48 | i += 1; 49 | else 50 | j -=1; 51 | } 52 | return false; 53 | } 54 | ``` -------------------------------------------------------------------------------- /search/81-search-in-rotated-sorted-array-ii.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 81-search-in-rotated-sorted-array-ii 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | 8 | # problem 9 | [81search-in-rotated-sorted-array-ii](https://leetcode.com/problems/search-in-rotated-sorted-array-ii/?tab=Description) 10 | 11 | ## similiar problem 12 | [33-search-in-rotated-sorted-array](https://github.com/DragonFive/Leetcode/blob/master/search/33-search-in-rotated-sorted-array.md) 13 | 14 | [63search-in-rotated-sorted-array-ii/](http://www.lintcode.com/en/problem/search-in-rotated-sorted-array-ii/) 15 | 16 | # solution 17 | 关口在于用开头和中间的比来确定有序序列 18 | ```cpp 19 | bool search(vector& nums, int target) { 20 | if (nums.empty()) 21 | return false; 22 | int i = 0, j = nums.size() - 1; 23 | while ( i + 1 < j) 24 | { 25 | int k = i + (j - i) / 2; 26 | if (nums[k] == target) 27 | return true; 28 | if (nums[i] < nums[k]) 29 | {//左边是有序序列 30 | if (nums[k] >= target && nums[i] <= target)//落在有序范围内 31 | { 32 | j = k; 33 | } 34 | else 35 | { 36 | i = k; 37 | } 38 | } 39 | else if (nums[i] > nums[k]) 40 | {//右边是有序序列; 41 | if (nums[k] <= target && nums[j] >= target)//落在有序范围内 42 | i = k; 43 | else//可能更大也可能更小 44 | j = k; 45 | } 46 | else 47 | i++; 48 | } 49 | if (nums[i] == target || nums[j] == target) 50 | return true; 51 | return false; 52 | } 53 | ``` 54 | 55 | # reference 56 | 57 | [leetcode 题解](https://algorithm.yuanbin.me/zh-hans/binary_search/search_in_rotated_sorted_array_ii.html) -------------------------------------------------------------------------------- /search/lint-60-search-insert-position.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: lint-60-search-insert-position 3 | tags: 新建,模板,小书匠 4 | grammar_cjkRuby: true 5 | --- 6 | 7 | # problem 8 | 9 | [lint60 search insert position]() 10 | 11 | # solution 12 | 13 | ```cpp 14 | int searchInsert(vector &A, int target) { 15 | // write your code here 16 | if (A.empty()) 17 | return 0; 18 | int i = 0, j = A.size(); 19 | while (i <= j) 20 | { 21 | int mid = (i + j) / 2; 22 | if (A[mid] == target) 23 | return mid; 24 | if (A[mid] < target) 25 | i = mid + 1; 26 | else 27 | j = mid - 1; 28 | } 29 | return i; 30 | } 31 | ``` -------------------------------------------------------------------------------- /search/readme.md: -------------------------------------------------------------------------------- 1 | 这里是搜索的题目 2 | -------------------------------------------------------------------------------- /sword_to_offer/15_find_back_k_elem.md: -------------------------------------------------------------------------------- 1 | # source 2 | 3 | [链表中倒数第k个结点](https://github.com/gatieme/CodingInterviews/tree/master/015-%E9%93%BE%E8%A1%A8%E4%B8%AD%E5%80%92%E6%95%B0%E7%AC%ACk%E4%B8%AA%E7%BB%93%E7%82%B9) 4 | # solution 5 | ```cpp 6 | ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) { 7 | ListNode *first = pListHead; 8 | ListNode *second = pListHead; 9 | if (pListHead == NULL || k <= 0) 10 | return NULL; 11 | //先找到隔着k个的下一个; 12 | int i = 1; 13 | while (first->next!=NULL && i < k) 14 | { 15 | first = first->next; 16 | i++; 17 | } 18 | if (first->next == NULL && i!= k) 19 | return NULL; 20 | while (first->next!=NULL) 21 | { 22 | first = first->next; 23 | second = second->next; 24 | } 25 | return second; 26 | } 27 | ``` 28 | -------------------------------------------------------------------------------- /sword_to_offer/16_reverse_linkedlist.md: -------------------------------------------------------------------------------- 1 | # source 2 | [16 翻转链表](https://github.com/gatieme/CodingInterviews/tree/master/016-%E5%8F%8D%E8%BD%AC%E9%93%BE%E8%A1%A8) 3 | 4 | # solution 5 | ## 三指针法 6 | 7 | ```cpp 8 | ListNode* ReverseList(ListNode* pHead) { 9 | if (pHead == NULL || pHead->next == NULL) 10 | return pHead; 11 | ListNode *pre = pHead; 12 | ListNode *cur = pHead->next; 13 | pre->next = NULL; 14 | while (cur->next!=NULL) 15 | { 16 | ListNode *tmp = cur->next; 17 | cur->next=pre; 18 | pre = cur; 19 | cur = tmp; 20 | } 21 | cur->next = pre; 22 | pHead = cur; 23 | return pHead; 24 | } 25 | 26 | ``` 27 | 28 | ## 头插法 29 | ```cpp 30 | ListNode* ReverseList(ListNode* pHead) { 31 | if (pHead == NULL || pHead->next == NULL) 32 | return pHead; 33 | ListNode *cur = pHead->next; 34 | ListNode *pre = pHead; 35 | while (cur!=NULL){ 36 | pHead->next = cur->next; 37 | cur->next = pre; 38 | pre = cur; 39 | cur = pHead->next; 40 | } 41 | pHead = pre; 42 | return pHead; 43 | } 44 | ``` 45 | -------------------------------------------------------------------------------- /sword_to_offer/17_combine_linkedList.md: -------------------------------------------------------------------------------- 1 | # source 2 | 3 | [017-合并两个排序的链表](https://github.com/gatieme/CodingInterviews/tree/master/017-%E5%90%88%E5%B9%B6%E4%B8%A4%E4%B8%AA%E6%8E%92%E5%BA%8F%E7%9A%84%E9%93%BE%E8%A1%A8) 4 | 5 | # solution 6 | 7 | ```cpp 8 | ListNode* Merge(ListNode* pHead1, ListNode* pHead2) 9 | { 10 | if (pHead1 == NULL) 11 | return pHead2; 12 | if (pHead2 == NULL) 13 | return pHead1; 14 | ListNode *yummy = new ListNode(0); 15 | yummy->next = pHead2; 16 | if (pHead2->val < pHead1->val){ 17 | yummy->next = pHead2->next; 18 | pHead2->next = pHead1; 19 | pHead1 = pHead2; 20 | } 21 | ListNode *cur = pHead1; 22 | while (cur->next != NULL && yummy->next!=NULL){ 23 | if (yummy->next->val < cur->next->val){ 24 | ListNode *tmp = yummy->next; 25 | yummy->next = tmp->next; 26 | tmp->next = cur->next; 27 | cur->next = tmp; 28 | } 29 | cur = cur->next; 30 | } 31 | if (cur->next == NULL) 32 | cur->next = yummy->next; 33 | return pHead1; 34 | 35 | } 36 | ``` 37 | 38 | 39 | -------------------------------------------------------------------------------- /sword_to_offer/1_two_dim_arr_search.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | class Solution { 5 | public: 6 | typedef vector > vv; 7 | bool Find(int target, vector > array) { 8 | if (array.empty() || array[0].empty()) 9 | return false; 10 | return bin_search(array, 0, array[0].size()-1, target); 11 | } 12 | bool bin_search(const vv &arr, size_t begin_line, size_t end_col, int target){ 13 | auto rows = arr.size(); 14 | auto cols = arr[0].size(); 15 | 16 | if (begin_line == rows-1 && end_col == 0){ 17 | if (arr[begin_line][end_col] != target)return false; 18 | return true; 19 | } 20 | if (begin_line == rows-1){ 21 | int res= search_line(arr, begin_line, end_col, target); 22 | if (res>=cols && arr[rows-1][res] != target)return false; 23 | return true; 24 | } 25 | if (end_col == 0){ 26 | int res = search_col(arr, begin_line, 0, target); 27 | if (arr[res][0] == target)return true; 28 | return false; 29 | } 30 | //cout<<"hehe"<=rows)return false; 33 | //cout < target) 44 | j = mid - 1; 45 | else 46 | i = mid + 1; 47 | } 48 | return i; 49 | } 50 | int search_col(const vv &arr, size_t begin_line, size_t col, int target){ 51 | int rows = arr.size(); 52 | int i = begin_line, j = rows-1; 53 | while (i<=j){ 54 | int mid = (i+j)/2; 55 | //cout<<"mid " << mid << endl; 56 | if (arr[mid][col] == target) 57 | { 58 | //cout< target) 62 | j = mid-1; 63 | else 64 | i = mid+1; 65 | } 66 | return i; 67 | } 68 | }; 69 | 70 | int main() 71 | { 72 | Solution::vv a={{1,2,8,9}, {2,4,9,12},{4,7,10,13},{6,8,11,15}}; 73 | Solution b; 74 | bool res = b.Find(16, a); 75 | cout< 2 | #include 3 | #define debug 4 | using namespace std; 5 | class Solution { 6 | public: 7 | typedef vector > vv; 8 | bool Find(int target, vector > array) { 9 | if (array.empty() || array[0].empty()) 10 | return false; 11 | int rows = array.size(); 12 | int cols = array[0].size(); 13 | for (int i=0,j=cols-1; i=0 ;){ 14 | #ifdef debug 15 | cout< target){ 19 | #ifdef debug 20 | cout <<">"; 21 | #endif 22 | j--; 23 | } 24 | else { 25 | #ifdef debug 26 | cout<<"<"; 27 | #endif 28 | i++; 29 | } 30 | #ifdef debug 31 | cout< nodes; 13 | ListNode *cur = pHead1; 14 | while (cur != NULL){ 15 | nodes.insert(cur); 16 | cur = cur->next; 17 | } 18 | //遍历第二个链表,知道找到set里有的 19 | cur = pHead2; 20 | while (cur!=NULL){ 21 | if (nodes.find(cur) != nodes.end()) 22 | return cur; 23 | cur = cur->next; 24 | } 25 | return NULL; 26 | 27 | } 28 | ``` 29 | -------------------------------------------------------------------------------- /sword_to_offer/39_Tree_depth.md: -------------------------------------------------------------------------------- 1 | # source 2 | 3 | [offer39-二叉树深度](https://github.com/gatieme/CodingInterviews/tree/master/039-%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E6%B7%B1%E5%BA%A6) 4 | # solution 5 | 6 | ```cpp 7 | int TreeDepth(TreeNode* pRoot) 8 | { 9 | if (pRoot == NULL) 10 | return 0; 11 | return max(TreeDepth(pRoot->left),TreeDepth(pRoot->right))+1; 12 | } 13 | ``` 14 | -------------------------------------------------------------------------------- /sword_to_offer/39_balance_binaryTree.md: -------------------------------------------------------------------------------- 1 | # source 2 | 3 | [剑指offer-判断平衡二叉树](https://www.nowcoder.com/practice/8b3b95850edb4115918ecebdf1b4d222?tpId=13&tqId=11192&rp=2&ru=%2Fta%2Fcoding-interviews&qru=%2Fta%2Fcoding-interviews%2Fquestion-ranking) 4 | 5 | # solution 6 | 7 | ```cpp 8 | bool IsBalanced_Solution(TreeNode* pRoot) { 9 | int depth; 10 | return IsBalanced(pRoot, depth); 11 | } 12 | bool IsBalanced(TreeNode * pRoot, int &depth){ 13 | if (pRoot == NULL){ 14 | depth = 0; 15 | return true; 16 | } 17 | int leftDept = 0, rightDept = 0; 18 | if (IsBalanced(pRoot->left, leftDept) && IsBalanced(pRoot->right, rightDept)){ 19 | int diff = leftDept - rightDept; 20 | if (diff <= 1 && diff >= -1){ 21 | depth = max(leftDept, rightDept) + 1; 22 | return true; 23 | } 24 | return false; 25 | } 26 | return false; 27 | } 28 | ``` 29 | -------------------------------------------------------------------------------- /sword_to_offer/3_rebuild_tree.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | using namespace std; 4 | // Definition for binary tree 5 | struct TreeNode { 6 | int val; 7 | TreeNode *left; 8 | TreeNode *right; 9 | TreeNode(int x) : val(x), left(NULL), right(NULL) {} 10 | }; 11 | 12 | class Solution { 13 | public: 14 | TreeNode* reConstructBinaryTree(vector pre,vector vin) { 15 | if (pre.empty()) 16 | return NULL; 17 | TreeNode *root = new TreeNode(pre[0]); 18 | //cout<<"new "<val< left, right; 25 | vector front, end; 26 | while (it!=vin.end()){ 27 | if (*it == root->val) 28 | break; 29 | it++; 30 | itp++; 31 | } 32 | //cout<<"hehe"<left = reConstructBinaryTree(front, left); 42 | root->right = reConstructBinaryTree(end, right); 43 | return root; 44 | } 45 | void preprint(TreeNode*root){ 46 | if (!root) return; 47 | cout<val<left) preprint(root->left); 49 | if (root->right) preprint(root->right); 50 | } 51 | }; 52 | 53 | int main() 54 | { 55 | vector pre={1,2,4,7,3,5,6,8}; 56 | vector vin={4,7,2,1,5,3,8,6}; 57 | Solution a; 58 | auto t = a.reConstructBinaryTree(pre, vin); 59 | a.preprint(t); 60 | return 0; 61 | } -------------------------------------------------------------------------------- /sword_to_offer/45_the_last_nubmer.md: -------------------------------------------------------------------------------- 1 | # source 2 | 3 | [45-圆圈中的最后一个](https://github.com/gatieme/CodingInterviews/tree/master/045-%E5%AD%A9%E5%AD%90%E4%BB%AC%E7%9A%84%E6%B8%B8%E6%88%8F(%E5%9C%86%E5%9C%88%E4%B8%AD%E6%9C%80%E5%90%8E%E5%89%A9%E4%B8%8B%E7%9A%84%E6%95%B0)) 4 | 5 | # solution 6 | 7 | ## 循环链表方法 8 | 是约瑟夫换问题,使用循环链表,可以使用list来表示链表,list实现的是链表,vector实现的是数组 9 | 10 | 11 | ```cpp 12 | int LastRemaining_Solution(int n, int m) 13 | { 14 | if (n==0 || m==1) 15 | return -1; 16 | //先创建一个链表; 17 | list childs; 18 | for (int i = 0; i < n; i++) 19 | childs.push_back(i); 20 | //接下来遍历知道只剩下一个元素; 21 | list::iterator lit = childs.begin(); 22 | while (childs.size() > 1) 23 | { 24 | //找到第m个元素; 25 | for (int i = 1; i < m; i++) 26 | { 27 | lit++; 28 | if (lit == childs.end()) 29 | lit = childs.begin(); 30 | } 31 | //删除lit指向的这个元素; 32 | list::iterator tmp = lit; 33 | lit++; 34 | if (lit == childs.end()) 35 | lit = childs.begin(); 36 | childs.erase(tmp); 37 | } 38 | return *lit; 39 | } 40 | 41 | ``` 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /sword_to_offer/readme.md: -------------------------------------------------------------------------------- 1 | # 剑指offer的一些题目 2 | 3 | -13题: O(1)时间内删除一个结点 4 | 5 | -39题: 判断一个二叉树是不是平衡二叉树 6 | 7 | -37题: 两个链表的第一个公共节点 8 | 9 | -45题: 圆圈中的最后一个 10 | --------------------------------------------------------------------------------