├── stringmatch.md ├── find.md ├── res └── recursion_example.png ├── find ├── ST.cpp ├── main.cpp └── ST.h ├── alg-cpp.xcodeproj ├── xcuserdata │ └── junl.xcuserdatad │ │ └── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist └── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcuserdata │ ├── junl.xcuserdatad │ │ ├── UserInterfaceState.xcuserstate │ │ └── xcdebugger │ │ │ └── Breakpoints_v2.xcbkptlist │ └── junlongj.xcuserdatad │ │ └── UserInterfaceState.xcuserstate │ └── xcshareddata │ └── IDEWorkspaceChecks.plist ├── stack+queue ├── queue.cpp ├── leetcode │ ├── MyCircularDeque.cpp │ ├── maxSlidingWindow.h │ ├── MyCircularDeque.h │ ├── evalRPN.h │ └── longestValidParentheses.h ├── itinterviews │ ├── getMaxRectSize.h │ ├── TwoStacksQueue.h │ └── sortStackByStack.h ├── sampleBrowser.h ├── coding-interviews │ ├── validateStackSequences.h │ └── queueByStack.h └── stack.h ├── tiny_stl ├── src │ ├── map.h │ └── type_traits.h ├── main.cpp └── test │ ├── all_test.h │ ├── forward_test.h │ └── allocator_test.h ├── dp ├── leetcode │ ├── minPathSum.h │ └── easy │ │ └── climbStairs.h ├── main.cpp └── coinChange.h ├── sort ├── main.cpp ├── select.c ├── bubble.c ├── insert.c ├── bucketSort.h ├── sort.h ├── heap.c ├── kthSmallest.h ├── merge.c ├── quick.c ├── countingSort.h └── sort.c ├── bit ├── main.cpp └── maximizingXor.h ├── divideandconquer ├── closestPair.h └── main.cpp ├── skip_list.md ├── array ├── linearList.h ├── leetcode │ ├── easy │ │ ├── twoSum.h │ │ ├── searchInsert.h │ │ ├── plusOne.h │ │ ├── pascals_triangle_ii.h │ │ ├── twoSum_ii.h │ │ ├── majorityElement.h │ │ ├── best_time_to_buy_and_sell_stock.h │ │ ├── pascals_triangle.h │ │ ├── removeDuplicates.h │ │ ├── removeElement.h │ │ ├── maxSubArray.h │ │ └── best_time_to_buy_and_sell_stock_ii.h │ ├── maxArea.h │ ├── moveZeroes.h │ └── medium │ │ └── 3sum.h ├── coding-interviews │ ├── FindNumsAppearOnce.h │ ├── ReOrder.h │ ├── Find.h │ ├── GetNumberOfK.h │ ├── MoreThanHalfNum_Solution.h │ └── minNumberInRotateArray.h ├── DSIterator.h └── DSArray.h ├── hashTable └── main.cpp ├── hash.md ├── base ├── illegalParameterValue.h └── base.h ├── string ├── coding-interviews │ ├── removeRepeatChar.h │ ├── FirstNotRepeatingChar.h │ ├── StrToInt.h │ └── match.h ├── leetcode │ ├── easy │ │ ├── lengthOfLastWord.h │ │ ├── strStr.h │ │ └── romanToInt.h │ └── medium │ │ └── lengthOfLongestSubstring.h └── matching.h ├── recursion ├── coding-interviews │ ├── jumpFloorII.h │ ├── rectCover.h │ ├── jumpFloor.h │ └── Fibonacci.h ├── main.cpp └── leetcode │ └── medium │ └── longestUnivaluePath.h ├── bsearch ├── bsearch_findLastElementLessOrEqual.h ├── bsearch_findLastElement.h ├── bsearch_findFirstElement.h ├── bsearch_findFirstElementGreaterOrEqual.h ├── leetcode │ ├── isPerfectSquare.h │ ├── mySqrt.h │ └── medium │ │ ├── searchInRotatedSortedArray.h │ │ └── searchRange.h ├── bsearch.h └── main.cpp ├── tree ├── Tree.h ├── leetcode │ ├── maxDepth.h │ ├── minDepth.h │ ├── invertTree.h │ └── easy │ │ └── isSameTree.h ├── coding-interviews │ ├── treeToDoublyList.h │ ├── VerifySquenceOfBST.h │ ├── GetNext.h │ └── HasSubtree.h └── heap.h ├── linkedList ├── leetcode │ ├── easy │ │ ├── deleteDuplicates.h │ │ ├── getIntersectionNode.h │ │ └── hasCycle.h │ ├── reverseList.h │ ├── medium │ │ └── addTwoNumbers.h │ ├── isPalindrome.h │ ├── middleNode.h │ └── removeNthFromEnd.h ├── coding-interviews │ ├── creatlist.h │ ├── printListFromTailToHead.h │ ├── DeleteNodeO1.h │ ├── FindKthToTail.h │ ├── FindFirstCommonNode.h │ ├── Clone.h │ ├── deleteDuplication.h │ └── LastRemaining_Solution.h └── itinterviews │ ├── printCommonPart.h │ └── josephusKill.h ├── greed ├── coin_dispenser.h ├── shared_the_sweets.h ├── main.cpp ├── region_overlapping.h └── leetcode │ └── medium │ └── jump_game.h ├── backtracking ├── knapsack.h ├── coding-interviews │ └── hasPath.h ├── Pattern.h ├── leetcode │ └── medium │ │ ├── subsets.h │ │ ├── permutations.h │ │ ├── combinationSum.h │ │ └── subsets_ii.h ├── main.cpp └── eightQueens.h ├── other ├── leetcode │ ├── easy │ │ ├── reverse_integer.h │ │ ├── palindrome_number.h │ │ └── romanToInt.h │ └── medium │ │ └── next_permutation.h └── coding-interviews │ ├── IsContinuous2.h │ ├── NumberOf1.h │ ├── Power.h │ ├── GetUglyNumber_Solution.h │ ├── IsContinuous.h │ ├── NumberOf1Between1AndN_Solution.h │ └── FindNumbersWithSum.h ├── README.md ├── greed.md └── divideandconquer.md /stringmatch.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /find.md: -------------------------------------------------------------------------------- 1 | 本模块内容为《算法4》第3章内容,原书算法是用java实现,所以各API都为java规范,迁移到C++实现后,难免会跟C++规范有差异,后面有时间在纠正这一块. 2 | 3 | 4 | -------------------------------------------------------------------------------- /res/recursion_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jincc/iOS-Algorithm/HEAD/res/recursion_example.png -------------------------------------------------------------------------------- /find/ST.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // ST.cpp 3 | // find 4 | // 5 | // Created by junl on 2020/12/2. 6 | // Copyright © 2020 junl. All rights reserved. 7 | // 8 | 9 | #include "ST.h" 10 | -------------------------------------------------------------------------------- /alg-cpp.xcodeproj/xcuserdata/junl.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /stack+queue/queue.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // queue.cpp 3 | // stack+queue 4 | // 5 | // Created by junl on 2019/7/18. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #include "queue.h" 10 | -------------------------------------------------------------------------------- /alg-cpp.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /alg-cpp.xcodeproj/project.xcworkspace/xcuserdata/junl.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jincc/iOS-Algorithm/HEAD/alg-cpp.xcodeproj/project.xcworkspace/xcuserdata/junl.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /stack+queue/leetcode/MyCircularDeque.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // MyCircularDeque.cpp 3 | // stack+queue 4 | // 5 | // Created by junl on 2019/7/18. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #include "MyCircularDeque.h" 10 | -------------------------------------------------------------------------------- /alg-cpp.xcodeproj/project.xcworkspace/xcuserdata/junlongj.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jincc/iOS-Algorithm/HEAD/alg-cpp.xcodeproj/project.xcworkspace/xcuserdata/junlongj.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /alg-cpp.xcodeproj/project.xcworkspace/xcuserdata/junl.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | -------------------------------------------------------------------------------- /tiny_stl/src/map.h: -------------------------------------------------------------------------------- 1 | // 2 | // map.h 3 | // tiny_stl 4 | // 5 | // Created by junl on 2020/11/21. 6 | // Copyright © 2020 junl. All rights reserved. 7 | // 8 | 9 | #ifndef map_hpp 10 | #define map_hpp 11 | 12 | #include 13 | 14 | #endif /* map_hpp */ 15 | -------------------------------------------------------------------------------- /dp/leetcode/minPathSum.h: -------------------------------------------------------------------------------- 1 | // 2 | // minPathSum.h 3 | // dp 4 | // 5 | // Created by junl on 2019/7/26. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef minPathSum_hpp 10 | #define minPathSum_hpp 11 | 12 | #include 13 | 14 | #endif /* minPathSum_hpp */ 15 | -------------------------------------------------------------------------------- /alg-cpp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /find/main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // main.cpp 3 | // find 4 | // 5 | // Created by junl on 2020/12/2. 6 | // Copyright © 2020 junl. All rights reserved. 7 | // 8 | 9 | #include 10 | #include "ST.h" 11 | int main(int argc, const char * argv[]) { 12 | // insert code here... 13 | std::cout << "Hello, World!\n"; 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /sort/main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // main.cpp 3 | // sort 4 | // 5 | // Created by junl on 2019/7/18. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #include 10 | #include "sort.h" 11 | using namespace std; 12 | int main(int argc, const char * argv[]) { 13 | // insert code here... 14 | test_sort_drive(); 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /bit/main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // main.cpp 3 | // bit 4 | // 5 | // Created by junl on 2020/5/14. 6 | // Copyright © 2020 junl. All rights reserved. 7 | // 8 | 9 | #include 10 | #include "maximizingXor.h" 11 | int main(int argc, const char * argv[]) { 12 | // insert code here... 13 | int v = maxXor(1, 10); 14 | printf("%d\n", v); 15 | return 0; 16 | } 17 | -------------------------------------------------------------------------------- /divideandconquer/closestPair.h: -------------------------------------------------------------------------------- 1 | // 2 | // closestPair.h 3 | // divideConquer 4 | // 5 | // Created by junlongj on 2019/7/25. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef closestPair_hpp 10 | #define closestPair_hpp 11 | 12 | #include 13 | 14 | /* 15 | 二维平面上有n个点,如何快速求出最近的两个点之间的距离 16 | */ 17 | 18 | //TODO: 19 | #endif /* closestPair_hpp */ 20 | -------------------------------------------------------------------------------- /tiny_stl/main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // main.cpp 3 | // tiny_stl 4 | // 5 | // Created by junl on 2020/11/9. 6 | // Copyright © 2020 junl. All rights reserved. 7 | // 8 | 9 | #include 10 | #include "test.h" 11 | #include "all_test.h" 12 | #include 13 | int main(int argc, const char * argv[]) { 14 | // insert code here... 15 | std::cout << "Hello, World!\n"; 16 | RUN_ALL_TESTS(); 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /stack+queue/itinterviews/getMaxRectSize.h: -------------------------------------------------------------------------------- 1 | // 2 | // getMaxRectSize.h 3 | // stack+queue 4 | // 5 | // Created by junl on 2019/10/23. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef getMaxRectSize_hpp 10 | #define getMaxRectSize_hpp 11 | 12 | #include 13 | /* 14 | 求最大矩阵的大小 15 | 16 | 给定一个整形矩阵,其中的值只有0和1两种,求其中全是1的所有矩阵区域中,最大矩形区域为1的数量. 17 | 18 | 1 0 1 1 最大区域为6 19 | 1 1 1 1 20 | 1 1 1 0 21 | */ 22 | #endif /* getMaxRectSize_hpp */ 23 | -------------------------------------------------------------------------------- /sort/select.c: -------------------------------------------------------------------------------- 1 | // 2 | // select.c 3 | // sort 4 | // 5 | // Created by junl on 2020/12/1. 6 | // Copyright © 2020 junl. All rights reserved. 7 | // 8 | 9 | #include "sort.h" 10 | void sort_select(ItemType a[], int l, int r){ 11 | int i, j, min; 12 | for (i = l; i <= r; i++) { 13 | min = i; 14 | for (j = i+1; j <= r; j++) { 15 | if (less(a[j], a[min])) 16 | min = j; 17 | } 18 | exch(a[min], a[i]); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /tiny_stl/test/all_test.h: -------------------------------------------------------------------------------- 1 | // 2 | // all_test.h 3 | // tiny_stl 4 | // 5 | // Created by junl on 2020/11/11. 6 | // Copyright © 2020 junl. All rights reserved. 7 | // 8 | 9 | #ifndef all_test_h 10 | #define all_test_h 11 | 12 | #include "allocator_test.h" 13 | #include "forward_test.h" 14 | #include "pair_test.h" 15 | #include "iterator_test.h" 16 | #include "vector_test.h" 17 | #include "list_test.h" 18 | #include "deque_test.h" 19 | #include "unordered_map_test.h" 20 | #include "map_test.h" 21 | #endif /* all_test_h */ 22 | -------------------------------------------------------------------------------- /sort/bubble.c: -------------------------------------------------------------------------------- 1 | // 2 | // sort.c 3 | // sort 4 | // 5 | // Created by junl on 2020/12/1. 6 | // Copyright © 2020 junl. All rights reserved. 7 | // 8 | 9 | #include "sort.h" 10 | void sort_bubble(ItemType a[], int l, int r){ 11 | int i, j, changed; 12 | for (i = l ; i < r; i++) { 13 | for (j = r, changed = 0; j > i; j--) { 14 | if (less(a[j], a[j-1])) { 15 | exch(a[j], a[j-1]); 16 | changed = 1; 17 | } 18 | } 19 | if (!changed) break; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /find/ST.h: -------------------------------------------------------------------------------- 1 | // 2 | // ST.h 3 | // find 4 | // 5 | // Created by junl on 2020/12/2. 6 | // Copyright © 2020 junl. All rights reserved. 7 | // 8 | 9 | #ifndef ST_h 10 | #define ST_h 11 | 12 | template 13 | class ST { 14 | public: 15 | ST(); 16 | void put(Key key, Value value); 17 | Value get(Key key); 18 | void remove(Key key); 19 | bool contains(Key key) { 20 | return get(key); 21 | }; 22 | bool isEmpty(); 23 | int size(); 24 | virtual ~ST(){} 25 | }; 26 | 27 | #endif /* ST_h */ 28 | -------------------------------------------------------------------------------- /skip_list.md: -------------------------------------------------------------------------------- 1 | # 背景 2 | 为什么要有跳表这样的结构? 3 | 4 | 拿一个单链表来说,即便单链表的数据是有序的,如果我们想从里面查找一个指定的数,那么时间复杂度任然是O(N). 那么怎么才能是链表的查询速度变快呢? 5 | 6 | 这就是跳表这个数据结构,跳表就是在链表的基础上增加多级索引,从而提高查询速度的. 7 | 8 | ![](https://static001.geekbang.org/resource/image/49/65/492206afe5e2fef9f683c7cff83afa65.jpg) 9 | ![](https://static001.geekbang.org/resource/image/46/a9/46d283cd82c987153b3fe0c76dfba8a9.jpg) 10 | 11 | 12 | # 查询速度 13 | 14 | 跳表结构,每两个节点会抽出一个节点来作为上一级索引的节点,那么第一级节点的个数就是n/2, 第二级n/4..... 那么跳表的高度时间就是log2(N). 15 | 16 | 查询16的路径分析: 17 | 18 | 1->7->13->13(down)->13(down)->16 19 | 20 | 整个查询是log(N)级别的. 21 | 22 | 23 | -------------------------------------------------------------------------------- /stack+queue/leetcode/maxSlidingWindow.h: -------------------------------------------------------------------------------- 1 | // 2 | // maxSlidingWindow.h 3 | // stack+queue 4 | // 5 | // Created by junl on 2019/7/18. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef maxSlidingWindow_hpp 10 | #define maxSlidingWindow_hpp 11 | 12 | #include 13 | 14 | /* 15 | 239.给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口 k 内的数字。滑动窗口每次只向右移动一位。 16 | 17 | 返回滑动窗口最大值。 18 | 19 | 来源:力扣(LeetCode) 20 | 链接:https://leetcode-cn.com/problems/sliding-window-maximum 21 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 22 | */ 23 | #endif /* maxSlidingWindow_hpp */ 24 | -------------------------------------------------------------------------------- /tiny_stl/src/type_traits.h: -------------------------------------------------------------------------------- 1 | // 2 | // type_traits.h 3 | // tiny_stl 4 | // 5 | // Created by junl on 2020/11/13. 6 | // Copyright © 2020 junl. All rights reserved. 7 | // 8 | 9 | #ifndef type_traits_hpp 10 | #define type_traits_hpp 11 | 12 | namespace tiny{ 13 | template 14 | struct m_integer_constant{ 15 | static constexpr T value = v; 16 | }; 17 | template 18 | using m_bool_constant = m_integer_constant; 19 | 20 | typedef m_bool_constant m_true_type; 21 | typedef m_bool_constant m_false_type; 22 | } 23 | #endif /* type_traits_hpp */ 24 | -------------------------------------------------------------------------------- /array/linearList.h: -------------------------------------------------------------------------------- 1 | // 2 | // linearList.h 3 | // ALG-DS 4 | // 5 | // Created by junl on 2019/4/29. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef linearList_h 10 | #define linearList_h 11 | 12 | // 线性表抽象描述 base ADT 13 | template 14 | class linearList { 15 | public: 16 | virtual ~linearList(){}; 17 | virtual bool empty() const = 0; 18 | virtual int size() const = 0; 19 | virtual T& get(int index) = 0; 20 | virtual int indexOf(const T& element) const = 0; 21 | virtual void earse(int index) = 0; 22 | virtual void insert(int index, const T& element) = 0; 23 | }; 24 | #endif /* linearList_h */ 25 | -------------------------------------------------------------------------------- /sort/insert.c: -------------------------------------------------------------------------------- 1 | // 2 | // insert.c 3 | // sort 4 | // 5 | // Created by junl on 2020/12/1. 6 | // Copyright © 2020 junl. All rights reserved. 7 | // 8 | 9 | #include "sort.h" 10 | //依次将未排序数组中的元素插入到已排序数组中的指定位置 11 | void sort_insert(ItemType a[], int l, int r){ 12 | int i, j, min = l, v; 13 | for (i = l+1; i <= r; i++) { 14 | if (less(a[i], a[min])) min = i; 15 | } 16 | //数组a的第一个元素为最小元素, 避免内层循环的判断 17 | exch(a[min], a[l]); 18 | 19 | for (i = l + 2; i <= r ; i++) { 20 | v = a[i]; 21 | for (j = i; less(v, a[j-1]); j--) { 22 | a[j] = a[j-1];//如果v比前一个元素小,向后移动一位 23 | } 24 | a[j] = v; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /hashTable/main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // main.cpp 3 | // hasTable 4 | // 5 | // Created by junl on 2019/7/20. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #include 10 | #include "hash_map.h" 11 | 12 | class SampleHash { 13 | public: 14 | size_t operator()(const int &s) const 15 | { 16 | return s % 3; 17 | } 18 | }; 19 | int main(int argc, const char * argv[]) { 20 | // insert code here... 21 | std::cout << "Hello, World!\n"; 22 | 23 | hash_map test; 24 | for (int i=0; i<20; i++) { 25 | test[i] = i; 26 | } 27 | std::cout << test[1] << ' ' << test[2] << std::endl; 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /dp/main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // main.cpp 3 | // dp 4 | // 5 | // Created by junlongj on 2019/7/23. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #include 10 | #include "knapsack.h" 11 | #include "minPathSum.h" 12 | #include "climbStairs.h" 13 | #include "double11advance.h" 14 | #include "coinChange.h" 15 | #include "levenshtein_distance.h" 16 | #include "pascals_triangle.h" 17 | #include "matrix_move.h" 18 | int main(int argc, const char * argv[]) { 19 | // insert code here... 20 | using namespace std; 21 | test_double11advance(); 22 | test_knapsack(); 23 | test_coinChange(); 24 | test_levenshtein_distance(); 25 | test_pascals_triangle(); 26 | test_matrix_move(); 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /hash.md: -------------------------------------------------------------------------------- 1 | 2 | # 哈希算法 3 | 4 | 定义: 将任意长度的二进制值串映射为固定长度的二进制串,这个映射的规则就是哈希算法。哈希算法要满足几个要求: 5 | 6 | * 输入数据不管长短,输出都是固定的长度. 7 | * 对输入数据铭感,哪怕只是修改了一个bit,最后的哈希值也不一样 8 | * 哈希算法是单向的,就是说原始数据可以映射到哈希值,但是不能反向推导 9 | * 哈希冲突的概率要很小,劲量避免冲突 10 | * 执行效率要竟可能高效,不管是多长的文本,也能快速计算出哈希值。 11 | 12 | 13 | ## 哈希函数的应用 14 | 15 | 16 | [网络安全——数据的加密与签名,RSA介绍](https://www.cnblogs.com/mddblog/p/5380556.html) 17 | 18 | 19 | 1. 哈希算法可以对大数据做信息摘要,通过一个较短的摘要来作为唯一标识,作为身份的象征。比如:我们可以对图库里面的所有图片做hash运算,然后将结果保存到散列表中。这样当我们想要判断某张图片是否在图库中,就可以通过hash值来判断了,非常高效. 20 | 21 | 22 | 2. 哈希算法可以用来做数据校验,比如BT下载种子里面保存了源文件的哈希值,当用户下载完文件后,可以对下载后文件进行hash,然后比较判断是否文件下载成功或是否被篡改过。 23 | 24 | 3. 散列函数也是哈希函数的一种应用。散列函数对算法冲突的要求比较低,同时也并不关心是否能反向解密,它更关心的是散列后的值是否能平均分布,并且这种计算要足够高效,不然就会影响散列表的性能 25 | 4. hash + salt可以避免字典攻击 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /base/illegalParameterValue.h: -------------------------------------------------------------------------------- 1 | // 2 | // illegalParameterValue.hpp 3 | // ALG-DS 4 | // 5 | // Created by junl on 2019/4/22. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef illegalParameterValue_hpp 10 | #define illegalParameterValue_hpp 11 | #include 12 | #include 13 | 14 | class illegalParameterValue { 15 | public: 16 | illegalParameterValue(): message("Illegal parameter value"){} 17 | illegalParameterValue(const std::string& theMessage) {message = theMessage;} 18 | void outputMessage() {std::cout << message << std::endl;} 19 | private: 20 | std::string message; 21 | }; 22 | 23 | class stackEmpty { 24 | 25 | public: 26 | 27 | }; 28 | 29 | 30 | #endif /* illegalParameterValue_hpp */ 31 | -------------------------------------------------------------------------------- /bit/maximizingXor.h: -------------------------------------------------------------------------------- 1 | // 2 | // maximizingXor.h 3 | // bit 4 | // 5 | // Created by junl on 2020/5/14. 6 | // Copyright © 2020 junl. All rights reserved. 7 | // 8 | 9 | #ifndef maximizingXor_h 10 | #define maximizingXor_h 11 | 12 | /* 13 | 题目:https://www.hackerrank.com/challenges/maximizing-xor/problem 14 | 先通过异或运算求出a和b有哪些位不一样,这样我们就知道最左边的1位于什么位置了,通过不断的右移,这样就可以定位到最左边的位置. 那么最大值就为最左位为0,后面全为1. 因为 15 | 16 | LxorR可以知道不变位。从L到R的范围内,任意两个整数异或的结果可能都不一样,但是必然存在前几位相同的特性。例如:L= 11110,R=11010.在其范围内的AxorB的结果一定是00xxx的模式 17 | */ 18 | 19 | int maxXor(int a, int b){ 20 | int value = a ^ b, result = 1; 21 | while(value){ 22 | value = value >> 1; 23 | result = result << 1; 24 | } 25 | return result - 1; 26 | } 27 | #endif /* maximizingXor_h */ 28 | -------------------------------------------------------------------------------- /divideandconquer/main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // main.cpp 3 | // divideConquer 4 | // 5 | // Created by junlongj on 2019/7/25. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #include 10 | #include "reversedOrderPairs.h" 11 | int main(int argc, const char * argv[]) { 12 | // insert code here... 13 | using namespace std; 14 | cout << "数组里面的逆序对 starting.........." << endl; 15 | 16 | { 17 | int nums[] = {7,5,6,4,3,2,1}; 18 | printf("%d\n", reversedOrderPairs(nums, 7)); 19 | for(int i=0; i < 7; i++) 20 | printf(" %d",nums[i]); 21 | }; 22 | { 23 | int nums[] = {7,5,6,4,3,2,1}; 24 | printf("\n%d\n", reversePairs(nums, 7)); 25 | for(int i=0; i < 7; i++) 26 | printf(" %d",nums[i]); 27 | }; 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /stack+queue/leetcode/MyCircularDeque.h: -------------------------------------------------------------------------------- 1 | // 2 | // MyCircularDeque.h 3 | // stack+queue 4 | // 5 | // Created by junl on 2019/7/18. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef MyCircularDeque_hpp 10 | #define MyCircularDeque_hpp 11 | 12 | #include 13 | 14 | /* 15 | 641.设计实现双端队列。 16 | 你的实现需要支持以下操作: 17 | 18 | MyCircularDeque(k):构造函数,双端队列的大小为k。 19 | insertFront():将一个元素添加到双端队列头部。 如果操作成功返回 true。 20 | insertLast():将一个元素添加到双端队列尾部。如果操作成功返回 true。 21 | deleteFront():从双端队列头部删除一个元素。 如果操作成功返回 true。 22 | deleteLast():从双端队列尾部删除一个元素。如果操作成功返回 true。 23 | getFront():从双端队列头部获得一个元素。如果双端队列为空,返回 -1。 24 | getRear():获得双端队列的最后一个元素。 如果双端队列为空,返回 -1。 25 | isEmpty():检查双端队列是否为空。 26 | isFull():检查双端队列是否满了。 27 | 28 | 来源:力扣(LeetCode) 29 | 链接:https://leetcode-cn.com/problems/design-circular-deque 30 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 31 | */ 32 | 33 | 34 | #endif /* MyCircularDeque_hpp */ 35 | -------------------------------------------------------------------------------- /sort/bucketSort.h: -------------------------------------------------------------------------------- 1 | // 2 | // bucketSort.h 3 | // sort 4 | // 5 | // Created by junlongj on 2019/9/2. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef bucketSort_hpp 10 | #define bucketSort_hpp 11 | 12 | #include 13 | #include 14 | 15 | void test_bucketsort(){ 16 | using namespace std; 17 | int ages[] = {15,78,24,26,67,90,1,56,78}; 18 | const int bucket_cout = 100; 19 | int buckets[bucket_cout];//创建100个桶,代表0-99个年龄 20 | memset(buckets, 0, sizeof(buckets)); 21 | for (auto &age : ages) { 22 | buckets[age]+=1; 23 | } 24 | 25 | //依次从桶里面读出 26 | printf("test_bucketsort starting.........\n"); 27 | for (int i=0; i0) { 29 | printf("%i,",i); 30 | buckets[i]-=1; 31 | } 32 | } 33 | printf("\n"); 34 | } 35 | 36 | 37 | 38 | #endif /* bucketSort_hpp */ 39 | -------------------------------------------------------------------------------- /string/coding-interviews/removeRepeatChar.h: -------------------------------------------------------------------------------- 1 | // 2 | // removeRepeatChar.h 3 | // string 4 | // 5 | // Created by junl on 2020/5/18. 6 | // Copyright © 2020 junl. All rights reserved. 7 | // 8 | 9 | #ifndef removeRepeatChar_h 10 | #define removeRepeatChar_h 11 | 12 | namespace codinginterviews { 13 | void removeRepeatChar(char *s){ 14 | if (s == NULL) return ; 15 | 16 | bool hashMap[256]; 17 | memset(hashMap, false, sizeof(hashMap)); 18 | 19 | char *ptr0 , *ptr1; 20 | ptr0 = ptr1 = s; 21 | while (*ptr1 != '\0') { 22 | if (!hashMap[*ptr1]) { 23 | hashMap[*ptr1] = true; 24 | *ptr0++ = *ptr1; 25 | } 26 | ptr1++; 27 | } 28 | *ptr0 = '\0'; 29 | } 30 | void test_removeRepeatChar(){ 31 | printf("test_removeRepeatChar\n"); 32 | char s[] = "google"; 33 | removeRepeatChar(s); 34 | puts(s); 35 | } 36 | } 37 | 38 | #endif /* removeRepeatChar_h */ 39 | -------------------------------------------------------------------------------- /sort/sort.h: -------------------------------------------------------------------------------- 1 | // 2 | // sort.h 3 | // sort 4 | // 5 | // Created by junl on 2020/12/1. 6 | // Copyright © 2020 junl. All rights reserved. 7 | // 8 | 9 | #ifndef sort_h 10 | #define sort_h 11 | 12 | #include 13 | 14 | typedef int ItemType; 15 | #define key(A) (A) 16 | #define less(A, B) (key(A) < key(B)) 17 | #define exch(A, B) {ItemType t = A; A = B; B = t;} 18 | #define compexch(A, B) if (less(B, A)) exch(A, B) 19 | 20 | #ifdef __cplusplus 21 | extern "C" { 22 | #endif 23 | void sort_bubble(ItemType a[], int l, int r); 24 | void sort_insert(ItemType a[], int l, int r); 25 | void sort_select(ItemType a[], int l, int r); 26 | void sort_merge(ItemType a[], int l, int r); 27 | void sort_quick(ItemType a[], int l, int r); 28 | void sort_heap(ItemType a[], int l, int r); 29 | 30 | typedef int(*Compare)(ItemType a[], int i, int j); 31 | //驱动程序 32 | void test_sort_drive(void); 33 | #ifdef __cplusplus 34 | } 35 | #endif 36 | #endif /* sort_h */ 37 | -------------------------------------------------------------------------------- /array/leetcode/easy/twoSum.h: -------------------------------------------------------------------------------- 1 | // 2 | // twoSum.h 3 | // array 4 | // 5 | // Created by junlongj on 2019/8/6. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef twoSum_hpp 10 | #define twoSum_hpp 11 | 12 | #include 13 | #include 14 | namespace leetcode { 15 | /* 16 | 1.两数之和 17 | 18 | 思路:通过集合来保存之前遍历过的元素,这样每次查找的时候先判断target-当前值的元素在不在hash table里面,就可以计算出结果了. 19 | */ 20 | std::vector twoSum(std::vector& nums, int target) { 21 | std::map mm;//key为当前值,value为下标 22 | std::vector result; 23 | for (int i=0;i 13 | #include 14 | #include 15 | #include "stack.h" 16 | class sampleBrowser { 17 | public: 18 | void open(const std::string &url){ 19 | aStack.push(url); 20 | } 21 | void goBack(){ 22 | std::string &url = aStack.pop(); 23 | bStack.push(url); 24 | } 25 | void goForward(){ 26 | std::string &url = bStack.pop(); 27 | aStack.push(url); 28 | } 29 | void checkCurrentPage(){ 30 | std::cout << "checkCurrentPage : " << aStack.topElement() << std::endl; 31 | } 32 | 33 | private: 34 | stack aStack; 35 | stack bStack; 36 | }; 37 | 38 | #endif /* sampleBrowser_hpp */ 39 | -------------------------------------------------------------------------------- /recursion/coding-interviews/jumpFloorII.h: -------------------------------------------------------------------------------- 1 | // 2 | // jumpFloorII.h 3 | // recursion 4 | // 5 | // Created by junlongj on 2019/8/4. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef jumpFloorII_hpp 10 | #define jumpFloorII_hpp 11 | 12 | #include 13 | /* 14 | 剑指Offer(九):变态跳台阶 15 | 一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。 16 | https://www.nowcoder.com/practice/22243d016f6b47f2a6928b4313c85387?tpId=13&tqId=11162&tPage=1&rp=1&ru=%2Fta%2Fcoding-interviews&qru=%2Fta%2Fcoding-interviews%2Fquestion-ranking 17 | 18 | */ 19 | namespace codinginterviews { 20 | /* 21 | n == 1 1 22 | n == 2 2 23 | n == 3 4 24 | ..... 25 | */ 26 | int jumpFloorII(int number) { 27 | if (number == 0)return 0; 28 | int step = 1; 29 | for (int i= 1; i 13 | /* 14 | 查找最后一个小于等于给定值的元素 15 | */ 16 | int bsearch_findLastElementLessOrEqual(int nums[], int n,int target){ 17 | if (n <= 0) return -1; 18 | int left = 0; 19 | int right = n-1; 20 | while(left<=right){ 21 | int mid = left+((right-left)>>1); 22 | if (nums[mid] <= target){ 23 | //已经是小于等于给定值的元素,找到最后一个 24 | if (mid == n-1 || nums[mid+1] > target){ 25 | return mid; 26 | } 27 | left = mid + 1; 28 | }else{ 29 | right = mid -1; 30 | } 31 | } 32 | return -1; 33 | } 34 | 35 | #endif /* bsearch_findLastElementLessOrEqual_hpp */ 36 | -------------------------------------------------------------------------------- /tree/Tree.h: -------------------------------------------------------------------------------- 1 | // 2 | // Tree.h 3 | // tree 4 | // 5 | // Created by junl on 2020/5/13. 6 | // Copyright © 2020 junl. All rights reserved. 7 | // 8 | 9 | #ifndef Tree_h 10 | #define Tree_h 11 | 12 | #ifdef __cplusplus 13 | extern "C" { 14 | #endif 15 | typedef struct BTreeNode BTreeNode; 16 | struct BTreeNode{ 17 | int val; 18 | BTreeNode *left; 19 | BTreeNode *right; 20 | }; 21 | BTreeNode *creatTreeNode(int val); 22 | BTreeNode *creatTree(int vals[], int n); 23 | void preOrder(BTreeNode *pTree); 24 | void preOrderIterate(BTreeNode *pTree); 25 | void inOrder(BTreeNode *pTree); 26 | void inOrderIterate(BTreeNode *pTree); 27 | void postOrder(BTreeNode *pTree); 28 | void postOrderIterate(BTreeNode *pTree); 29 | void levelOrder(BTreeNode *pTree); 30 | 31 | //根据前序遍历和中序遍历构建二叉树 32 | BTreeNode *construct(int preorder[], int inorder[], int size); 33 | #ifdef __cplusplus 34 | } 35 | #endif 36 | 37 | #endif /* Tree_h */ 38 | -------------------------------------------------------------------------------- /tree/leetcode/maxDepth.h: -------------------------------------------------------------------------------- 1 | // 2 | // maxDepth.h 3 | // tree 4 | // 5 | // Created by junl on 2019/8/1. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef maxDepth_hpp 10 | #define maxDepth_hpp 11 | 12 | #include 13 | /* 14 | 104.给定一个二叉树,找出其最大深度。 15 | 16 | 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。 17 | 18 | 说明: 叶子节点是指没有子节点的节点。 19 | 20 | 示例: 21 | 给定二叉树 [3,9,20,null,null,15,7], 22 | 23 | 3 24 | / \ 25 | 9 20 26 | / \ 27 | 15 7 28 | 返回它的最大深度 3 。 29 | 30 | 31 | 32 | 来源:力扣(LeetCode) 33 | 链接:https://leetcode-cn.com/problems/maximum-depth-of-binary-tree 34 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 35 | */ 36 | 37 | namespace leetcode { 38 | int maxDepth(TreeNode* root) { 39 | if (!root) { 40 | return 0; 41 | } 42 | int leftDepth = maxDepth(root->lchild); 43 | int rightDepth = maxDepth(root->rchild); 44 | return std::max(leftDepth, rightDepth) + 1; 45 | } 46 | } 47 | #endif /* maxDepth_hpp */ 48 | -------------------------------------------------------------------------------- /dp/leetcode/easy/climbStairs.h: -------------------------------------------------------------------------------- 1 | // 2 | // climbStairs.h 3 | // dp 4 | // 5 | // Created by junlongj on 2019/8/14. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef climbStairs_hpp 10 | #define climbStairs_hpp 11 | 12 | #include 13 | /* 14 | 70.爬楼梯 15 | 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 16 | 17 | 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢? 18 | 19 | 注意:给定 n 是一个正整数。 20 | 21 | 示例 1: 22 | 23 | 输入: 2 24 | 输出: 2 25 | 解释: 有两种方法可以爬到楼顶。 26 | 1. 1 阶 + 1 阶 27 | 2. 2 阶 28 | 29 | 来源:力扣(LeetCode) 30 | 链接:https://leetcode-cn.com/problems/climbing-stairs 31 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 32 | */ 33 | namespace leetcode { 34 | int climbStairs(int n) { 35 | if (n == 0) return 0; 36 | if (n == 1) return 1; 37 | if (n == 2) return 2; 38 | int dp[n]; 39 | dp[0] = 1; 40 | dp[1] = 2; 41 | for (int i=2;i 13 | /* 14 | 给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次。 15 | 16 | 示例 1: 17 | 18 | 输入: 1->1->2 19 | 输出: 1->2 20 | 示例 2: 21 | 22 | 输入: 1->1->2->3->3 23 | 输出: 1->2->3 24 | 25 | 来源:力扣(LeetCode) 26 | 链接:https://leetcode-cn.com/problems/remove-duplicates-from-sorted-list 27 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 28 | */ 29 | 30 | namespace leetcode { 31 | ListNode* deleteDuplicates(ListNode* head) { 32 | ListNode *ct=head; 33 | while(ct && ct->next){ 34 | if (ct->val == ct->next->val){ 35 | ct->next=ct->next->next; 36 | }else{ 37 | ct=ct->next; 38 | } 39 | } 40 | return head; 41 | } 42 | } 43 | #endif /* deleteDuplicates_hpp */ 44 | -------------------------------------------------------------------------------- /bsearch/bsearch_findLastElement.h: -------------------------------------------------------------------------------- 1 | // 2 | // bsearch_findLastElement.h 3 | // bsearch 4 | // 5 | // Created by junl on 2019/9/4. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef bsearch_findLastElement_hpp 10 | #define bsearch_findLastElement_hpp 11 | 12 | #include 13 | /* 14 | 有序数组中,存在着相同的元素,找到最后一个值等于指定元素的位置 15 | */ 16 | 17 | int bsearch_findLastElement(int nums[], int n,int target){ 18 | if (n <= 0) { 19 | return -1; 20 | } 21 | int left=0; 22 | int right=n-1; 23 | while (left<=right) { 24 | int mid = left+((right-left)>>1); 25 | if (nums[mid] < target) { 26 | left = mid+1; 27 | }else if (nums[mid] > target){ 28 | right=mid-1; 29 | }else{ 30 | //找到了target,我们判断它是否是最后一个 31 | if (mid == n-1 || nums[mid+1] !=target) { 32 | return mid; 33 | } 34 | left=mid+1; 35 | } 36 | } 37 | return -1; 38 | } 39 | 40 | #endif /* bsearch_findLastElement_hpp */ 41 | -------------------------------------------------------------------------------- /bsearch/bsearch_findFirstElement.h: -------------------------------------------------------------------------------- 1 | // 2 | // bsearch_findFirstElement.h 3 | // bsearch 4 | // 5 | // Created by junlongj on 2019/9/4. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef bsearch_findFirstElement_hpp 10 | #define bsearch_findFirstElement_hpp 11 | 12 | #include 13 | 14 | /* 15 | 有序数组中,存在着相同的元素,找到指定元素的第一个值. 16 | */ 17 | 18 | int bsearch_findFirstElement(int nums[], int n,int target){ 19 | if (n <= 0) { 20 | return -1; 21 | } 22 | int left=0; 23 | int right=n-1; 24 | while (left<=right) { 25 | int mid = left+((right-left)>>1); 26 | if (nums[mid] < target) { 27 | left = mid+1; 28 | }else if (nums[mid] > target){ 29 | right=mid-1; 30 | }else{ 31 | //找到了target,我们判断它是否是第一个 32 | if (mid == 0 || nums[mid-1] != target) { 33 | return mid; 34 | } 35 | right = mid-1; 36 | } 37 | } 38 | return -1; 39 | } 40 | #endif /* bsearch_findFirstElement_hpp */ 41 | -------------------------------------------------------------------------------- /bsearch/bsearch_findFirstElementGreaterOrEqual.h: -------------------------------------------------------------------------------- 1 | // 2 | // bsearch_findFirstElementGreaterOrEqual.h 3 | // bsearch 4 | // 5 | // Created by junl on 2019/9/4. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef bsearch_findFirstElementGreaterOrEqual_hpp 10 | #define bsearch_findFirstElementGreaterOrEqual_hpp 11 | 12 | #include 13 | /* 14 | 有序数组中,存在着相同的元素, 查找第一个大于等于指定元素的值. 15 | */ 16 | int bsearch_findFirstElementGreaterOrEqual(int nums[], int n,int target){ 17 | //首先找到大于等于指定元素的值,然后判断它是否是第一个. 18 | if (n <= 0) return -1; 19 | int left = 0; 20 | int right = n-1; 21 | while(left<=right){ 22 | int mid = left+((right-left)>>1); 23 | if (nums[mid] >= target){ 24 | //已经是大于等于target的值了,找到第一个 25 | if (mid == 0 || nums[mid-1] < target){ 26 | return mid; 27 | } 28 | right = mid -1; 29 | }else{ 30 | left = mid+1; 31 | } 32 | } 33 | return -1; 34 | 35 | } 36 | 37 | 38 | 39 | #endif /* bsearch_findFirstElementGreaterOrEqual_hpp */ 40 | -------------------------------------------------------------------------------- /bsearch/leetcode/isPerfectSquare.h: -------------------------------------------------------------------------------- 1 | // 2 | // isPerfectSquare.h 3 | // bsearch 4 | // 5 | // Created by junl on 2019/7/19. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef isPerfectSquare_hpp 10 | #define isPerfectSquare_hpp 11 | 12 | #include 13 | /* 14 | 367.给定一个正整数 num,编写一个函数,如果 num 是一个完全平方数,则返回 True,否则返回 False。 15 | 16 | 说明:不要使用任何内置的库函数,如  sqrt。 17 | 18 | 示例 1: 19 | 20 | 输入:16 21 | 输出:True 22 | 示例 2: 23 | 24 | 输入:14 25 | 输出:False 26 | 27 | 来源:力扣(LeetCode) 28 | 链接:https://leetcode-cn.com/problems/valid-perfect-square 29 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 30 | */ 31 | 32 | bool isPerfectSquare(int num) { 33 | if (num<=1) return true; 34 | int left=1; 35 | int right=num/2; 36 | while (left=num/mid) { 39 | //至少mid^2大于num 40 | right=mid; 41 | } else { 42 | //mid^2无限逼近num 43 | left=mid+1; 44 | } 45 | } 46 | return (long)left*left == num; 47 | } 48 | 49 | #endif /* isPerfectSquare_hpp */ 50 | -------------------------------------------------------------------------------- /recursion/coding-interviews/rectCover.h: -------------------------------------------------------------------------------- 1 | // 2 | // rectCover.h 3 | // recursion 4 | // 5 | // Created by junlongj on 2019/8/4. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef rectCover_hpp 10 | #define rectCover_hpp 11 | 12 | #include 13 | /* 14 | 剑指Offer(十):矩形覆盖 15 | 我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法? 16 | https://www.nowcoder.com/practice/72a5a919508a4251859fb2cfb987a0e6?tpId=13&tqId=11163&tPage=1&rp=1&ru=%2Fta%2Fcoding-interviews&qru=%2Fta%2Fcoding-interviews%2Fquestion-ranking 17 | */ 18 | 19 | namespace codinginterviews { 20 | /* 21 | 这个问题实际上就是Fibonacci数列的问题。 22 | 就拿2*5的格子来说,定义为f(5).第一行我们可以顺着放,那么f5=f(4). 23 | 如果第一行我们横着放,占用了两格,那么f5=f3; 24 | 所以f5=f4+f3. 25 | */ 26 | int rectCover(int n) { 27 | int f0,f1,f2; 28 | f0 = 0; 29 | f1 = 1; 30 | if (n == 0) return f0; 31 | if (n == 1) return f1; 32 | for (int i=2; i<=n; i++) { 33 | f2 = f0+f1; 34 | f0 = f1; 35 | f1 = f2; 36 | } 37 | return f2; 38 | } 39 | } 40 | 41 | #endif /* rectCover_hpp */ 42 | -------------------------------------------------------------------------------- /greed/coin_dispenser.h: -------------------------------------------------------------------------------- 1 | // 2 | // coin_dispenser.h 3 | // greed 4 | // 5 | // Created by junl on 2019/9/9. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef coin_dispenser_hpp 10 | #define coin_dispenser_hpp 11 | 12 | #include 13 | #include 14 | using namespace std; 15 | 16 | /** 17 | 假设我们有100元,50,20,10,5,2,1这些面额的纸币,它们分别的张数为a1,a2,a3....张. 18 | 题目是使用最少的纸币数目来支付K元. 19 | */ 20 | int coin_dispenser(vector &cointypes,vector &coincounts, int targetmoney){ 21 | /* 22 | 限制值:筹齐这targetmoney 23 | 期望值: 纸币数量最小 24 | 贪心思想:对于贡献一张纸币来说(期望值),我们肯定希望它的价值越大,因为这样意味着更少的张数. 25 | */ 26 | int count=0; 27 | for (size_t i=cointypes.size()-1; i>=0;) { 28 | if (targetmoney <= 0 ) 29 | break; 30 | 31 | if (targetmoney >= cointypes[i] && coincounts[i]>0) { 32 | count++; 33 | coincounts[i]--; 34 | targetmoney -= cointypes[i]; 35 | }else{ 36 | i--; 37 | } 38 | } 39 | if (targetmoney > 0) { 40 | throw "钱不够啊"; 41 | } 42 | return count; 43 | } 44 | 45 | #endif /* coin_dispenser_hpp */ 46 | -------------------------------------------------------------------------------- /linkedList/coding-interviews/creatlist.h: -------------------------------------------------------------------------------- 1 | // 2 | // creatlist.h 3 | // linkedList 4 | // 5 | // Created by junl on 2019/8/2. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef creatlist_hpp 10 | #define creatlist_hpp 11 | 12 | #include 13 | #include 14 | 15 | namespace codinginterviews { 16 | ListNode *creatLists(const std::vector &s){ 17 | ListNode *root = new ListNode(0); 18 | ListNode *node = root; 19 | auto it = s.begin(); 20 | while (it != s.end()) { 21 | node->next = new ListNode(*it); 22 | node = node->next; 23 | it++; 24 | } 25 | return root; 26 | } 27 | DoubleNode *creatDoubleLists(const std::vector &s){ 28 | DoubleNode *root = new DoubleNode(0); 29 | DoubleNode *node = root; 30 | auto it = s.begin(); 31 | while (it != s.end()) { 32 | node->next = new DoubleNode(*it); 33 | node->next->pre = node; 34 | node = node->next; 35 | it++; 36 | } 37 | return root; 38 | } 39 | } 40 | 41 | #endif /* creatlist_hpp */ 42 | -------------------------------------------------------------------------------- /backtracking/knapsack.h: -------------------------------------------------------------------------------- 1 | // 2 | // knapsack.h 3 | // backtracking 4 | // 5 | // Created by junl on 2019/7/25. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef knapsack_hpp 10 | #define knapsack_hpp 11 | 12 | #include 13 | /** 14 | 0-1背包问题. 对于一组不同质量,不可分割的物品,我们需要选择一些放入背包中,在满足最大重量限制的条件下,背包中所能放入的最大值是多少? 15 | */ 16 | 17 | void backpack01_bt(int weights[], int n, int level, int ctweight,int limitweight, int *result); 18 | int backpack01(int weights[], int n, int limitweight){ 19 | int result = 0; 20 | backpack01_bt(weights, n, 0, 0, limitweight, &result); 21 | return result; 22 | } 23 | void backpack01_bt(int weights[], int n,int level, int ctweight,int limitweight, int *result){ 24 | if (level == n || *result == limitweight){ 25 | if (*result < ctweight){ 26 | *result = ctweight; 27 | } 28 | return; 29 | } 30 | 31 | backpack01_bt(weights, n, level+1, ctweight, limitweight, result); 32 | if (ctweight + weights[level] <= limitweight) 33 | backpack01_bt(weights, n, level+1, ctweight + weights[level], limitweight, result); 34 | 35 | } 36 | #endif /* knapsack_hpp */ 37 | -------------------------------------------------------------------------------- /bsearch/leetcode/mySqrt.h: -------------------------------------------------------------------------------- 1 | // 2 | // mySqrt.h 3 | // bsearch 4 | // 5 | // Created by junl on 2019/7/19. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef mySqrt_hpp 10 | #define mySqrt_hpp 11 | 12 | #include 13 | /* 14 | 69.实现 int sqrt(int x) 函数。 15 | 16 | 计算并返回 x 的平方根,其中 x 是非负整数。 17 | 18 | 由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去。 19 | 20 | 示例 1: 21 | 22 | 输入: 4 23 | 输出: 2 24 | 示例 2: 25 | 26 | 输入: 8 27 | 输出: 2 28 | 说明: 8 的平方根是 2.82842..., 29 |   由于返回类型是整数,小数部分将被舍去。 30 | 31 | 32 | 来源:力扣(LeetCode) 33 | 链接:https://leetcode-cn.com/problems/sqrtx 34 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 35 | 36 | */ 37 | 38 | int mySqrt(int x) { 39 | if (x==1) 40 | return 1; 41 | int start=0; 42 | //the sqt is not greater than x/2+1 43 | int end=x/2+1; 44 | while (start <= end) { 45 | int mid = start + ((end-start)>>1); 46 | 47 | if (mid < x / mid) {//用除法不用乘法防止越界 48 | start = mid+1; 49 | }else if (mid > x / mid){ 50 | end = mid-1; 51 | }else{ 52 | return mid; 53 | } 54 | } 55 | return end; 56 | } 57 | #endif /* mySqrt_hpp */ 58 | -------------------------------------------------------------------------------- /greed/shared_the_sweets.h: -------------------------------------------------------------------------------- 1 | // 2 | // shared_the_sweets.h 3 | // greed 4 | // 5 | // Created by junl on 2019/9/9. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef shared_the_sweets_hpp 10 | #define shared_the_sweets_hpp 11 | 12 | #include 13 | #include 14 | 15 | using namespace std; 16 | 17 | /** 18 | 分糖果. 把m个糖果分给n个孩子,只有当糖果的大小大于孩子期望的大小时,孩子才会得到满足. 19 | 20 | @param sweets m个糖果分别的大小 21 | @param childwants 孩子们每个人期望的糖果大小. 22 | @return 能得到满足的孩子数量 23 | */ 24 | int shared_the_sweets(vector &sweets, vector &childwants){ 25 | /* 26 | 限制条件:一共只有m个糖果。 27 | 期望值: 希望得到满足的孩子数量最大. 28 | 贪心思想: 要求糖果大小越小的孩子越容易满足,对于期望值来说,满足它跟满足要大糖果的孩子是一样的,所以我们优先满足它。 29 | */ 30 | sort(sweets.begin(), sweets.end()); 31 | sort(childwants.begin(), childwants.end()); 32 | int count = 0; 33 | for (int i=0,j=0; i= childwants[i]) { 36 | count++;//孩子得到了满足 37 | i++; 38 | }else{ 39 | } 40 | } 41 | return count; 42 | } 43 | 44 | #endif /* shared_the_sweets_hpp */ 45 | -------------------------------------------------------------------------------- /array/leetcode/easy/searchInsert.h: -------------------------------------------------------------------------------- 1 | // 2 | // searchInsert.h 3 | // array 4 | // 5 | // Created by junlongj on 2019/8/7. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef searchInsert_hpp 10 | #define searchInsert_hpp 11 | 12 | #include 13 | #include 14 | /* 15 | 35. 搜索插入位置 16 | 17 | 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 18 | 19 | 你可以假设数组中无重复元素。 20 | 21 | 示例 1: 22 | 23 | 输入: [1,3,5,6], 5 24 | 输出: 2 25 | 26 | 来源:力扣(LeetCode) 27 | 链接:https://leetcode-cn.com/problems/search-insert-position 28 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 29 | */ 30 | namespace leetcode { 31 | int searchInsert(std::vector& nums, int target) { 32 | if (nums.empty()) 33 | return 0; 34 | int l=0; 35 | int r=nums.size()-1; 36 | while(l<=r){ 37 | int mid = l+(r-l)/2; 38 | if (nums[mid] == target){ 39 | return mid; 40 | }else if (nums[mid] < target){ 41 | l = mid+1; 42 | }else{ 43 | r = mid-1; 44 | } 45 | } 46 | return l; 47 | } 48 | } 49 | #endif /* searchInsert_hpp */ 50 | -------------------------------------------------------------------------------- /other/leetcode/easy/reverse_integer.h: -------------------------------------------------------------------------------- 1 | // 2 | // reverse_integer.h 3 | // other 4 | // 5 | // Created by junlongj on 2019/8/11. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef reverse_integer_hpp 10 | #define reverse_integer_hpp 11 | 12 | #include 13 | /* 14 | 7. 整数反转 15 | 16 | 给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。 17 | 18 | 示例 1: 19 | 20 | 输入: 123 21 | 输出: 321 22 |  示例 2: 23 | 24 | 输入: -123 25 | 输出: -321 26 | 示例 3: 27 | 28 | 输入: 120 29 | 输出: 21 30 | 31 | 来源:力扣(LeetCode) 32 | 链接:https://leetcode-cn.com/problems/reverse-integer 33 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 34 | */ 35 | 36 | namespace leetcode { 37 | //这个题提交失败了多次,关键在于如何确保数据不会溢出。 38 | int reverse(int x) { 39 | int result=0; 40 | while(x){ 41 | int v=x%10; 42 | //int最大值是2147483647,最小值是-2147483648 43 | if (result > INT_MAX/10){ 44 | return 0; 45 | } 46 | if (result < INT_MIN/10){ 47 | return 0; 48 | } 49 | result=result*10+v; 50 | x/=10; 51 | } 52 | return result; 53 | } 54 | } 55 | #endif /* reverse_integer_hpp */ 56 | -------------------------------------------------------------------------------- /string/leetcode/easy/lengthOfLastWord.h: -------------------------------------------------------------------------------- 1 | // 2 | // lengthOfLastWord.h 3 | // string 4 | // 5 | // Created by junlongj on 2019/8/14. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef lengthOfLastWord_hpp 10 | #define lengthOfLastWord_hpp 11 | 12 | #include 13 | #include 14 | /* 15 | 58. 最后一个单词的长度 16 | 给定一个仅包含大小写字母和空格 ' ' 的字符串,返回其最后一个单词的长度。 17 | 18 | 如果不存在最后一个单词,请返回 0 。 19 | 20 | 说明:一个单词是指由字母组成,但不包含任何空格的字符串。 21 | 22 | 示例: 23 | 24 | 输入: "Hello World" 25 | 输出: 5 26 | 27 | 28 | 来源:力扣(LeetCode) 29 | 链接:https://leetcode-cn.com/problems/length-of-last-word 30 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 31 | */ 32 | namespace leetcode { 33 | int lengthOfLastWord(std::string s) { 34 | int length=0; 35 | if (s.empty()) return 0; 36 | bool ch = false;//是否已经出现过字符 37 | for(int i=s.length()-1;i>=0;i--){ 38 | if (s[i] == ' '){ 39 | if (ch){ 40 | return length; 41 | } 42 | }else{ 43 | ch = true; 44 | length++; 45 | } 46 | } 47 | return ch ? length : 0 ; 48 | } 49 | } 50 | #endif /* lengthOfLastWord_hpp */ 51 | -------------------------------------------------------------------------------- /other/coding-interviews/IsContinuous2.h: -------------------------------------------------------------------------------- 1 | // 2 | // IsContinuous2.h 3 | // other 4 | // 5 | // Created by junl on 2020/1/13. 6 | // Copyright © 2020 junl. All rights reserved. 7 | // 8 | 9 | #ifndef IsContinuous2_hpp 10 | #define IsContinuous2_hpp 11 | 12 | #include 13 | #include 14 | 15 | namespace codinginterviews { 16 | using namespace std; 17 | bool IsContinuous2( vector numbers ) { 18 | sort(numbers.begin(), numbers.end()); 19 | 20 | int offset = 0; 21 | int zerocount = numbers[0] == 0; 22 | for (int i=1;i < numbers.size();i++){ 23 | if (numbers[i] == 0){ 24 | zerocount++; 25 | continue; 26 | } 27 | if (numbers[i] == numbers[i-1]){ 28 | return false; 29 | } 30 | offset += numbers[i] - numbers[i-1] - 1; 31 | } 32 | return offset <= zerocount ? true : false ; 33 | } 34 | 35 | void test_IsContinuous2(){ 36 | vector nums{1,3,4,6,0}; 37 | cout << "-------test_IsContinuous2------" << endl; 38 | cout << IsContinuous2(nums) << endl; 39 | } 40 | } 41 | 42 | #endif /* IsContinuous2_hpp */ 43 | -------------------------------------------------------------------------------- /sort/heap.c: -------------------------------------------------------------------------------- 1 | // 2 | // heap.c 3 | // sort 4 | // 5 | // Created by junl on 2020/12/2. 6 | // Copyright © 2020 junl. All rights reserved. 7 | // 8 | 9 | #include "sort.h" 10 | 11 | int cmp(ItemType a[], int i, int j) { 12 | return less(a[i], a[j]); 13 | } 14 | //上浮操作,将制定元素上浮到它应该在的位置 15 | void swim(ItemType a[], int n, int idx, Compare cmp){ 16 | while (idx > 1 && cmp(a, idx/2, idx)) { 17 | exch(a[idx/2], a[idx]); 18 | idx /= 2; 19 | } 20 | } 21 | //下沉操作,将制定元素下沉到它应该在的位置 22 | void sink(ItemType a[], int n, int idx, Compare cmp){ 23 | while (2 * idx <= n) { 24 | int j = 2 * idx; 25 | if (j+1 <= n && cmp(a, j, j+1)) { 26 | j++; 27 | } 28 | if (cmp(a, idx, j)) { 29 | //swap 30 | exch(a[idx], a[j]); 31 | idx = j; 32 | }else break; 33 | } 34 | } 35 | void sort_heap(ItemType a[], int l, int r){ 36 | //构建初始堆 37 | int k, n; 38 | n = r - l + 1; 39 | for (k = n / 2; k >= 1; k--) { 40 | sink(a, n, k, cmp); 41 | } 42 | //依次将堆首的最大元素放到数组末尾,并将堆的大小缩短,直到堆被缩短完成 43 | for (k = n-1; k>1; ) { 44 | exch(a[1], a[k]); 45 | k--; 46 | sink(a, k, 1, cmp); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /array/leetcode/easy/plusOne.h: -------------------------------------------------------------------------------- 1 | // 2 | // plusOne.h 3 | // array 4 | // 5 | // Created by junlongj on 2019/7/28. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef plusOne_hpp 10 | #define plusOne_hpp 11 | 12 | #include 13 | #include 14 | 15 | /* 16 | 66.给定一个由整数组成的非空数组所表示的非负整数,在该数的基础上加一。 17 | 18 | 最高位数字存放在数组的首位, 数组中每个元素只存储一个数字。 19 | 20 | 你可以假设除了整数 0 之外,这个整数不会以零开头。 21 | 22 | 示例 1: 23 | 24 | 输入: [1,2,3] 25 | 输出: [1,2,4] 26 | 解释: 输入数组表示数字 123。 27 | 示例 2: 28 | 29 | 输入: [4,3,2,1] 30 | 输出: [4,3,2,2] 31 | 解释: 输入数组表示数字 4321。 32 | 33 | 来源:力扣(LeetCode) 34 | 链接:https://leetcode-cn.com/problems/plus-one 35 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 36 | 37 | 38 | */ 39 | 40 | std::vector plusOne(std::vector& digits) { 41 | std::vector r; 42 | if (digits.empty()){ 43 | return r; 44 | } 45 | int i=digits.size()-1; 46 | int carry = 1; 47 | while (i>=0) { 48 | int t = digits[i] + carry; 49 | carry = t/10; 50 | t = t % 10; 51 | r.insert(r.begin(), t); 52 | i--; 53 | } 54 | if (carry > 0) { 55 | r.insert(r.begin(), carry); 56 | } 57 | return r; 58 | } 59 | #endif /* plusOne_hpp */ 60 | -------------------------------------------------------------------------------- /linkedList/leetcode/reverseList.h: -------------------------------------------------------------------------------- 1 | // 2 | // reverseList.h 3 | // linkedList 4 | // 5 | // Created by junl on 2019/7/17. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef reverseList_hpp 10 | #define reverseList_hpp 11 | 12 | #include 13 | #include "singlyLinkedList.h" 14 | 15 | namespace leetcode { 16 | /* 17 | 206.反转一个单链表。 18 | 19 | 示例: 20 | 21 | 输入: 1->2->3->4->5->NULL 22 | 输出: 5->4->3->2->1->NULL 23 | */ 24 | ListNode* reverseList(ListNode* head) { 25 | ListNode *pre,*ct,*next; 26 | if (!head->next) { 27 | return head; 28 | } 29 | 30 | 31 | ct = head; 32 | pre = nullptr; 33 | while (ct) { 34 | next = ct->next; 35 | ct->next = pre; 36 | pre = ct; 37 | ct = next; 38 | } 39 | return pre; 40 | 41 | } 42 | 43 | void test_reverseList(){ 44 | singlyLinkedList ll; 45 | ll.insertTail(3); 46 | ll.insertTail(2); 47 | ll.insertTail(0); 48 | ll.insertTail(-4); 49 | reverseList(ll.start())->print(); 50 | } 51 | } 52 | 53 | 54 | 55 | #endif /* reverseList_hpp */ 56 | -------------------------------------------------------------------------------- /sort/kthSmallest.h: -------------------------------------------------------------------------------- 1 | // 2 | // kthSmallest.h 3 | // sort 4 | // 5 | // Created by junlongj on 2019/7/19. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef kthSmallest_h 10 | #define kthSmallest_h 11 | 12 | /* 13 | 如何在o(n)内查找一个无序数组中的第K大元素. 14 | 15 | 16 | 利用快排分区的思想,将数组一分为3,然后根据pivot和kth的位置关系,继续寻找,最终定位到kth. 17 | 18 | */ 19 | 20 | int _partition(int nums[], int start, int end){ 21 | int i=start; 22 | int j=start; 23 | for (; j 13 | #include 14 | /* 15 | 119. 杨辉三角 II 16 | 给定一个非负索引 k,其中 k ≤ 33,返回杨辉三角的第 k 行。 17 | https://leetcode-cn.com/problems/pascals-triangle-ii/ 18 | 19 | 你可以优化你的算法到 O(k) 空间复杂度吗? 20 | */ 21 | 22 | namespace leetcode { 23 | /* 24 | 思路:通过上一行内容推算出下行的内容,比如: 25 | 1,1 26 | 1 , 2 + 1 27 | 28 | 1,2,1 如果j指向这一行的话 29 | 1, 3 3 +1 结果:result[j]=result[j]+result[j-1]; 30 | */ 31 | std::vector getRow(int rowIndex) { 32 | if (rowIndex<0) return {}; 33 | std::vector result; 34 | for (int i=0;i<=rowIndex;i++){ 35 | if (i==0) { 36 | result.push_back(1); 37 | }else{ 38 | for(int j=i-1;j-1>=0;j--){ 39 | result[j]=result[j]+result[j-1]; 40 | } 41 | result.push_back(1); 42 | } 43 | } 44 | return result; 45 | } 46 | } 47 | 48 | #endif /* pascals_triangle_ii_hpp */ 49 | -------------------------------------------------------------------------------- /sort/merge.c: -------------------------------------------------------------------------------- 1 | // 2 | // merge.c 3 | // sort 4 | // 5 | // Created by junl on 2020/12/1. 6 | // Copyright © 2020 junl. All rights reserved. 7 | // 8 | 9 | #include "sort.h" 10 | void _merge(ItemType a[], ItemType aux[], int l, int mid, int r); 11 | void _sort_merge(ItemType a[], ItemType aux[], int l, int r); 12 | void sort_merge(ItemType a[], int l, int r){ 13 | int sz = r - l + 1; 14 | //利用辅助数组,避免频繁创建数组带来的消耗 15 | ItemType aux[sz]; 16 | _sort_merge(a, aux, l, r); 17 | } 18 | void _sort_merge(ItemType a[], ItemType aux[], int l, int r){ 19 | if (l >= r) return; 20 | int mid = l + (r - l)/2; 21 | //先将左右两半分别排序,然后将结果合并起来 22 | _sort_merge(a, aux, l, mid); 23 | _sort_merge(a, aux, mid+1, r); 24 | _merge(a, aux, l, mid, r); 25 | } 26 | void _merge(ItemType a[], ItemType aux[], int l, int mid, int r){ 27 | int i = l, j = mid+1, k; 28 | for (k=l; k<=r; k++) { 29 | aux[k] = a[k]; 30 | } 31 | //原地排序 32 | for (k=l; k<=r; k++) { 33 | if (i > mid) { 34 | a[k] = aux[j++]; 35 | }else if (j > r){ 36 | a[k] = aux[i++]; 37 | }else if (less(aux[i], aux[j])) { 38 | a[k] = aux[i++]; 39 | }else{ 40 | a[k] = aux[j++]; 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /array/coding-interviews/FindNumsAppearOnce.h: -------------------------------------------------------------------------------- 1 | // 2 | // FindNumsAppearOnce.h 3 | // array 4 | // 5 | // Created by junlongj on 2019/8/3. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef FindNumsAppearOnce_hpp 10 | #define FindNumsAppearOnce_hpp 11 | 12 | #include 13 | #include 14 | #include 15 | /* 16 | 剑指Offer(四十):数组中只出现一次的数字 17 | 18 | 一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。 19 | https://www.nowcoder.com/practice/e02fdb54d7524710a7d664d082bb7811?tpId=13&tqId=11193&tPage=2&rp=1&ru=%2Fta%2Fcoding-interviews&qru=%2Fta%2Fcoding-interviews%2Fquestion-ranking 20 | */ 21 | 22 | namespace codinginterviews { 23 | void FindNumsAppearOnce(std::vector data,int* num1,int *num2) { 24 | std::map mm; 25 | for(auto it = data.begin();it!=data.end();it++){ 26 | auto find = mm.find(*it); 27 | if (find!= mm.end()) { 28 | mm.erase(find); 29 | }else{ 30 | mm[*it]=true; 31 | } 32 | } 33 | if (mm.size() == 2) { 34 | auto begin = mm.begin(); 35 | *num1 = begin->first; 36 | begin++; 37 | *num2 = begin->first; 38 | } 39 | } 40 | } 41 | #endif /* FindNumsAppearOnce_hpp */ 42 | -------------------------------------------------------------------------------- /stack+queue/leetcode/evalRPN.h: -------------------------------------------------------------------------------- 1 | // 2 | // evalRPN.h 3 | // stack+queue 4 | // 5 | // Created by junl on 2019/7/18. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef evalRPN_hpp 10 | #define evalRPN_hpp 11 | 12 | #include 13 | 14 | namespace leetcode { 15 | /* 16 | 150. 根据逆波兰表示法,求表达式的值。 17 | 18 | 有效的运算符包括 +, -, *, / 。每个运算对象可以是整数,也可以是另一个逆波兰表达式。 19 | 20 | 说明: 21 | 22 | 整数除法只保留整数部分。 23 | 给定逆波兰表达式总是有效的。换句话说,表达式总会得出有效数值且不存在除数为 0 的情况。 24 | 示例 1: 25 | 26 | 输入: ["2", "1", "+", "3", "*"] 27 | 输出: 9 28 | 解释: ((2 + 1) * 3) = 9 29 | 示例 2: 30 | 31 | 输入: ["4", "13", "5", "/", "+"] 32 | 输出: 6 33 | 解释: (4 + (13 / 5)) = 6 34 | 示例 3: 35 | 36 | 输入: ["10", "6", "9", "3", "+", "-11", "*", "/", "*", "17", "+", "5", "+"] 37 | 输出: 22 38 | 解释: 39 | ((10 * (6 / ((9 + 3) * -11))) + 17) + 5 40 | = ((10 * (6 / (12 * -11))) + 17) + 5 41 | = ((10 * (6 / -132)) + 17) + 5 42 | = ((10 * 0) + 17) + 5 43 | = (0 + 17) + 5 44 | = 17 + 5 45 | = 22 46 | 47 | 来源:力扣(LeetCode) 48 | 链接:https://leetcode-cn.com/problems/evaluate-reverse-polish-notation 49 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 50 | */ 51 | } 52 | 53 | #endif /* evalRPN_hpp */ 54 | -------------------------------------------------------------------------------- /linkedList/coding-interviews/printListFromTailToHead.h: -------------------------------------------------------------------------------- 1 | // 2 | // printListFromTailToHead.h 3 | // linkedList 4 | // 5 | // Created by junl on 2019/8/2. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef printListFromTailToHead_hpp 10 | #define printListFromTailToHead_hpp 11 | 12 | #include 13 | #include 14 | 15 | /* 16 | 剑指Offer(三):从尾到头打印链表: 17 | 输入一个链表,按链表值从尾到头的顺序返回一个ArrayList。 18 | https://www.nowcoder.com/practice/d0267f7f55b3412ba93bd35cfa8e8035?tpId=13&tqId=11156&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking 19 | 20 | */ 21 | 22 | 23 | namespace codinginterviews { 24 | std::vector printListFromTailToHead(ListNode* head) { 25 | if (head == nullptr) { 26 | return {}; 27 | } 28 | std::vector nodes; 29 | std::vector values; 30 | ListNode *node = head; 31 | while (node) { 32 | nodes.push_back(node); 33 | node = node->next; 34 | } 35 | for (int i=nodes.size()-1; i>=0; i--) { 36 | values.push_back(nodes[i]->val); 37 | } 38 | return values; 39 | } 40 | 41 | void test_printListFromTailToHead(){ 42 | 43 | } 44 | } 45 | #endif /* printListFromTailToHead_hpp */ 46 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 下面按照具体的分类来刷题,总结每个思想的精髓。 4 | 5 | # **算法思想** 6 | 7 | - [排序](./sort.md) 8 | - [递归](./recursion.md) 9 | - [二分查找](./bsearch.md) 10 | - [哈希算法](./hash.md) 11 | 12 | 20 | 21 | - [贪心](./greed.md) 22 | - [回溯算法](./backtracking.md) 23 | - [分治算法](./divideandconquer.md) 24 | - [动态规划](./dp.md) 25 | - [字符串匹配](./stringmatch.md) 26 | - [其他](./other.md) 27 | 28 | 29 | # **数据结构** 30 | 31 | - [数组](./array.md) 32 | - [链表](./linkedList.md) 33 | - [栈&队列](./stack_queue.md) 34 | - [树](./tree.md) 35 | - [字符串](./string.md) 36 | 37 | 38 | # [STL设计](./tiny_stl/README.md) 39 | 40 | - iterator 【DONE】 41 | - vector 【DONE】 42 | - list 【DONE】 43 | - deque 【DONE】 44 | - unordered_map 【DONE】 45 | - map 46 | 47 | 48 | # [leetcode](./leetcode.md) 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /linkedList/leetcode/easy/getIntersectionNode.h: -------------------------------------------------------------------------------- 1 | // 2 | // getIntersectionNode.h 3 | // linkedList 4 | // 5 | // Created by junlongj on 2019/8/10. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef getIntersectionNode_hpp 10 | #define getIntersectionNode_hpp 11 | 12 | #include 13 | #include 14 | /* 15 | 编写一个程序,找到两个单链表相交的起始节点。 16 | 17 | */ 18 | 19 | namespace leetcode{ 20 | ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) { 21 | int sizeA,sizeB; 22 | sizeA=0;sizeB=0; 23 | ListNode *ctA= headA; 24 | while(ctA){ 25 | sizeA++; 26 | ctA=ctA->next; 27 | } 28 | ListNode *ctB=headB; 29 | while(ctB){ 30 | sizeB++; 31 | ctB=ctB->next; 32 | } 33 | ListNode *ll = sizeA>sizeB?headA:headB; 34 | ListNode *ll2 = ll==headA?headB:headA; 35 | int count=0; 36 | int step=fabs(sizeA-sizeB); 37 | while(count < step){ 38 | ll=ll->next; 39 | count++; 40 | } 41 | 42 | while(ll&&ll2){ 43 | if (ll == ll2) 44 | return ll; 45 | ll=ll->next; 46 | ll2=ll2->next; 47 | } 48 | return nullptr; 49 | } 50 | } 51 | #endif /* getIntersectionNode_hpp */ 52 | -------------------------------------------------------------------------------- /stack+queue/coding-interviews/validateStackSequences.h: -------------------------------------------------------------------------------- 1 | // 2 | // validateStackSequences.h 3 | // stack+queue 4 | // 5 | // Created by junl on 2020/5/15. 6 | // Copyright © 2020 junl. All rights reserved. 7 | // 8 | 9 | #ifndef validateStackSequences_h 10 | #define validateStackSequences_h 11 | #include 12 | namespace codinginterviews{ 13 | class ValidateStackSequences { 14 | public: 15 | bool validateStackSequences(vector& pushed, vector& popped) { 16 | if (pushed.empty() && popped.empty()) return true; 17 | 18 | std::stack stk; 19 | int i, j; 20 | i = 0; j = 0; 21 | while(j < popped.size()){ 22 | if (stk.empty() || stk.top() != popped[j]){ 23 | if (i == pushed.size()) 24 | return false; 25 | stk.push(pushed[i++]); 26 | }else{ 27 | stk.pop(); 28 | j++; 29 | } 30 | } 31 | return stk.empty(); 32 | } 33 | }; 34 | } 35 | void test_validateStackSequences(){ 36 | vector pushed{1,2,3,4,5}; 37 | vector poped{4,5,3,2,1}; 38 | codinginterviews::ValidateStackSequences so; 39 | std::cout << "validateStackSequences: " << so.validateStackSequences(pushed, poped) << std::endl; 40 | } 41 | 42 | #endif /* validateStackSequences_h */ 43 | -------------------------------------------------------------------------------- /linkedList/coding-interviews/DeleteNodeO1.h: -------------------------------------------------------------------------------- 1 | // 2 | // DeleteNodeO1.h 3 | // linkedList 4 | // 5 | // Created by junl on 2020/1/3. 6 | // Copyright © 2020 junl. All rights reserved. 7 | // 8 | 9 | #ifndef DeleteNodeO1_hpp 10 | #define DeleteNodeO1_hpp 11 | 12 | #include 13 | #include "creatlist.h" 14 | /* 15 | 面试题13. 在O(1)时间删除链表节点 16 | 17 | 前提假设:该节点存在链表中.否则查找这个过程就已经o(n)了. 18 | */ 19 | namespace itinterviews { 20 | void DeleteNodeO1(ListNode **head, ListNode *deleteNode){ 21 | if (!head || !deleteNode) 22 | return; 23 | if (deleteNode->next) { 24 | ListNode *next = deleteNode->next; 25 | deleteNode->val = next->val; 26 | deleteNode->next = next->next; 27 | delete next; 28 | }else{ 29 | //后置节点不存在 30 | if (*head == deleteNode){ 31 | delete deleteNode; 32 | *head = nullptr; 33 | deleteNode = nullptr; 34 | }else{ 35 | ListNode *node = *head; 36 | while (node->next != deleteNode) { 37 | node = node->next; 38 | } 39 | node->next = nullptr; 40 | delete deleteNode; 41 | deleteNode = nullptr; 42 | } 43 | } 44 | } 45 | } 46 | #endif /* DeleteNodeO1_hpp */ 47 | -------------------------------------------------------------------------------- /greed/main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // main.cpp 3 | // greed 4 | // 5 | // Created by junl on 2019/9/9. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #include 10 | #include "shared_the_sweets.h" 11 | #include "coin_dispenser.h" 12 | #include "region_overlapping.h" 13 | #include "jump_game.h" 14 | #include "gas_station.h" 15 | #include 16 | using namespace std; 17 | int main(int argc, const char * argv[]) { 18 | // insert code here... 19 | std::cout << "Hello, World!\n"; 20 | 21 | vector childwants{5,10,2,9,15,9}; 22 | vector sweets{6,1,20,3,8}; 23 | int sharecount = shared_the_sweets(sweets, childwants); 24 | cout << "分糖果: " << sharecount << endl; 25 | 26 | vector cointypes{ 1, 2, 5, 10, 20,50,100}; 27 | vector coincounts{10,0, 0, 1, 2, 0, 2};//2*100+20*2+10*1+1*2 = 7 28 | 29 | int ccount = coin_dispenser(cointypes, coincounts, 252); 30 | cout << "钱币找零: " << ccount << endl; 31 | 32 | vector> areas; 33 | areas.push_back({6,8}); 34 | areas.push_back({2,4}); 35 | areas.push_back({3,5}); 36 | areas.push_back({1,5}); 37 | areas.push_back({5,9}); 38 | areas.push_back({8,10}); 39 | cout << "区域覆盖:" << region_overlapping(areas) << endl; 40 | 41 | queue q; 42 | q.push(1); 43 | q.front(); 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /array/coding-interviews/ReOrder.h: -------------------------------------------------------------------------------- 1 | // 2 | // ReOrder.h 3 | // array 4 | // 5 | // Created by junl on 2020/1/4. 6 | // Copyright © 2020 junl. All rights reserved. 7 | // 8 | 9 | #ifndef ReOrder_hpp 10 | #define ReOrder_hpp 11 | 12 | #include 13 | #include 14 | /* 15 | 面试题14. 调整数组顺序使得奇数位于偶数前面 16 | */ 17 | 18 | namespace codinginterviews { 19 | void ReOrder(std::vector &nums){ 20 | if (nums.empty()) 21 | return; 22 | 23 | int pos1 = 0; 24 | int pos2 = nums.size() - 1; 25 | if (pos1 == pos2) 26 | return; 27 | while (pos1 < pos2) { 28 | //寻找前面第一个偶数 29 | while (nums[pos1] & 0x1) { 30 | pos1++; 31 | } 32 | if (pos1 == nums.size()+1) 33 | break; 34 | while (!(nums[pos2] & 0x1)) { 35 | pos2--; 36 | } 37 | if (pos2 == -1) 38 | break; 39 | std::swap(nums[pos1], nums[pos2]); 40 | pos1++;pos2--; 41 | } 42 | } 43 | 44 | void test_ReOrder(){ 45 | std::cout << "调整数组顺序使得奇数位于偶数前面" << std::endl; 46 | std::vector nums{2,4,6,8}; 47 | ReOrder(nums); 48 | for(auto &x : nums){ 49 | std::cout << x << std::endl; 50 | } 51 | } 52 | } 53 | #endif /* ReOrder_hpp */ 54 | -------------------------------------------------------------------------------- /stack+queue/stack.h: -------------------------------------------------------------------------------- 1 | // 2 | // stack.h 3 | // stack+queue 4 | // 5 | // Created by junl on 2019/7/18. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef stack_hpp 10 | #define stack_hpp 11 | 12 | #include 13 | #include 14 | #include "illegalParameterValue.h" 15 | 16 | 17 | template 18 | class stack { 19 | public: 20 | void push(const Value &v){ 21 | Node *node = new Node(v); 22 | if (top) { 23 | node->next = top; 24 | top = node; 25 | }else{ 26 | top = node; 27 | } 28 | } 29 | Value& pop(){ 30 | if (top == nullptr) 31 | throw stackEmpty(); 32 | Value &v = top->val; 33 | top = top->next; 34 | return v; 35 | } 36 | Value& topElement(){ 37 | if (top == nullptr) 38 | throw stackEmpty(); 39 | Value &v = top->val; 40 | return v; 41 | } 42 | void print(){ 43 | Node *ct = top; 44 | while (ct) { 45 | std::cout << ct->val << ", "; 46 | ct = ct->next; 47 | } 48 | std::cout << std::endl; 49 | } 50 | private: 51 | class Node{ 52 | public: 53 | Value val; 54 | Node *next; 55 | Node(const Value &v):val(v),next(nullptr){} 56 | }; 57 | Node *top; 58 | }; 59 | 60 | #endif /* stack_hpp */ 61 | -------------------------------------------------------------------------------- /recursion/coding-interviews/jumpFloor.h: -------------------------------------------------------------------------------- 1 | // 2 | // jumpFloor.h 3 | // recursion 4 | // 5 | // Created by junlongj on 2019/8/4. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef jumpFloor_hpp 10 | #define jumpFloor_hpp 11 | 12 | #include 13 | /* 14 | 剑指Offer(八):跳台阶 15 | 一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。 16 | https://www.nowcoder.com/practice/8c82a5b80378478f9484d87d1c5f12a4?tpId=13&tqId=11161&tPage=1&rp=1&ru=%2Fta%2Fcoding-interviews&qru=%2Fta%2Fcoding-interviews%2Fquestion-ranking 17 | */ 18 | 19 | namespace codinginterviews { 20 | int jumpFloor(int number) { 21 | if (number == 0) return 0; 22 | if (number == 1) return 1; 23 | if (number == 2) return 2; 24 | return jumpFloor(number-1) + jumpFloor(number-2); 25 | } 26 | 27 | int jumpFloor2(int number) { 28 | if (number == 0) return 0; 29 | if (number == 1) return 1; 30 | if (number == 2) return 2; 31 | int dp[number]; 32 | memset(dp, 0, sizeof(dp)); 33 | dp[0]=1; 34 | dp[1]=2; 35 | for (int i=2; i 13 | #include 14 | /* 15 | 给定一个已按照升序排列 的有序数组,找到两个数使得它们相加之和等于目标数。 16 | 17 | 函数应该返回这两个下标值 index1 和 index2,其中 index1 必须小于 index2。 18 | 19 | 说明: 20 | 21 | 返回的下标值(index1 和 index2)不是从零开始的。 22 | 你可以假设每个输入只对应唯一的答案,而且你不可以重复使用相同的元素。 23 | 示例: 24 | 25 | 输入: numbers = [2, 7, 11, 15], target = 9 26 | 输出: [1,2] 27 | 解释: 2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。 28 | 29 | 来源:力扣(LeetCode) 30 | 链接:https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted 31 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 32 | */ 33 | 34 | namespace leetcode { 35 | std::vector twoSum_ii(std::vector& numbers, int target) { 36 | if (numbers.empty()) return {}; 37 | std::vector result; 38 | for(int i=0,j=numbers.size()-1;i 13 | #include 14 | /* 15 | 假设我们有N个区间,区间的起始断点和结束断点分别是[l1,r1],[l2,r2],......[ln,rn]. 16 | 我们从这N个区间选出一部分区间,这部分区间两两不能相交,(端点相交不算相交),最多能选出多少个区间? 17 | */ 18 | 19 | int region_overlapping(vector> areas){ 20 | /* 21 | 我们把所有区域里面,最左边的点记为lmin,最右边的点记为rmax.整个大区间就为[lmin,rmax]. 22 | 题目可以转换为: 23 | 在[lmin,rmax]中寻找一部分区间,要求它们两两不能相交,最多能选出多少个空间? 24 | 25 | 限制值: 在大区间[lmin,rmax]里 26 | 期望值:满足要求的区域数量 27 | 贪心思想: 在贡献相同期望值(符合要求的区间数)时,我们选择范围更小的子区间,这样意味着后面可以由更多的符合要求的子区间. 28 | */ 29 | int count=0; 30 | sort(areas.begin(), areas.end(), [](vector &l,vector&r){ 31 | return l[0] < r[0]; 32 | }); 33 | int lmin=areas[0][0]; 34 | for (int i=0; i 13 | /* 14 | 剑指Offer(六十五):矩阵中的路径 15 | 16 | 请设计一个函数,用来判断在一个矩阵中是否存在一条包含某字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则之后不能再次进入这个格子。 例如 a b c e s f c s a d e e 这样的3 X 4 矩阵中包含一条字符串"bcced"的路径,但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。 17 | https://www.nowcoder.com/practice/c61c6999eecb4b8f88a98f66b273a3cc?tpId=13&tqId=11218&tPage=4&rp=1&ru=%2Fta%2Fcoding-interviews&qru=%2Fta%2Fcoding-interviews%2Fquestion-ranking 18 | */ 19 | 20 | namespace codinginterviews { 21 | bool hasPath(char** matrix, int rows, int cols, char* str,int ctrow,int ctcol,bool **states) 22 | { 23 | if (ctrow<=0 || ctrow>=rows) { 24 | return false; 25 | } 26 | if (ctcol <=0 || ctcol >= cols) { 27 | return false; 28 | } 29 | if (*str == '\0') { 30 | return true; 31 | } 32 | if (matrix[ctrow][ctcol] == *str) { 33 | str++; 34 | } 35 | return hasPath(matrix, rows, cols, str, ctrow+1, ctcol,states); 36 | } 37 | bool hasPath(char* matrix, int rows, int cols, char* str) 38 | { 39 | return false; 40 | } 41 | } 42 | #endif /* hasPath_hpp */ 43 | -------------------------------------------------------------------------------- /stack+queue/coding-interviews/queueByStack.h: -------------------------------------------------------------------------------- 1 | // 2 | // queueByStack.h 3 | // stack+queue 4 | // 5 | // Created by junlongj on 2019/8/4. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef queueByStack_hpp 10 | #define queueByStack_hpp 11 | 12 | #include 13 | #include 14 | /* 15 | 剑指Offer(五):用两个栈实现队列 16 | 用两个栈来实现一个队列,完成队列的Push和Pop操作。 队列中的元素为int类型。 17 | https://www.nowcoder.com/practice/54275ddae22f475981afa2244dd448c6?tpId=13&tqId=11158&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking 18 | 19 | */ 20 | namespace codinginterviews { 21 | class Queue 22 | { 23 | public: 24 | void push(int node) { 25 | stack1.push(node); 26 | } 27 | 28 | int pop() { 29 | if (stack2.empty()) { 30 | while (!stack1.empty()) { 31 | stack2.push(stack1.top()); 32 | stack1.pop(); 33 | } 34 | } 35 | if (stack2.size() > 0) { 36 | int node = stack2.top(); 37 | stack2.pop(); 38 | return node; 39 | } 40 | return 0; 41 | } 42 | 43 | private: 44 | std::stack stack1; 45 | std::stack stack2; 46 | }; 47 | 48 | void test_Queue(){ 49 | Queue q; 50 | 51 | } 52 | } 53 | 54 | 55 | #endif /* queueByStack_hpp */ 56 | -------------------------------------------------------------------------------- /linkedList/itinterviews/printCommonPart.h: -------------------------------------------------------------------------------- 1 | // 2 | // printCommonPart.h 3 | // linkedList 4 | // 5 | // Created by junl on 2019/10/27. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef printCommonPart_hpp 10 | #define printCommonPart_hpp 11 | 12 | #include 13 | #include "creatlist.h" 14 | 15 | /* 16 | 给定两个有序链表的头指针head1和head2,打印两个链表的公共部分 17 | */ 18 | 19 | namespace itinterviews { 20 | class printCommonPart{ 21 | public: 22 | void solve(ListNode *head1, ListNode *head2){ 23 | while (head1 && head2) { 24 | if (head1->val == head2->val) { 25 | std::cout << head1->val << ", "; 26 | head1 = head1->next; 27 | head2 = head2->next; 28 | }else if (head1->val < head2->val){ 29 | head1 = head1->next; 30 | }else{ 31 | head2 = head2->next; 32 | } 33 | } 34 | std::cout << std::endl; 35 | } 36 | }; 37 | 38 | void test_printCommonPart(){ 39 | std::cout << "---给定两个有序链表的头指针head1和head2,打印两个链表的公共部分----" << std::endl; 40 | class printCommonPart so; 41 | ListNode *head1 = codinginterviews::creatLists({2,4,6,8})->next; 42 | ListNode *head2 = codinginterviews::creatLists({2,3,4})->next; 43 | so.solve(head1, head2); 44 | } 45 | } 46 | 47 | 48 | #endif /* printCommonPart_hpp */ 49 | -------------------------------------------------------------------------------- /string/leetcode/easy/strStr.h: -------------------------------------------------------------------------------- 1 | // 2 | // strStr.h 3 | // string 4 | // 5 | // Created by junlongj on 2019/8/12. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef strStr_hpp 10 | #define strStr_hpp 11 | 12 | #include 13 | #include 14 | /* 15 | 28.实现 strStr() 函数。 16 | 17 | 给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回  -1。 18 | 19 | 示例 1: 20 | 21 | 输入: haystack = "hello", needle = "ll" 22 | 输出: 2 23 | 示例 2: 24 | 25 | 输入: haystack = "aaaaa", needle = "bba" 26 | 输出: -1 27 | 说明: 28 | 29 | 当 needle 是空字符串时,我们应当返回什么值呢?这是一个在面试中很好的问题。 30 | 31 | 对于本题而言,当 needle 是空字符串时我们应当返回 0 。这与C语言的 strstr() 以及 Java的 indexOf() 定义相符。 32 | 33 | 34 | 35 | 来源:力扣(LeetCode) 36 | 链接:https://leetcode-cn.com/problems/implement-strstr 37 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 38 | */ 39 | 40 | namespace leetcode { 41 | int strStr(std::string haystack, std::string needle) { 42 | if (needle.empty()) return 0; 43 | if (haystack.empty()) return -1; 44 | int i=0; 45 | int j=0; 46 | while(i 13 | #include 14 | /* 15 | 给定一个大小为 n 的数组,找到其中的众数。众数是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。 16 | 17 | 你可以假设数组是非空的,并且给定的数组总是存在众数。 18 | 19 | 示例 1: 20 | 21 | 输入: [3,2,3] 22 | 输出: 3 23 | 示例 2: 24 | 25 | 输入: [2,2,1,1,1,2,2] 26 | 输出: 2 27 | 28 | 来源:力扣(LeetCode) 29 | 链接:https://leetcode-cn.com/problems/majority-element 30 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 31 | */ 32 | 33 | namespace leetcode { 34 | /* 35 | 思路:利用压栈和出栈的方式,只要和栈顶元素一样就进栈,不一样的话就出栈,栈为空时重新加入新元素来比较,这样栈里面最后的元素肯定是个数最多的那个. 36 | */ 37 | int majorityElement(std::vector& nums) { 38 | if (nums.empty()) return -1; 39 | int lastelement = nums[0]; 40 | int count = 1; 41 | for (int i=1;i nums.size()/2) return lastelement; 53 | } 54 | return count > 0 ? lastelement : -1; 55 | } 56 | } 57 | #endif /* majorityElement_hpp */ 58 | -------------------------------------------------------------------------------- /string/coding-interviews/FirstNotRepeatingChar.h: -------------------------------------------------------------------------------- 1 | // 2 | // FirstNotRepeatingChar.h 3 | // string 4 | // 5 | // Created by junlongj on 2019/8/4. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef FirstNotRepeatingChar_hpp 10 | #define FirstNotRepeatingChar_hpp 11 | 12 | #include 13 | #include 14 | #include 15 | /* 16 | 剑指Offer(三十四):第一个只出现一次的字符 17 | 18 | 在一个字符串(0<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1(需要区分大小写). 19 | https://www.nowcoder.com/practice/1c82e8cf713b4bbeb2a5b31cf5b0417c?tpId=13&tqId=11187&tPage=2&rp=1&ru=%2Fta%2Fcoding-interviews&qru=%2Fta%2Fcoding-interviews%2Fquestion-ranking 20 | */ 21 | 22 | namespace codinginterviews { 23 | int FirstNotRepeatingChar(std::string &str) { 24 | int length = str.size(); 25 | if(length == 0){ 26 | return -1; 27 | } 28 | std::map item; 29 | for(int i = 0; i < length; i++){ 30 | item[str[i]]++; 31 | } 32 | for(int i = 0; i < length; i++){ 33 | if(item[str[i]] == 1){ 34 | return i; 35 | } 36 | } 37 | return -1; 38 | } 39 | 40 | void test_FirstNotRepeatingChar(){ 41 | std::cout << "FirstNotRepeatingChar starting......" << std::endl; 42 | std::string s{"google"}; 43 | std::cout << FirstNotRepeatingChar(s) << std::endl; 44 | } 45 | } 46 | 47 | #endif /* FirstNotRepeatingChar_hpp */ 48 | -------------------------------------------------------------------------------- /sort/quick.c: -------------------------------------------------------------------------------- 1 | // 2 | // quick.c 3 | // sort 4 | // 5 | // Created by junl on 2020/12/2. 6 | // Copyright © 2020 junl. All rights reserved. 7 | // 8 | 9 | #include "sort.h" 10 | int _partition(ItemType a[], int l, int r); 11 | void sort_quick(ItemType a[], int l, int r){ 12 | if (l >= r) return; 13 | int idx = _partition(a, l, r); 14 | sort_quick(a, l, idx-1); 15 | sort_quick(a, idx+1, r); 16 | } 17 | #if 1 18 | void _setMid(ItemType a[], int l, int r){ 19 | int min, mid = l + (r - l) / 2; 20 | if (less(a[l], a[r])){ 21 | min = less(a[mid], a[r]) ? mid : r; 22 | }else{ 23 | min = less(a[mid], a[l]) ? mid : l; 24 | } 25 | exch(a[r], a[min]); 26 | } 27 | 28 | int _partition(ItemType a[], int l, int r){ 29 | _setMid(a, l, r); 30 | int t = a[r], i = l, j = l;//i代表比t小的数组的末尾 31 | for (; j < r; j++) { 32 | if (less(a[j], t)) { 33 | exch(a[j], a[i]); 34 | i++; 35 | } 36 | } 37 | exch(a[i], a[r]); 38 | return i; 39 | } 40 | #else 41 | int _partition(ItemType a[], int l, int r){ 42 | int t = a[l], i = l, j = r+1; 43 | while (1) { 44 | //从左边开始寻找第一个比t大的值 45 | for (; less(a[++i], t); ) 46 | if (i == r) break; 47 | //从右边开始寻找第一个比t小的值 48 | for (; less(t, a[--j]); ) 49 | if (j == l) break; 50 | if (i>=j) break; 51 | exch(a[i], a[j]); 52 | } 53 | exch(a[l], a[j]); 54 | return j; 55 | } 56 | #endif 57 | -------------------------------------------------------------------------------- /greed.md: -------------------------------------------------------------------------------- 1 | # 贪心算法 2 | 3 | 当我们看到这类题目时,首先要联想到贪心:针对一组数据,我们定义了期望值,限制值,希望从中选出几个数据,在满足限制值的条件下,期望值最大. 4 | 5 | 关键点就在于:每次在选择当前情况下,如果对期望值贡献一样的情况下,我们使用选择那个对期望值贡献最多的那个. 6 | 7 | 8 | 比如0,1背包问题. 限制值就是w kg, 期望值就是背包里所有物品的总价值最大,而贪心思想每次向背包里放1kg物品时,我们始终选择那个最贵的. 9 | 10 | 11 | # [分糖果](./greed/shared_the_sweets.h) 12 | 13 | # [纸币找零](./greed/coin_dispenser.h) 14 | 15 | # [区间覆盖](./greed/region_overlapping.h) 16 | 17 | 18 | # leetcode 19 | |  题号  | 题目链接            | 答案链接            |  难度  |  完成度  | 20 | | :--: | :--: | :----------------------------------------------------------- | :----------------------------------------------------------- | :------: | 21 | | 55 | [跳跃游戏](https://leetcode-cn.com/problems/jump-game/) | [jump_game](./greed/leetcode/medium/jump_game.h) | medium | ✅ | 22 | | 134 | [加油站](https://leetcode-cn.com/problems/gas-station/) | [gas_station](./greed/leetcode/medium/gas_station.h) | medium | ✅ | 23 | | 455 | [分发饼干](https://leetcode-cn.com/problems/assign-cookies/description/) | -- | ✨ | ❌ | 24 | | 860 | [柠檬水找零](https://leetcode-cn.com/problems/lemonade-change/description/) | -- | ✨ | ❌ | 25 | | 874 | [模拟行走机器人](https://leetcode-cn.com/problems/walking-robot-simulation/description/) | -- | ✨ | ❌ | -------------------------------------------------------------------------------- /string/leetcode/medium/lengthOfLongestSubstring.h: -------------------------------------------------------------------------------- 1 | // 2 | // lengthOfLongestSubstring.h 3 | // string 4 | // 5 | // Created by junlongj on 2019/8/15. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef lengthOfLongestSubstring_hpp 10 | #define lengthOfLongestSubstring_hpp 11 | 12 | #include 13 | #include 14 | #include 15 | /* 16 | 3.无重复字符的最长子串 17 | 给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。 18 | 19 | 示例 1: 20 | 21 | 输入: "abcabcbb" 22 | 输出: 3 23 | 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。 24 | 25 | 来源:力扣(LeetCode) 26 | 链接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters 27 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 28 | */ 29 | namespace leetcode { 30 | //思路:求的是最长子串,是连续的。利用滑动窗口,hash_table的特性来判断是否包含。 31 | int lengthOfLongestSubstring(std::string s) { 32 | if (s.empty()) return 0; 33 | int left=0; 34 | int right=0; 35 | std::map mm;//字符对应的下标 36 | int maxlen=0; 37 | for(;right 13 | 14 | /* 15 | 111.给定一个二叉树,找出其最小深度。 16 | 17 | 最小深度是从根节点到最近叶子节点的最短路径上的节点数量。 18 | 19 | 说明: 叶子节点是指没有子节点的节点。 20 | 21 | 示例: 22 | 23 | 给定二叉树 [3,9,20,null,null,15,7], 24 | 25 | 3 26 | / \ 27 | 9 20 28 | / \ 29 | 15 7 30 | 返回它的最小深度  2. 31 | 32 | 来源:力扣(LeetCode) 33 | 链接:https://leetcode-cn.com/problems/minimum-depth-of-binary-tree 34 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 35 | */ 36 | 37 | namespace leetcode { 38 | int minDepth(TreeNode* root) { 39 | if (root == nullptr) { 40 | return 0; 41 | } 42 | if (root->lchild == nullptr && root->rchild == nullptr) { 43 | return 1; 44 | } 45 | int left = INT_MAX; 46 | if (root->lchild) { 47 | left = minDepth(root->lchild) + 1; 48 | } 49 | int right = INT_MAX; 50 | if (root->rchild) { 51 | right = minDepth(root->rchild) + 1; 52 | } 53 | return left < right ? left : right; 54 | } 55 | 56 | void test_minDepth(){ 57 | TreeNode *node = new TreeNode(1); 58 | node->lchild = new TreeNode(2); 59 | std::cout << "minDepth staring...... \n" << minDepth(node) << std::endl; 60 | } 61 | } 62 | 63 | #endif /* minDepth_hpp */ 64 | -------------------------------------------------------------------------------- /recursion/coding-interviews/Fibonacci.h: -------------------------------------------------------------------------------- 1 | // 2 | // Fibonacci.h 3 | // recursion 4 | // 5 | // Created by junlongj on 2019/8/4. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef Fibonacci_hpp 10 | #define Fibonacci_hpp 11 | 12 | #include 13 | /* 14 | 剑指Offer(七):裴波那契数列 15 | https://www.nowcoder.com/practice/c6c7742f5ba7442aada113136ddea0c3?tpId=13&tqId=11160&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking 16 | */ 17 | namespace codinginterviews { 18 | int Fibonacci(int n) { 19 | if (n == 0) return 0; 20 | if (n == 1) return 1; 21 | return Fibonacci(n-2) + Fibonacci(n-1); 22 | } 23 | long long Fibonacci2(int n) { 24 | long long dp[n+1]; 25 | memset(dp, 0, sizeof(dp)); 26 | dp[0]=0; 27 | dp[1]=1; 28 | for (int i=2; i<=n; i++) { 29 | dp[i] = dp[i-2]+dp[i-1]; 30 | } 31 | return dp[n]; 32 | } 33 | int Fibonacci3(int n) { 34 | int f0,f1,f2; 35 | f0 = 0; 36 | f1 = 1; 37 | if (n == 0) return f0; 38 | if (n == 1) return f1; 39 | for (int i=2; i<=n; i++) { 40 | f2 = f0+f1; 41 | f0 = f1; 42 | f1 = f2; 43 | } 44 | return f2; 45 | } 46 | void test_Fibonacci(){ 47 | std::cout << "Fibonacci starting......" << std::endl; 48 | std::cout << Fibonacci2(39) << std::endl;//63245986 63245986 49 | } 50 | } 51 | #endif /* Fibonacci_hpp */ 52 | -------------------------------------------------------------------------------- /greed/leetcode/medium/jump_game.h: -------------------------------------------------------------------------------- 1 | // 2 | // jump_game.h 3 | // greed 4 | // 5 | // Created by junl on 2019/9/10. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef jump_game_hpp 10 | #define jump_game_hpp 11 | 12 | #include 13 | #include 14 | /* 15 | 55. 跳跃游戏 16 | 给定一个非负整数数组,你最初位于数组的第一个位置。 17 | 18 | 数组中的每个元素代表你在该位置可以跳跃的最大长度。 19 | 20 | 判断你是否能够到达最后一个位置。 21 | 22 | 示例 1: 23 | 24 | 输入: [2,3,1,1,4] 25 | 输出: true 26 | 解释: 从位置 0 到 1 跳 1 步, 然后跳 3 步到达最后一个位置。 27 | 28 | 来源:力扣(LeetCode) 29 | 链接:https://leetcode-cn.com/problems/jump-game 30 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 31 | */ 32 | 33 | namespace leetcode { 34 | bool canJump(vector& nums) { 35 | //贪心思想,始终选择当前跳和下一跳加起来最远的那个 36 | if (nums.empty()) return false; 37 | int destination = nums.size()-1; 38 | for (int i=0;i= destination) 48 | return true; 49 | if (maxstep < j+nums[i+j]){ 50 | maxstep =j+nums[i+j]; 51 | nexstep = j; 52 | } 53 | } 54 | i += nexstep; 55 | } 56 | return false; 57 | } 58 | } 59 | #endif /* jump_game_hpp */ 60 | -------------------------------------------------------------------------------- /linkedList/coding-interviews/FindKthToTail.h: -------------------------------------------------------------------------------- 1 | // 2 | // FindKthToTail.h 3 | // linkedList 4 | // 5 | // Created by junl on 2019/8/2. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef FindKthToTail_hpp 10 | #define FindKthToTail_hpp 11 | 12 | #include 13 | #include "creatlist.h" 14 | /* 15 | 剑指Offer(十四):链表中倒数第k个结点 16 | 输入一个链表,输出该链表中倒数第k个结点。 17 | https://www.nowcoder.com/practice/529d3ae5a407492994ad2a246518148a?tpId=13&tqId=11167&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking 18 | */ 19 | 20 | namespace codinginterviews { 21 | ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) { 22 | //利用快慢指针 23 | ListNode *head = new ListNode(0); 24 | head->next = pListHead; 25 | int i=0; 26 | ListNode *fast,*slow; 27 | fast = slow = head; 28 | while (fast && i++next; 30 | } 31 | if (fast == nullptr) { 32 | return nullptr; 33 | } 34 | while (fast) { 35 | fast = fast->next; 36 | slow = slow->next; 37 | } 38 | return slow; 39 | } 40 | 41 | void test_FindKthToTail(){ 42 | std::vector nos{}; 43 | ListNode *root = creatLists(nos)->next; 44 | ListNode *node = FindKthToTail(root, 100); 45 | 46 | std::cout << "test_FindKthToTail starting....... " << std::endl; 47 | node->print(); 48 | } 49 | } 50 | #endif /* FindKthToTail_hpp */ 51 | -------------------------------------------------------------------------------- /other/coding-interviews/NumberOf1.h: -------------------------------------------------------------------------------- 1 | // 2 | // NumberOf1.h 3 | // other 4 | // 5 | // Created by junlongj on 2019/8/4. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef NumberOf1_hpp 10 | #define NumberOf1_hpp 11 | 12 | #include 13 | #include 14 | /* 15 | 剑指Offer(十一):二进制中1的个数 16 | 输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。 17 | 18 | https://www.nowcoder.com/practice/8ee967e43c2c4ec193b040ea7fbb10b8?tpId=13&tqId=11164&tPage=1&rp=1&ru=%2Fta%2Fcoding-interviews&qru=%2Fta%2Fcoding-interviews%2Fquestion-ranking 19 | */ 20 | 21 | namespace codinginterviews { 22 | int NumberOf1(long long n) { 23 | int count = 0; 24 | while (n) { 25 | //N每次和1做&运算,计算出最右边的二进制是否为1.然后在右移一位.但是如果N为负数时,n右移会在最高位补1(为了保证数据为负数),所以会陷入死循环》 26 | if (n & 1) 27 | count++; 28 | n = n >> 1; 29 | } 30 | return count; 31 | } 32 | //为了避免上面负数导致的死循环,我们现在通过左移的方式,移动临时变量flag(1)。但是这样操作的话,int 32位,就需要移动32次. 33 | int NumberOf1_2(long long n) { 34 | int count = 0; 35 | int flag = 1; 36 | while (flag) { 37 | // std::cout << flag << ", "< 13 | #include 14 | /* 15 | 121. 买卖股票的最佳时机 16 | 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。 17 | 18 | 如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润。 19 | 20 | 注意你不能在买入股票前卖出股票。 21 | 22 | 示例 1: 23 | 24 | 输入: [7,1,5,3,6,4] 25 | 输出: 5 26 | 解释: 在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。 27 | 注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格。 28 | 29 | 来源:力扣(LeetCode) 30 | 链接:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock 31 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 32 | */ 33 | 34 | namespace leetcode { 35 | /* 36 | 思路:如果我们设立一个状态数组,里面states[i]存储的是在哪一天购买股票能够带来最大收益。 37 | 那么根据前一天的状态是能计算出后一天的状态的. 38 | */ 39 | int maxProfit(std::vector& prices) { 40 | if (prices.empty()) return 0; 41 | int max = 0; 42 | int buys[prices.size()]; 43 | buys[0] = prices[0]; 44 | for (int i = 1; i< prices.size();i++){ 45 | if (prices[i]-buys[i-1] < 0){ 46 | buys[i]=prices[i]; 47 | }else{ 48 | buys[i]=buys[i-1]; 49 | } 50 | max = std::max(max,prices[i]-buys[i]); 51 | } 52 | return max; 53 | } 54 | } 55 | #endif /* best_time_to_buy_and_sell_stock_hpp */ 56 | -------------------------------------------------------------------------------- /array/leetcode/easy/pascals_triangle.h: -------------------------------------------------------------------------------- 1 | // 2 | // pascals_triangle.h 3 | // array 4 | // 5 | // Created by junlongj on 2019/8/8. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef pascals_triangle_hpp 10 | #define pascals_triangle_hpp 11 | 12 | #include 13 | #include 14 | /* 15 | 118. 杨辉三角 16 | 在杨辉三角中,每个数是它左上方和右上方的数的和。 17 | 18 | 示例: 19 | 20 | 输入: 5 21 | 输出: 22 | [ 23 | [1], 24 | [1,1], 25 | [1,2,1], 26 | [1,3,3,1], 27 | [1,4,6,4,1] 28 | ] 29 | 30 | 来源:力扣(LeetCode) 31 | 链接:https://leetcode-cn.com/problems/pascals-triangle 32 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 33 | https://leetcode-cn.com/problems/pascals-triangle/ 34 | */ 35 | 36 | namespace leetcode { 37 | /* 38 | 思路: 下一行的内容是由上一行产生的,所以内存循环遍历上一次的vec就行了 39 | */ 40 | std::vector> generate(int numRows) { 41 | if (numRows == 0) return {}; 42 | std::vector> result; 43 | std::vector lastVec; 44 | result.push_back({1}); 45 | for(int i=1;i vec; 47 | vec.push_back(1); 48 | if (lastVec.size()>=2){ 49 | for (int j=0; j+1 13 | #include 14 | /* 15 | 剑指Offer(一):二维数组中的查找 16 | 17 | 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。 18 | https://www.nowcoder.com/practice/abc3fe2ce8e146608e868a70efebf62e?tpId=13&tqId=11154&tPage=1&rp=1&ru=%2Fta%2Fcoding-interviews&qru=%2Fta%2Fcoding-interviews%2Fquestion-ranking 19 | */ 20 | 21 | namespace codinginterviews { 22 | /* 23 | */ 24 | bool Find(int target, std::vector > &array, int row,int column) { 25 | if (row < 0 || column >= array[0].size()) { 26 | return false; 27 | } 28 | int it = array[row][column]; 29 | if (it == target) { 30 | return true; 31 | }else if (it < target){ 32 | return Find(target, array, row, column+1); 33 | }else{ 34 | return Find(target, array, row-1, column); 35 | } 36 | } 37 | bool Find(int target, std::vector > array) { 38 | return Find(target, array, array.size()-1, 0); 39 | } 40 | 41 | void test_find(){ 42 | std::vector > v{{1,2,8,9},{2,4,9,12},{4,7,10,13},{6,8,11,15}}; 43 | std::cout << "test_find starting........" < 13 | #include "reverse_integer.h" 14 | /* 15 | 9. 回文数 16 | 判断一个整数是否是回文数。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。 17 | 18 | 示例 1: 19 | 20 | 输入: 121 21 | 输出: true 22 | 示例 2: 23 | 24 | 输入: -121 25 | 输出: false 26 | 解释: 从左向右读, 为 -121 。 从右向左读, 为 121- 。因此它不是一个回文数。 27 | 示例 3: 28 | 29 | 输入: 10 30 | 输出: false 31 | 解释: 从右向左读, 为 01 。因此它不是一个回文数。 32 | 进阶: 33 | 34 | 你能不将整数转为字符串来解决这个问题吗? 35 | 36 | 来源:力扣(LeetCode) 37 | 链接:https://leetcode-cn.com/problems/palindrome-number 38 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 39 | */ 40 | 41 | namespace leetcode { 42 | /* 43 | 思路1: 44 | 整体反转,然后判断是否相等 45 | */ 46 | bool isPalindrome2(int x) { 47 | if (x<0) return false; 48 | return x == reverse(x); 49 | } 50 | /* 51 | 思路2: 52 | 我们只反转一半的数字,然后判断前后是否相等。 53 | 那么怎么判断数字旋转了一半呢? 54 | */ 55 | bool isPalindrome(int x) { 56 | if (x<0 || x % 10 == 0 && x!=0) return false; 57 | int revalue = 0; 58 | while(x > revalue){ 59 | revalue = revalue*10+x%10; 60 | x/=10; 61 | } 62 | //判断前后是否相等有两种情况: 63 | //1.比如 : 1221 ,x=12,revalue=12 64 | //2.比如 : 12321,x=12,revalue=123 65 | return x == revalue || x == revalue/10; 66 | } 67 | } 68 | #endif /* palindrome_number_hpp */ 69 | -------------------------------------------------------------------------------- /tree/coding-interviews/treeToDoublyList.h: -------------------------------------------------------------------------------- 1 | // 2 | // treeToDoublyList.h 3 | // tree 4 | // 5 | // Created by junl on 2020/5/16. 6 | // Copyright © 2020 junl. All rights reserved. 7 | // 8 | 9 | #ifndef treeToDoublyList_h 10 | #define treeToDoublyList_h 11 | namespace codinginterviews { 12 | class TreeToDoublyList { 13 | // Definition for a Node. 14 | public: 15 | class Node { 16 | public: 17 | int val; 18 | Node* left; 19 | Node* right; 20 | 21 | Node() {} 22 | 23 | Node(int _val) { 24 | val = _val; 25 | left = NULL; 26 | right = NULL; 27 | } 28 | 29 | Node(int _val, Node* _left, Node* _right) { 30 | val = _val; 31 | left = _left; 32 | right = _right; 33 | } 34 | }; 35 | Node* treeToDoublyList(Node* root) { 36 | if(!root) return nullptr; 37 | Node* head = nullptr, *pre = nullptr; 38 | helper(root, head, pre); 39 | head->left = pre; 40 | pre->right = head; 41 | return head; 42 | } 43 | void helper(Node* root, Node*& head, Node*& pre) { 44 | if(!root) return; 45 | helper(root->left, head, pre); 46 | if(!head) { 47 | head = root; // 找到head 48 | pre = root; // 对pre进行初始化 49 | } else { 50 | pre->right = root; 51 | root->left = pre; 52 | pre = root; 53 | } 54 | helper(root->right, head, pre); 55 | } 56 | }; 57 | }; 58 | 59 | 60 | #endif /* treeToDoublyList_h */ 61 | -------------------------------------------------------------------------------- /tree/leetcode/invertTree.h: -------------------------------------------------------------------------------- 1 | // 2 | // invertTree.h 3 | // tree 4 | // 5 | // Created by junl on 2019/7/30. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef invertTree_hpp 10 | #define invertTree_hpp 11 | 12 | #include 13 | 14 | /* 15 | 226.翻转一棵二叉树。 16 | 17 | 示例: 18 | 19 | 输入: 20 | 21 | 4 22 | / \ 23 | 2 7 24 | / \ / \ 25 | 1 3 6 9 26 | 输出: 27 | 28 | 4 29 | / \ 30 | 7 2 31 | / \ / \ 32 | 9 6 3 1 33 | 34 | 35 | 来源:力扣(LeetCode) 36 | 链接:https://leetcode-cn.com/problems/invert-binary-tree 37 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 38 | */ 39 | 40 | TreeNode* invertTree(TreeNode* root) { 41 | if (root == nullptr) 42 | return nullptr; 43 | TreeNode *node = new TreeNode(root->val); 44 | node->lchild = invertTree(root->rchild); 45 | node->rchild = invertTree(root->lchild); 46 | return node; 47 | } 48 | namespace leetcode{ 49 | void test_invertTree(){ 50 | TreeNode *node4 = new TreeNode(4); 51 | TreeNode *node2 = new TreeNode(2); 52 | TreeNode *node7 = new TreeNode(7); 53 | TreeNode *node1 = new TreeNode(1); 54 | TreeNode *node3 = new TreeNode(3); 55 | TreeNode *node6 = new TreeNode(6); 56 | TreeNode *node9 = new TreeNode(9); 57 | node4->lchild = node2; 58 | node4->rchild = node7; 59 | node2->lchild = node1; 60 | node2->rchild = node3; 61 | node7->lchild = node6; 62 | node7->rchild = node9; 63 | 64 | 65 | TreeNode *root = invertTree(node4); 66 | root; 67 | } 68 | } 69 | #endif /* invertTree_hpp */ 70 | -------------------------------------------------------------------------------- /linkedList/leetcode/medium/addTwoNumbers.h: -------------------------------------------------------------------------------- 1 | // 2 | // addTwoNumbers.h 3 | // linkedList 4 | // 5 | // Created by junlongj on 2019/8/15. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef addTwoNumbers_hpp 10 | #define addTwoNumbers_hpp 11 | 12 | #include 13 | /* 14 | 2.两数相加 15 | 给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。 16 | 17 | 如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。 18 | 19 | 您可以假设除了数字 0 之外,这两个数都不会以 0 开头。 20 | 21 | 示例: 22 | 23 | 输入:(2 -> 4 -> 3) + (5 -> 6 -> 4) 24 | 输出:7 -> 0 -> 8 25 | 原因:342 + 465 = 807 26 | 27 | 来源:力扣(LeetCode) 28 | 链接:https://leetcode-cn.com/problems/add-two-numbers 29 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 30 | */ 31 | 32 | namespace leetcode { 33 | ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) { 34 | if (!l1 || !l2) return nullptr; 35 | int flag = 0; 36 | ListNode *head = new ListNode(0); 37 | ListNode *ct = head; 38 | while(l1 || l2){ 39 | int a1=0,a2=0; 40 | if (l1){ 41 | a1=l1->val; 42 | l1=l1->next; 43 | } 44 | if (l2){ 45 | a2=l2->val; 46 | l2=l2->next; 47 | } 48 | int v = a1 + a2 + flag; 49 | flag = v/10; 50 | ListNode *node = new ListNode(v%10); 51 | ct->next=node; 52 | ct=ct->next; 53 | } 54 | if (flag) 55 | ct->next = new ListNode(flag); 56 | return head->next; 57 | } 58 | } 59 | #endif /* addTwoNumbers_hpp */ 60 | -------------------------------------------------------------------------------- /linkedList/leetcode/easy/hasCycle.h: -------------------------------------------------------------------------------- 1 | // 2 | // hasCycle.h 3 | // linkedList 4 | // 5 | // Created by junl on 2019/7/17. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef hasCycle_hpp 10 | #define hasCycle_hpp 11 | 12 | #include 13 | #include "singlyLinkedList.h" 14 | namespace leetcode { 15 | /* 16 | 141.给定一个链表,判断链表中是否有环。 17 | 18 | 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。 19 | 20 |   21 | 22 | 示例 1: 23 | 24 | 输入:head = [3,2,0,-4], pos = 1 25 | 输出:true 26 | 解释:链表中有一个环,其尾部连接到第二个节点。 27 | 28 | 29 | 来源:力扣(LeetCode) 30 | 链接:https://leetcode-cn.com/problems/linked-list-cycle 31 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 32 | */ 33 | bool hasCycle(ListNode *head) { 34 | ListNode *fast,*slow; 35 | fast = slow = head; 36 | while (fast && fast->next) { 37 | slow = slow->next; 38 | fast = fast->next->next; 39 | if (slow == fast) { 40 | return true; 41 | } 42 | } 43 | return false; 44 | } 45 | 46 | void test_hasCycle(){ 47 | singlyLinkedList ll; 48 | ll.insertTail(3); 49 | ll.insertTail(2); 50 | ll.insertTail(0); 51 | ll.insertTail(-4); 52 | ListNode *l2 = ll.findByValue(2); 53 | ListNode *l4 = ll.findByValue(-4); 54 | l4->next = l2; 55 | std::cout << "test_hasCycle: " << hasCycle(ll.start()) << std::endl; 56 | 57 | } 58 | } 59 | 60 | #endif /* hasCycle_hpp */ 61 | -------------------------------------------------------------------------------- /sort/countingSort.h: -------------------------------------------------------------------------------- 1 | // 2 | // countingSort.h 3 | // sort 4 | // 5 | // Created by junl on 2019/7/19. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef countingSort_hpp 10 | #define countingSort_hpp 11 | 12 | #include 13 | /* 14 | 计数排序是一种更细粒度的桶排序. 15 | 桶排序的核心思想是将要排序的数据分为几个桶,每个桶内部在单独进行排序,桶排完序之后,在把每个桶的数据按照顺序依次取出,组成的序列就是有序的。 16 | 而计数排序,假设这些数的最大值为max,那么它就分成max+1个桶(0,1,2....max).这样每个桶内部就不用在排序了。 17 | 18 | */ 19 | //数组里面存储的是学生考试的分数 20 | void countingSort(int nums[], int n){ 21 | 22 | //1.先要分为max个桶,里面保存每个分数的人数 23 | //2.建立新数组,每个位置保存小于等于这个分数的人数 24 | //3.从后向前开始遍历,然后把数据放在正确的位置 25 | 26 | if (n <= 1) { 27 | return; 28 | } 29 | //先求出数值最大的分数 30 | int max = nums[0]; 31 | for(int i=0;i max) 33 | max = nums[i]; 34 | } 35 | //建立max+1个桶,idex为分数,value为该分数的个数 36 | int bucket[max+1]; 37 | for(int i=0;i<=max;i++){ 38 | bucket[i]=0; 39 | } 40 | for(int i=0;i=0; i--) { 52 | //分数小于等于i分的有a人 53 | int score = nums[i]; 54 | int a = scores2[score]; 55 | temp[a-1] = score; 56 | scores2[score]-=1; 57 | } 58 | 59 | for (int i=0; i 13 | #include 14 | /* 15 | 正则表达式匹配,假设通配符只有两个,一个是*,一个是? 16 | * 代表可以匹配任意多个(>=0)任意字符. 17 | ? 代表匹配另个或一个任意字符 18 | 19 | 对于字符串的匹配,对于字符来说有两种情况: 20 | 1.如果是非通配符情况下,必须完全匹配 21 | 2.如果是通配字符,就有很多种选择了,就拿*来说,它可以匹配任意多个任意字符,这里我们利用回溯的思想穷举出所有的情况. 22 | 23 | */ 24 | 25 | typedef struct { 26 | const char *str; 27 | size_t slen; 28 | const char *pattern; 29 | size_t plen; 30 | bool match; 31 | }match_t; 32 | 33 | void match(match_t *context, int pidx, int sidx); 34 | bool isMatch(const char *str, const char *pattern){ 35 | match_t m = (match_t){str, strlen(str), pattern, strlen(pattern), false}; 36 | match(&m, 0, 0); 37 | return m.match; 38 | } 39 | 40 | void match(match_t *context, int pidx, int sidx){ 41 | if (context->match) return; 42 | 43 | if (pidx == context->plen){ 44 | if (sidx == context->slen) 45 | context->match = true; 46 | } 47 | 48 | char ch = context->pattern[pidx]; 49 | if (ch == '?'){ 50 | match(context, pidx+1, sidx); 51 | match(context, pidx+1, sidx+1); 52 | }else if (ch == '*'){ 53 | for (int i=0; i <= context->slen - sidx; i++) { 54 | match(context, pidx+1, sidx+i); 55 | } 56 | }else if (sidx < context->slen && ch == context->str[sidx]){ 57 | match(context, pidx+1, sidx+1); 58 | } 59 | 60 | } 61 | #endif /* Pattern_hpp */ 62 | -------------------------------------------------------------------------------- /backtracking/leetcode/medium/subsets.h: -------------------------------------------------------------------------------- 1 | // 2 | // subsets.h 3 | // backtracking 4 | // 5 | // Created by junl on 2019/9/23. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef subsets_hpp 10 | #define subsets_hpp 11 | 12 | #include 13 | /* 14 | 78.子集 15 | 给定一组不含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。 16 | 17 | 说明:解集不能包含重复的子集。 18 | 19 | 示例: 20 | 21 | 输入: nums = [1,2,3] 22 | 输出: 23 | [ 24 | [3], 25 |   [1], 26 |   [2], 27 |   [1,2,3], 28 |   [1,3], 29 |   [2,3], 30 |   [1,2], 31 |   [] 32 | ] 33 | 34 | 来源:力扣(LeetCode) 35 | 链接:https://leetcode-cn.com/problems/subsets 36 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 37 | */ 38 | 39 | namespace leetcode { 40 | /* 41 | 思路: 42 | 有点类似0,1背包的问题,我们把问题的求解分成N个阶段,每个阶段,我们可以选择数组nums第n个数字是否放进结果里面,最终回溯出结果. 43 | */ 44 | class Solution78 { 45 | public: 46 | vector> subsets(vector& nums) { 47 | vector elements; 48 | subsets(nums, elements, 0); 49 | return results; 50 | } 51 | 52 | private: 53 | vector> results; 54 | void subsets(vector& nums, vector elements, int ctindex){ 55 | if (ctindex == nums.size()){ 56 | results.push_back(elements); 57 | return; 58 | } 59 | 60 | //对于数组里面的每一个元素,我们可以选择把他放进去,也可以选择不放进去. 61 | subsets(nums, elements, ctindex+1); 62 | 63 | elements.push_back(nums[ctindex]); 64 | subsets(nums, elements, ctindex+1); 65 | elements.pop_back(); 66 | } 67 | }; 68 | } 69 | 70 | #endif /* subsets_hpp */ 71 | -------------------------------------------------------------------------------- /linkedList/coding-interviews/FindFirstCommonNode.h: -------------------------------------------------------------------------------- 1 | // 2 | // FindFirstCommonNode.h 3 | // linkedList 4 | // 5 | // Created by junl on 2019/8/2. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef FindFirstCommonNode_hpp 10 | #define FindFirstCommonNode_hpp 11 | 12 | #include 13 | 14 | /* 15 | 剑指Offer(三十六):两个链表的第一个公共结点 16 | 输入两个链表,找出它们的第一个公共结点。 17 | https://www.nowcoder.com/practice/6ab1d9a29e88450685099d45c9e31e46?tpId=13&tqId=11189&tPage=2&rp=1&ru=%2Fta%2Fcoding-interviews&qru=%2Fta%2Fcoding-interviews%2Fquestion-ranking 18 | */ 19 | 20 | namespace codinginterviews { 21 | ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) { 22 | if (pHead1 == nullptr || pHead2 == nullptr) { 23 | return nullptr; 24 | } 25 | int size1=0,size2=0; 26 | ListNode *ct1 = pHead1; 27 | while (ct1) { 28 | size1++; 29 | ct1=ct1->next; 30 | } 31 | ListNode *ct2 = pHead2; 32 | while (ct2) { 33 | size2++; 34 | ct2=ct2->next; 35 | } 36 | //链表长的先多走几步,这样他们到末尾的距离是一样的 37 | ListNode *fast = size1 < size2 ? pHead2 : pHead1; 38 | ListNode *slow = fast == pHead2 ? pHead1 : pHead2; 39 | int i=0; 40 | while (inext; 42 | i++; 43 | } 44 | while (fast && slow) { 45 | if (fast == slow) { 46 | return fast; 47 | } 48 | fast = fast->next; 49 | slow = slow->next; 50 | } 51 | 52 | return nullptr; 53 | } 54 | } 55 | #endif /* FindFirstCommonNode_hpp */ 56 | -------------------------------------------------------------------------------- /array/leetcode/maxArea.h: -------------------------------------------------------------------------------- 1 | // 2 | // maxArea.h 3 | // array 4 | // 5 | // Created by junl on 2019/7/26. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef maxArea_hpp 10 | #define maxArea_hpp 11 | 12 | #include 13 | #include 14 | /* 15 | 11. 给定 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) 。在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 (i, ai) 和 (i, 0)。找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。 16 | 17 | 说明:你不能倾斜容器,且 n 的值至少为 2。 18 | 19 | 20 | 21 | 图中垂直线代表输入数组 [1,8,6,2,5,4,8,3,7]。在此情况下,容器能够容纳水(表示为蓝色部分)的最大值为 49。 22 | 23 |   24 | 25 | 示例: 26 | 27 | 输入: [1,8,6,2,5,4,8,3,7] 28 | 输出: 49 29 | 30 | 来源:力扣(LeetCode) 31 | 链接:https://leetcode-cn.com/problems/container-with-most-water 32 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 33 | */ 34 | 35 | #pragma mark - 方法一:双指针前后移动 36 | int maxArea(const std::vector& height) { 37 | //1,2,4,3 38 | //0,1,2,3 39 | if (height.size() <= 1) { 40 | return 0; 41 | } 42 | int maxarea=0; 43 | size_t i=0; 44 | size_t j=height.size()-1; 45 | while (i < j) { 46 | int area = static_cast((j - i) * std::min(height[i], height[j])); 47 | maxarea = std::max(maxarea, area); 48 | // 区域的面积实际上是由最短的一条边决定的,因此我们想要增加增大面积其实就是要增加最短边的值。 49 | // height[i] < height[j] ? i++ : j--; 50 | // 高效的方式 51 | if (height[i] < height[j]) { 52 | do{ 53 | i++; 54 | } while (i< j && height[i-1] >= height[i]) ; //找到比左边那条边大的 55 | }else{ 56 | do{ 57 | j--; 58 | }while (i < j && height[j] <= height[j+1]); 59 | } 60 | } 61 | return maxarea; 62 | } 63 | 64 | #endif /* maxArea_hpp */ 65 | -------------------------------------------------------------------------------- /other/coding-interviews/Power.h: -------------------------------------------------------------------------------- 1 | // 2 | // Power.h 3 | // other 4 | // 5 | // Created by junlongj on 2019/8/4. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef Power_hpp 10 | #define Power_hpp 11 | 12 | #include 13 | /* 14 | 剑指Offer(十二):数值的整数次方 15 | 给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。 16 | https://www.nowcoder.com/practice/1a834e5e3e1a4b7ba251417554e07c00?tpId=13&tqId=11165&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking 17 | */ 18 | 19 | namespace codinginterviews { 20 | //注意exponent的取值,可正可负 21 | double myPowWithSignedExponent(double x, int n); 22 | int equal(double x, double y); 23 | double myPow(double x, int n){ 24 | if (equal(x, 0) && n < 0){ 25 | return 0;//输入无效 26 | } 27 | //指数存在正数和负数 28 | signed int absN = n > 0 ? -n : n; 29 | double res = myPowWithSignedExponent(x, absN); 30 | if (n < 0){ 31 | res = 1.0 / res; 32 | } 33 | return res; 34 | } 35 | int equal(double x, double y){ 36 | if (x - y <= 0.0000001 && x - y >= -0.0000001){ 37 | return 1; 38 | } 39 | return 0; 40 | } 41 | double myPowWithSignedExponent(double x, int n){ 42 | if (n == 0) return 1; 43 | if (n == -1) return x; 44 | double val = myPowWithSignedExponent(x, n >> 1); 45 | val *= val; 46 | if (n % 2 == -1) 47 | val *= x; 48 | return val; 49 | } 50 | 51 | void test_Power(){ 52 | std::cout << "Power starting......." < 13 | #include 14 | #include 15 | namespace leetcode { 16 | /* 17 | 32.给定一个只包含 '(' 和 ')' 的字符串,找出最长的包含有效括号的子串的长度。 18 | 19 | 示例 1: 20 | 21 | 输入: "(()" 22 | 输出: 2 23 | 解释: 最长有效括号子串为 "()" 24 | 示例 2: 25 | 26 | 输入: ")()())" 27 | 输出: 4 28 | 解释: 最长有效括号子串为 "()()" 29 | 30 | 来源:力扣(LeetCode) 31 | 链接:https://leetcode-cn.com/problems/longest-valid-parentheses 32 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 33 | */ 34 | int longestValidParentheses(std::string &s) { 35 | int maxlen = 0; 36 | 37 | std::stack stk;//栈里面只存储***左括号****的位置 38 | int errorindex = -1; 39 | for(int i=0;i 12 | 13 | 14 | /** 15 | * @brief 自定义一个双向的迭代器. 需要实现向前迭代,前后迭代. 也就是说需要实现*,->,++,++(int),--,--(int),!=,== 16 | */ 17 | template 18 | class DSIterator { 19 | public: 20 | typedef std::bidirectional_iterator_tag iterator_category; 21 | typedef _Iter value_type; 22 | typedef std::ptrdiff_t difference_type; 23 | typedef _Iter* pointer; 24 | typedef _Iter& reference; 25 | DSIterator(_Iter* thePosition=0):position(thePosition){} 26 | //解引用 27 | _Iter& operator*(){ 28 | return *position; 29 | } 30 | _Iter* operator->(){ 31 | return &*position; 32 | } 33 | //例如++a 34 | DSIterator& operator++() { 35 | ++position; 36 | //this指向的是DSIterator<_Iter>,*this才是DSIterator<_Iter> 37 | return *this; 38 | } 39 | //例如a++ 40 | DSIterator operator++(int) { 41 | DSIterator __tmp(*this); 42 | ++position; 43 | return __tmp; 44 | } 45 | DSIterator& operator--() { 46 | --position; 47 | return *this;} 48 | DSIterator operator--(int) { 49 | DSIterator __tmp(*this); 50 | --position; 51 | return __tmp;} 52 | 53 | bool operator==(const DSIterator& other){ 54 | return position == other.position; 55 | } 56 | bool operator!=(const DSIterator& other){ 57 | return position != other.position; 58 | } 59 | protected: 60 | _Iter* position;//指向数组里的元素 61 | }; 62 | 63 | 64 | #endif /* DSIterator_hpp */ 65 | -------------------------------------------------------------------------------- /array/leetcode/easy/removeDuplicates.h: -------------------------------------------------------------------------------- 1 | // 2 | // removeDuplicates.h 3 | // array 4 | // 5 | // Created by junlongj on 2019/7/28. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef removeDuplicates_hpp 10 | #define removeDuplicates_hpp 11 | 12 | #include 13 | #include 14 | /* 15 | 26.给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。 16 | 17 | 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。 18 | 19 | 示例 1: 20 | 21 | 给定数组 nums = [1,1,2], 22 | 23 | 函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2。 24 | 25 | 你不需要考虑数组中超出新长度后面的元素。 26 | 示例 2: 27 | 28 | 给定 nums = [0,0,1,1,1,2,2,3,3,4], 29 | 30 | 函数应该返回新的长度 5, 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4。 31 | 32 | 你不需要考虑数组中超出新长度后面的元素。 33 | 说明: 34 | 35 | 为什么返回数值是整数,但输出的答案是数组呢? 36 | 37 | 请注意,输入数组是以“引用”方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。 38 | 39 | 你可以想象内部操作如下: 40 | 41 | // nums 是以“引用”方式传递的。也就是说,不对实参做任何拷贝 42 | int len = removeDuplicates(nums); 43 | 44 | // 在函数里修改输入数组对于调用者是可见的。 45 | // 根据你的函数返回的长度, 它会打印出数组中该长度范围内的所有元素。 46 | for (int i = 0; i < len; i++) { 47 |     print(nums[i]); 48 | } 49 | 50 | 来源:力扣(LeetCode) 51 | 链接:https://leetcode-cn.com/problems/remove-duplicates-from-sorted-array 52 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 53 | */ 54 | int removeDuplicates(std::vector& nums) { 55 | /* 56 | 思路:利用快慢指针,慢指针始终指向不相同数组的末尾,然后开始遍历,如果nums[i]和nums[j]一样,那么过滤掉重复项,j++. 57 | 否则的话,将不同项nums[j]拷贝给nums[++i]; 58 | */ 59 | size_t size = nums.size(); 60 | if (size <= 1) { 61 | return size; 62 | } 63 | 64 | int j=0; 65 | for (int i=1; i 13 | #include 14 | /* 15 | 33.假设按照升序排序的数组在预先未知的某个点上进行了旋转。 16 | 17 | ( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] )。 18 | 19 | 搜索一个给定的目标值,如果数组中存在这个目标值,则返回它的索引,否则返回 -1 。 20 | 21 | 你可以假设数组中不存在重复的元素。 22 | 23 | 你的算法时间复杂度必须是 O(log n) 级别。 24 | 25 | 示例 1: 26 | 27 | 输入: nums = [4,5,6,7,0,1,2], target = 0 28 | 输出: 4 29 | 示例 2: 30 | 31 | 输入: nums = [4,5,6,7,0,1,2], target = 3 32 | 输出: -1 33 | 34 | 来源:力扣(LeetCode) 35 | 链接:https://leetcode-cn.com/problems/search-in-rotated-sorted-array 36 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 37 | 38 | */ 39 | 40 | int search(std::vector& nums, int target) { 41 | 42 | int left=0; 43 | int right=nums.size()-1; 44 | while (left <= right) { 45 | //数组旋转过一次,所以一边肯定是有序的,另一边无序. 46 | int mid = left + (right - left) / 2; 47 | if (nums[mid] == target) 48 | return mid; 49 | 50 | if (nums[right] < nums[mid]) { 51 | //左边是有序的 52 | if (nums[left] <= target && nums[mid] > target) { 53 | right = mid - 1; 54 | }else{ 55 | left = mid + 1; 56 | } 57 | }else{ 58 | if (nums[mid] < target && nums[right] >= target) { 59 | left = mid + 1; 60 | }else{ 61 | right = mid - 1; 62 | } 63 | } 64 | } 65 | return -1; 66 | } 67 | 68 | #endif /* searchInRotatedSortedArray_hpp */ 69 | -------------------------------------------------------------------------------- /bsearch/leetcode/medium/searchRange.h: -------------------------------------------------------------------------------- 1 | // 2 | // searchRange.h 3 | // bsearch 4 | // 5 | // Created by junlongj on 2019/8/26. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef searchRange_hpp 10 | #define searchRange_hpp 11 | 12 | #include 13 | #include 14 | /* 15 | 34.在排序数组中查找元素的第一个和最后一个位置 16 | 17 | 给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。 18 | 19 | 你的算法时间复杂度必须是 O(log n) 级别。 20 | 21 | 如果数组中不存在目标值,返回 [-1, -1]。 22 | 23 | 示例 1: 24 | 25 | 输入: nums = [5,7,7,8,8,10], target = 8 26 | 输出: [3,4] 27 | 示例 2: 28 | 29 | 输入: nums = [5,7,7,8,8,10], target = 6 30 | 输出: [-1,-1] 31 | 32 | 来源:力扣(LeetCode) 33 | 链接:https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array 34 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 35 | 36 | */ 37 | 38 | namespace leetcod { 39 | using namespace std; 40 | vector searchRange(vector& nums, int target) { 41 | if (nums.empty()) return {-1,-1}; 42 | int size = nums.size(); 43 | int left=0; 44 | int right=size-1; 45 | while(left<=right){ 46 | int mid=left+(right-left)/2; 47 | if (nums[mid] == target){ 48 | int s,e; 49 | s = e = mid; 50 | while(s >= 1 &&nums[s-1] == nums[s]){ 51 | s--; 52 | } 53 | while(e+1 < size &&nums[e] == nums[e+1]){ 54 | e++; 55 | } 56 | return {s,e}; 57 | }else if (nums[mid] < target){ 58 | left=mid+1; 59 | }else{ 60 | right=mid-1; 61 | } 62 | } 63 | return {-1,-1}; 64 | } 65 | } 66 | #endif /* searchRange_hpp */ 67 | -------------------------------------------------------------------------------- /linkedList/coding-interviews/Clone.h: -------------------------------------------------------------------------------- 1 | // 2 | // Clone.h 3 | // linkedList 4 | // 5 | // Created by junl on 2019/8/2. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef Clone_hpp 10 | #define Clone_hpp 11 | 12 | #include 13 | #include 14 | /* 15 | 剑指Offer(二十五):复杂链表的复制 16 | 17 | 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空) 18 | https://www.nowcoder.com/practice/f836b2c43afc4b35ad6adc41ec941dba?tpId=13&tqId=11178&tPage=2&rp=1&ru=%2Fta%2Fcoding-interviews&qru=%2Fta%2Fcoding-interviews%2Fquestion-ranking 19 | */ 20 | 21 | namespace codinginterviews { 22 | struct RandomListNode { 23 | int label; 24 | struct RandomListNode *next, *random; 25 | RandomListNode(int x) : 26 | label(x), next(NULL), random(NULL) { 27 | } 28 | }; 29 | 30 | RandomListNode* Clone(RandomListNode* pHead) 31 | { 32 | RandomListNode *root = new RandomListNode(0); 33 | RandomListNode *newct = root; 34 | RandomListNode *ct = pHead; 35 | std::map maps; 36 | //第一次循环构建出单链表 37 | while (ct) { 38 | newct->next = new RandomListNode(ct->label); 39 | maps[ct->label] = newct->next; 40 | newct = newct->next; 41 | ct = ct->next; 42 | } 43 | //第二次循环构建random节点 44 | ct = pHead; 45 | newct = root->next; 46 | while (ct) { 47 | if (ct->random) { 48 | newct->random = maps[ct->random->label]; 49 | } 50 | ct = ct->next; 51 | newct = newct->next; 52 | } 53 | return root->next; 54 | } 55 | } 56 | 57 | 58 | #endif /* Clone_hpp */ 59 | -------------------------------------------------------------------------------- /array/coding-interviews/GetNumberOfK.h: -------------------------------------------------------------------------------- 1 | // 2 | // GetNumberOfK.h 3 | // array 4 | // 5 | // Created by junlongj on 2019/8/3. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef GetNumberOfK_hpp 10 | #define GetNumberOfK_hpp 11 | 12 | #include 13 | #include 14 | /* 15 | 剑指Offer(三十七):数字在排序数组中出现的次数 16 | 统计一个数字在排序数组中出现的次数。 17 | https://www.nowcoder.com/practice/70610bf967994b22bb1c26f9ae901fa2?tpId=13&tqId=11190&tPage=2&rp=1&ru=%2Fta%2Fcoding-interviews&qru=%2Fta%2Fcoding-interviews%2Fquestion-ranking 18 | */ 19 | namespace codinginterviews { 20 | /* 21 | 先找出第一个出现k的位置,然后在统计个数 22 | */ 23 | int GetNumberOfK(std::vector data ,int k) { 24 | int count = 0; 25 | int left =0; 26 | int right = data.size()-1; 27 | int minKindex = 0; 28 | while (left <= right) { 29 | int mid = left + (right- left)/2; 30 | if (data[mid] == k) { 31 | //找到第一个k 32 | if (mid != 0 && data[mid-1] != k) { 33 | minKindex = mid; 34 | break; 35 | } 36 | right = mid-1; 37 | }else if (data[mid] < k){ 38 | left = mid+1; 39 | }else{ 40 | right = mid-1; 41 | } 42 | } 43 | while (minKindex < data.size()) { 44 | if (data[minKindex++] == k) { 45 | count++; 46 | } 47 | } 48 | return count; 49 | } 50 | void test_GetNumberOfK(){ 51 | std::cout << "GetNumberOfK: starting....... " << std::endl; 52 | std::vector a{1,2,3,3,3,4,4}; 53 | std::cout << GetNumberOfK(a, 5) << std::endl; 54 | } 55 | } 56 | 57 | #endif /* GetNumberOfK_hpp */ 58 | -------------------------------------------------------------------------------- /tree/coding-interviews/VerifySquenceOfBST.h: -------------------------------------------------------------------------------- 1 | // 2 | // VerifySquenceOfBST.h 3 | // tree 4 | // 5 | // Created by junlongj on 2019/8/3. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef VerifySquenceOfBST_hpp 10 | #define VerifySquenceOfBST_hpp 11 | 12 | #include 13 | #include 14 | /* 15 | 剑指Offer(二十三):二叉搜索树的后序遍历序列 16 | 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果。如果是则输出Yes,否则输出No。假设输入的数组的任意两个数字都互不相同。 17 | https://www.nowcoder.com/practice/a861533d45854474ac791d90e447bafd?tpId=13&tqId=11176&tPage=2&rp=1&ru=%2Fta%2Fcoding-interviews&qru=%2Fta%2Fcoding-interviews%2Fquestion-ranking 18 | */ 19 | 20 | namespace codinginterviews { 21 | /* 22 | 后序遍历顺序:左右根. 23 | 思路:先找到左子树和右子树的分界线,然后递归判断是否满足条件 24 | */ 25 | bool verifyPostorder(int* postorder, int postorderSize){ 26 | if (postorder == NULL || postorderSize == 0) return true; 27 | 28 | int rootvalue = postorder[postorderSize-1]; 29 | int i, j; 30 | for(i=0;i < postorderSize-1; i++){ 31 | if (postorder[i] > rootvalue) 32 | break; 33 | } 34 | for(j = i; j < postorderSize-1; j++){ 35 | if (postorder[j] < rootvalue) 36 | return false; 37 | } 38 | int result = 1; 39 | if (i > 0) 40 | result = verifyPostorder(postorder, i); 41 | if (result && i < postorderSize-1) //如果左子树已经不满足,那么久没有必要监测右子树了. 42 | result &= verifyPostorder(postorder+i, postorderSize-i-1); 43 | 44 | return result; 45 | } 46 | void test_verifyPostorder(){ 47 | int post[] = {1,3,2,6,5}; 48 | int result = verifyPostorder(post, 5); 49 | printf("test_verifyPostorder: %d\n",result); 50 | } 51 | } 52 | #endif /* VerifySquenceOfBST_hpp */ 53 | -------------------------------------------------------------------------------- /divideandconquer.md: -------------------------------------------------------------------------------- 1 | # 分治算法 2 | 3 | 分治算法的核心思想就是分而治之。将问题尺寸为N的问题分解成两个独立的部分,然后递归性去解决这些子问题,最后将子问题的解合并成结果,就得到了原问题的解. 4 | 5 | 6 | 7 | 分治算法能解决的问题,一般要满足下面几个条件: 8 | 9 | 1. 原问题和分解的小问题具有相同的求解模式. 10 | 2. 分解的子问题可以独立求解,子问题之间没有任何关联,这是分治和动态规划最明显的区别 11 | 3. 具有分解的终止条件,也就是说当问题足够小时,可以直接求解. 12 | 4. 可以将子问题的求解合并成原问题,而这个合并操作的复杂度不能太高,否则就起不到减少算法总体的复杂度效果了。 13 | 14 | 15 | 16 | 分治算法的范例: 17 | 18 | - 二分搜索 19 | - 归并排序 20 | 21 | 它们都是将规模为N的大问题一分为二,在对子问题求解的过程. 递归表明了每个算法的分治计算本质. 22 | 23 | 快速排序和二叉树搜索代表了分治算法的变异版本,它将问题剖成为`k-1`和 `N - k`的子问题,其中的k是由输入决定的某个值. 对于随机输入,这些算法将问题分解成大体上一半大小的子问题. 当我们讨论这些算法时,就会分析这种差异的效果. 24 | 25 | 26 | -------------------------------------------------------------------------------- /recursion/main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // main.cpp 3 | // recursion 4 | // 5 | // Created by junlongj on 2019/8/4. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #include 10 | #include "Fibonacci.h" 11 | #include "jumpFloor.h" 12 | #include "jumpFloorII.h" 13 | #include "rectCover.h" 14 | #include "generateParenthesis.h" 15 | #include "permutations.h" 16 | #include "longestUnivaluePath.h" 17 | #include 18 | /** 19 | * Note: The returned array must be malloced, assume caller calls free(). 20 | */ 21 | void helper(double *nums, int len, int n, int ctsum); 22 | double* twoSum(int n, int* returnSize){ 23 | if (n == 0){ 24 | if (returnSize) *returnSize = 0; 25 | return NULL; 26 | } 27 | 28 | int minSum = n; 29 | int maxSum = 6 * n; 30 | int len = maxSum - minSum + 1; 31 | int allPointCnts = pow(6, n); 32 | double *nums = (double *)malloc(sizeof(double) * len); 33 | for(int i=0; i < len; i++) 34 | nums[0] = 0; 35 | helper(nums, len, n, 0); 36 | for(int i=0; i < len;i++){ 37 | nums[i] /= allPointCnts; 38 | } 39 | if (returnSize) *returnSize = len; 40 | return nums; 41 | } 42 | void helper(double *nums, int len, int n, int ctsum){ 43 | if (n == 0){ 44 | int idx = ctsum - n; 45 | nums[idx] += 1; 46 | return; 47 | } 48 | for(int i=0; i < 6;i++){ 49 | helper(nums, len, n-1, ctsum+(i+1)); 50 | } 51 | } 52 | int main(int argc, const char * argv[]) { 53 | // insert code here... 54 | codinginterviews::test_Fibonacci(); 55 | codinginterviews::test_jumpFloor(); 56 | leetcode::test_generateParenthesis2(); 57 | 58 | int s; 59 | double *r = twoSum(1, &s); 60 | for(int i=0;i 13 | #include 14 | /* 15 | 27.给定一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,返回移除后数组的新长度。 16 | 17 | 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成。 18 | 19 | 元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。 20 | 21 | 示例 1: 22 | 23 | 给定 nums = [3,2,2,3], val = 3, 24 | 25 | 函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。 26 | 27 | 你不需要考虑数组中超出新长度后面的元素。 28 | 29 | 来源:力扣(LeetCode) 30 | 链接:https://leetcode-cn.com/problems/remove-element 31 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 32 | https://leetcode-cn.com/problems/remove-element/ 33 | */ 34 | 35 | namespace leetcode { 36 | /* 37 | 思路:双指针,始终指针有效数组的末尾,然后遍历j,如果nums[j] != val,那么将nums[j]放在有效数组的末尾,即: 38 | nums[i] = nums[j]; 39 | i++; 40 | */ 41 | int removeElement(std::vector& nums, int val) { 42 | int i=0; 43 | for(int j=0;j& nums, int val) { 55 | int n=nums.size(); 56 | int j=0; 57 | while(j < n){ 58 | if (nums[j] == val){//主要遇到了val这个值,就将末尾元素赋给nums[j],注意新的末尾元素可能是有效值 59 | nums[j] = nums[n-1]; 60 | n--; 61 | }else{ 62 | j++; 63 | } 64 | } 65 | return n; 66 | } 67 | } 68 | #endif /* removeElement_hpp */ 69 | -------------------------------------------------------------------------------- /stack+queue/itinterviews/TwoStacksQueue.h: -------------------------------------------------------------------------------- 1 | // 2 | // TwoStacksQueue.h 3 | // stack+queue 4 | // 5 | // Created by junl on 2019/10/14. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef TwoStacksQueue_hpp 10 | #define TwoStacksQueue_hpp 11 | 12 | #include 13 | #include 14 | /* 15 | 思路: 16 | 两个栈正好可以实现倒序.关键点把pushStack的数据倒序放到popStack中: 17 | 1.如果popStack包含元素了的话,那么不能将数据从pushStack移动到popStack 18 | 2.必须一次性的把pushStackd里面的元素移动到popStack中 19 | */ 20 | class TwoStacksQueue { 21 | public: 22 | typedef int Value_t; 23 | void add(Value_t x)//添加元素 24 | { 25 | pushStack.push(x); 26 | } 27 | void poll()//删除队列首元素 28 | { 29 | move(); 30 | if (popStack.empty()) { 31 | throw stackEmpty(); 32 | } 33 | popStack.pop(); 34 | } 35 | Value_t peek()//获取首元素 36 | { 37 | if (popStack.empty() && pushStack.empty()) { 38 | throw stackEmpty(); 39 | } 40 | move(); 41 | return popStack.top(); 42 | } 43 | private: 44 | std::stack pushStack; 45 | std::stack popStack; 46 | void move(){ 47 | if (popStack.empty()) { 48 | //如果popStack为空,则把pushStack的所有元素倒序加入. 49 | while (!pushStack.empty()) { 50 | popStack.push(pushStack.top()); 51 | pushStack.pop(); 52 | } 53 | } 54 | } 55 | }; 56 | 57 | 58 | void test_TwoStacksQueue(){ 59 | std::cout << "-----------test_TwoStacksQueue-----------" << std::endl; 60 | TwoStacksQueue queue; 61 | queue.add(1); 62 | queue.add(2); 63 | queue.add(3); 64 | std::cout << "peek: "<< queue.peek() << std::endl;//1 65 | queue.poll(); 66 | std::cout << "peek: "<< queue.peek() << std::endl;//2 67 | 68 | } 69 | 70 | #endif /* TwoStacksQueue_hpp */ 71 | -------------------------------------------------------------------------------- /backtracking/main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // main.cpp 3 | // backtracking 4 | // 5 | // Created by junl on 2019/7/25. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #include 10 | #include "eightQueens.h" 11 | #include "knapsack.h" 12 | #include "hasPath.h" 13 | #include "letter_combinations_of_a_phone_number.h" 14 | #include "Pattern.h" 15 | #include "combinationSumII.h" 16 | #include "permutationsii.h" 17 | #include 18 | #include "permutation_sequence.h" 19 | #include "combinations.h" 20 | #include "subsets.h" 21 | #include "word_search.h" 22 | #include "gray_code.h" 23 | #include "subsets_ii.h" 24 | #include "restore_ip_addresses.h" 25 | bool isFindNum(int num){ 26 | int sum = 0; 27 | for (int i=1; i2 20 | 输出: false 21 | 示例 2: 22 | 23 | 输入: 1->2->2->1 24 | 输出: true 25 | 进阶: 26 | 你能否用 O(n) 时间复杂度和 O(1) 空间复杂度解决此题? 27 | 28 | 来源:力扣(LeetCode) 29 | 链接:https://leetcode-cn.com/problems/palindrome-linked-list 30 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 31 | */ 32 | ListNode* findMiddleNode(ListNode *head){ 33 | ListNode *fast,*slow; 34 | fast = slow = head; 35 | while (fast && fast ->next) { 36 | slow = slow->next; 37 | fast = fast->next->next; 38 | } 39 | return slow; 40 | } 41 | bool isPalindrome(ListNode* head) { 42 | if (!head) 43 | return false; 44 | 45 | if (!head->next) 46 | return true; 47 | 48 | ListNode *pMid = findMiddleNode(head); 49 | //翻转 50 | ListNode *pRev = reverseList(pMid); 51 | for(;head!=pMid; head=head->next, pRev=pRev->next) { 52 | if (head->val != pRev->val) { 53 | return false; 54 | } 55 | } 56 | return true; 57 | } 58 | 59 | void test_isPalindrome(){ 60 | singlyLinkedList ll; 61 | ll.insertTail(1); 62 | ll.insertTail(2); 63 | ll.insertTail(2); 64 | ll.insertTail(2); 65 | ll.insertTail(1); 66 | std::cout << "test_isPalindrome: " << isPalindrome(ll.start())< 13 | #include 14 | #include 15 | /* 16 | 剑指Offer(二十八):数组中出现次数超过一半的数字 17 | 18 | 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。 19 | https://www.nowcoder.com/practice/e8a1b01a2df14cb2b228b30ee6a92163?tpId=13&tqId=11181&tPage=2&rp=1&ru=%2Fta%2Fcoding-interviews&qru=%2Fta%2Fcoding-interviews%2Fquestion-ranking 20 | */ 21 | 22 | namespace codinginterviews { 23 | int MoreThanHalfNum_Solution(std::vector numbers) { 24 | int temp = numbers[0]; 25 | int markcount = 1; 26 | for (int i=1; i numbers.size()/2) { 44 | return result; 45 | } 46 | return 0; 47 | } 48 | 49 | void test_MoreThanHalfNum_Solution(){ 50 | std::vector a{1,2,3,2,4,2,5,2,3}; 51 | std::cout << "test_MoreThanHalfNum_Solution starting........" << std::endl; 52 | std::cout << MoreThanHalfNum_Solution(a) << std::endl; 53 | } 54 | } 55 | #endif /* MoreThanHalfNum_Solution_hpp */ 56 | -------------------------------------------------------------------------------- /array/leetcode/moveZeroes.h: -------------------------------------------------------------------------------- 1 | // 2 | // moveZeroes.h 3 | // array 4 | // 5 | // Created by junl on 2019/7/29. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef moveZeroes_hpp 10 | #define moveZeroes_hpp 11 | 12 | #include 13 | #include 14 | /* 15 | 283.给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。 16 | 17 | 示例: 18 | 19 | 输入: [0,1,0,3,12] 20 | 输出: [1,3,12,0,0] 21 | 说明: 22 | 23 | 必须在原数组上操作,不能拷贝额外的数组。 24 | 尽量减少操作次数。 25 | 26 | 27 | 来源:力扣(LeetCode) 28 | 链接:https://leetcode-cn.com/problems/move-zeroes 29 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 30 | */ 31 | 32 | //方法1 : i表示非零数组的末尾 33 | void moveZeroes(std::vector& nums) { 34 | size_t n = nums.size(); 35 | if (n <= 1) 36 | return; 37 | int i=0; 38 | for(int j=1;j& nums) { 53 | int i = 0; 54 | for (int j=0; j < nums.size(); j++) { 55 | //只要当前元素不为0,就保存到数组末尾. 56 | if (nums[j] != 0) { 57 | nums[i++] = nums[j]; //这个方法会有大量浪费浪费操作. 58 | } 59 | } 60 | //后面部分填0 61 | while (i& nums) { 67 | int i=0; 68 | //找到第一个为0的位置 69 | for (; i 11 | #include 12 | #include 13 | //统计算法完成时间 14 | #define TIME_INIT \ 15 | clock_t start, end; 16 | #define TIME_START \ 17 | start = clock(); 18 | 19 | #define TIME_END(msg) \ 20 | end = clock(); \ 21 | printf("%stime: %f s\n", msg, ((double)(end - start)) / CLOCKS_PER_SEC); 22 | 23 | int check_sort(ItemType a[], int l, int r){ 24 | for (; l < r; l++) { 25 | if (less(a[l+1], a[l])) { 26 | return 0; 27 | } 28 | } 29 | return 1; 30 | } 31 | void test_sort_drive(void){ 32 | printf("-------------排序---------------------\n\n\n"); 33 | #define N 10000 34 | ItemType items[N], i; 35 | ItemType sorts[N], rsorts[N], eqs[N],threes[N]; 36 | for (i = 0; i < N ; i++) { 37 | items[i] = 1000 * (1.0 * rand() / RAND_MAX); 38 | sorts[i] = i; 39 | rsorts[i] = N - i; 40 | eqs[i] = 1; 41 | threes[i] = random() % 3; 42 | } 43 | void (*sortfunc)(ItemType items[], int l, int r); 44 | sortfunc = sort_heap; 45 | 46 | TIME_INIT; 47 | TIME_START; 48 | sortfunc(items, 0, N - 1); 49 | TIME_END("排序随机元素"); 50 | 51 | TIME_START; 52 | sortfunc(sorts, 0, N - 1); 53 | TIME_END("排序已排序的数据源"); 54 | 55 | TIME_START; 56 | sortfunc(rsorts, 0, N - 1); 57 | TIME_END("排序逆序的数据源"); 58 | 59 | TIME_START; 60 | sortfunc(eqs, 0, N - 1); 61 | TIME_END("排序相同的数据源"); 62 | 63 | TIME_START; 64 | sortfunc(threes, 0, N - 1); 65 | TIME_END("排序只有三种元素的数据源"); 66 | 67 | assert(check_sort(items, 0, N-1) == 1); 68 | /* 69 | 排序随机元素time: 0.021226 s 70 | 排序已排序的数据源time: 0.001346 s 71 | 排序逆序的数据源time: 0.012575 s 72 | */ 73 | } 74 | -------------------------------------------------------------------------------- /backtracking/leetcode/medium/permutations.h: -------------------------------------------------------------------------------- 1 | // 2 | // permutations.h 3 | // recursion 4 | // 5 | // Created by junlongj on 2019/8/30. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef permutations_hpp 10 | #define permutations_hpp 11 | 12 | #include 13 | #include 14 | #include 15 | /* 16 | 46.全排列 17 | 给定一个没有重复数字的序列,返回其所有可能的全排列。 18 | 19 | 示例: 20 | 21 | 输入: [1,2,3] 22 | 输出: 23 | [ 24 | [1,2,3], 25 | [1,3,2], 26 | [2,1,3], 27 | [2,3,1], 28 | [3,1,2], 29 | [3,2,1] 30 | ] 31 | 32 | 来源:力扣(LeetCode) 33 | 链接:https://leetcode-cn.com/problems/permutations 34 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 35 | */ 36 | namespace leetcode { 37 | using namespace std; 38 | /* 39 | 思路:符合"在一组可能的解中,选出符合期望的结果"题型,首先联想到回溯算法。 40 | 41 | 我们将求解全排列求解过程,划分为N个阶段. 42 | 每个阶段我们穷举出所有可能的情况,即在数组中选择一个数: 43 | 1. 如果是已经选择过的直接掉过 44 | 2. 如果未选中,进入下一轮阶段。 45 | 46 | 直到N次排列完成. 47 | */ 48 | class Solution_46 { 49 | public: 50 | vector> permute(vector& nums) { 51 | vector elements; 52 | permute(nums, elements); 53 | return results; 54 | } 55 | private: 56 | vector> results; 57 | void permute(vector& nums, vector elements) { 58 | //终止条件 59 | if (elements.size() == nums.size()){ 60 | results.push_back(elements); 61 | return; 62 | } 63 | //递归公式 64 | for (auto &num : nums){ 65 | if(find(elements.begin(),elements.end(),num) != elements.end()) 66 | continue; 67 | elements.push_back(num); 68 | permute(nums, elements); 69 | elements.pop_back(); 70 | } 71 | } 72 | }; 73 | } 74 | 75 | #endif /* permutations_hpp */ 76 | -------------------------------------------------------------------------------- /tree/leetcode/easy/isSameTree.h: -------------------------------------------------------------------------------- 1 | // 2 | // isSameTree.h 3 | // tree 4 | // 5 | // Created by junlongj on 2019/8/15. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef isSameTree_hpp 10 | #define isSameTree_hpp 11 | 12 | #include 13 | #include "btree.h" 14 | #include 15 | /* 16 | 100.相同的树 17 | 给定两个二叉树,编写一个函数来检验它们是否相同。 18 | 19 | 如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。 20 | 21 | 示例 1: 22 | 23 | 输入: 1 1 24 | / \ / \ 25 | 2 3 2 3 26 | 27 | [1,2,3], [1,2,3] 28 | 29 | 输出: true 30 | 31 | 来源:力扣(LeetCode) 32 | 链接:https://leetcode-cn.com/problems/same-tree 33 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 34 | */ 35 | namespace leetcode { 36 | //先序遍历 37 | bool isSameTree(TreeNode* p, TreeNode* q) { 38 | if (p == nullptr && q == nullptr){ 39 | return true; 40 | } 41 | if (p == nullptr || q == nullptr){ 42 | return false; 43 | } 44 | return p->val==q->val && isSameTree(p->lchild,q->lchild) && isSameTree(p->rchild,q->rchild); 45 | } 46 | //层次遍历 47 | bool isSameTree2(TreeNode* p, TreeNode* q){ 48 | //层级遍历,先进先出 49 | std::queue q1,q2; 50 | q1.push(p); 51 | q2.push(q); 52 | while(!q1.empty() && !q2.empty()){ 53 | TreeNode *a1 = q1.front(); 54 | TreeNode *a2 = q2.front(); 55 | q1.pop(); 56 | q2.pop(); 57 | if (!a1 && !a2) 58 | continue; 59 | if (!a1 || !a2) 60 | return false; 61 | if (a1->val != a2->val) 62 | return false; 63 | q1.push(a1->lchild); 64 | q2.push(a2->lchild); 65 | 66 | q1.push(a1->rchild); 67 | q2.push(a2->rchild); 68 | } 69 | return true; 70 | } 71 | } 72 | #endif /* isSameTree_hpp */ 73 | -------------------------------------------------------------------------------- /linkedList/itinterviews/josephusKill.h: -------------------------------------------------------------------------------- 1 | // 2 | // josephusKill.h 3 | // linkedList 4 | // 5 | // Created by junl on 2019/11/4. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef josephusKill_hpp 10 | #define josephusKill_hpp 11 | 12 | #include 13 | #include "creatlist.h" 14 | /* 15 | 还原约瑟夫问题 16 | 输入:一个环形单向链表的头节点和报数的值n 17 | 返回:最后生存下来的节点,且这个节点自己组成环形单向链表,其他节点都删除. 18 | 19 | 20 | 进阶问题: 21 | 如果链表节点数为N,想要在时间复杂度为o(N)时完成原问题的求解,该怎么实现? 22 | */ 23 | //TODO: 进阶 24 | namespace itinterviews{ 25 | class josephusKill{ 26 | public: 27 | ListNode* solve(ListNode *head, int n){ 28 | if (!head || head->next == head || n < 1 ) 29 | return head; 30 | 31 | int ct = 0; 32 | ListNode *node = head; 33 | std::cout << "依次删除节点如下: "; 34 | int __step = 0; 35 | while (node && node->next != node) { 36 | ct++; 37 | __step++; 38 | if (ct == n - 1) { 39 | std::cout << node->next->val << ", "; 40 | node->next = node->next->next; 41 | ct = 0; 42 | } 43 | node = node->next; 44 | } 45 | std::cout << "最后剩下的: " << node->val << std::endl; 46 | std::cout << "一共走了 " << __step << "步" << std::endl; 47 | return node; 48 | } 49 | }; 50 | 51 | void test_josephusKill(){ 52 | ListNode *head = codinginterviews::creatLists({1,2,3,4,5})->next; 53 | ListNode *tail = head; 54 | while (tail->next) { 55 | tail = tail->next; 56 | } 57 | tail->next = head; 58 | std::cout << "-----test_josephusKill-------" << std::endl; 59 | class josephusKill so; 60 | head = so.solve(head, 3); 61 | 62 | } 63 | }; 64 | #endif /* josephusKill_hpp */ 65 | -------------------------------------------------------------------------------- /tiny_stl/test/forward_test.h: -------------------------------------------------------------------------------- 1 | // 2 | // forward_test.h 3 | // tiny_stl 4 | // 5 | // Created by junl on 2020/11/11. 6 | // Copyright © 2020 junl. All rights reserved. 7 | // 8 | 9 | #ifndef forward_test_h 10 | #define forward_test_h 11 | 12 | #include 13 | #include "test.h" 14 | 15 | namespace tiny{ 16 | namespace test{ 17 | namespace forward_test{ 18 | struct Test 19 | { 20 | public: 21 | int* m; 22 | Test(int i):m(new int(i)){std::cout << "Test()" << std::endl;} 23 | Test(const Test& t):m(new int(*t.m)) {std::cout << "Test(const Test&)" << std::endl;} 24 | Test(Test&& t):m(t.m) { 25 | t.m = nullptr; 26 | std::cout << "Test(Test&&)" << std::endl;} 27 | Test& operator=(Test&& t){ 28 | if (&t != this ){ 29 | m = t.m; 30 | t.m = nullptr; 31 | } 32 | std::cout << "Test(Test&&)" << std::endl; 33 | return *this; 34 | } 35 | ~Test(){std::cout << "~Test()" << std::endl;} 36 | }; 37 | 38 | TEST(forward_test){ 39 | #define TEST_IS_RVALUE(val) EXPECT_TRUE(std::is_rvalue_reference::value); 40 | int i = 0; 41 | int &&ri = i++;//i++为右值 42 | int &li = ++i; 43 | int *p = &i; 44 | int &lp = *p; 45 | int *&& rp = &i;//取地址表达式是个地址值,估&rp是纯右值 46 | 47 | int &&xi1 = std::move(i);//xil是个xvalue将亡右值 48 | int &&xi2 = static_cast(i);//xvalue 49 | auto&& fn = [](int x){return x * x;};//lambda是个右值 50 | 51 | Test t1(1), t2(2); 52 | swap(t1, t2); 53 | EXPECT_TRUE(*t1.m == 2); 54 | EXPECT_TRUE(*t2.m == 1); 55 | 56 | //test swap 57 | int arr1[] = {1,3,5,7}; 58 | int arr2[] = {2, 4, 6,8}; 59 | int arr3[] = {1,3,5,7}; 60 | int arr4[] = {2, 4, 6,8}; 61 | swap(arr1, arr2); 62 | EXPECT_PTR_RANGE_EQ(arr1, arr4, 4); 63 | EXPECT_PTR_RANGE_EQ(arr2, arr3, 4); 64 | } 65 | } 66 | 67 | } 68 | } 69 | 70 | #endif /* forward_test_h */ 71 | -------------------------------------------------------------------------------- /backtracking/leetcode/medium/combinationSum.h: -------------------------------------------------------------------------------- 1 | // 2 | // combinationSum.h 3 | // array 4 | // 5 | // Created by junlongj on 2019/8/28. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef combinationSum_hpp 10 | #define combinationSum_hpp 11 | 12 | #include 13 | #include 14 | /* 15 | 39. 组合总和 16 | 给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。 17 | 18 | candidates 中的数字可以无限制重复被选取。 19 | 20 | 说明: 21 | 22 | 所有数字(包括 target)都是正整数。 23 | 解集不能包含重复的组合。 24 | 示例 1: 25 | 26 | 输入: candidates = [2,3,6,7], target = 7, 27 | 所求解集为: 28 | [ 29 | [7], 30 | [2,2,3] 31 | ] 32 | 33 | 来源:力扣(LeetCode) 34 | 链接:https://leetcode-cn.com/problems/combination-sum 35 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 36 | */ 37 | namespace leetcode { 38 | /* 39 | 解题思路: 40 | 回溯枚举法.我们的目的是要在目标数组里面找N个数字和等于一个给定的数,那么我们可以利用枚举法,每次递归把candidates里面的每一个值拿来试试,如果不满足的话,那么拿下一个值再来试试。 41 | 42 | 为了保证不出现重复的集合,我们只从ctindex向后查找,这避免了重复集合的产生. 43 | 44 | */ 45 | using namespace std; 46 | vector> results; 47 | void _combinationSum(vector& candidates,vector elements, int target, int ctindex){ 48 | if (target == 0){ 49 | results.push_back(elements); 50 | return; 51 | } 52 | for (int i=ctindex;i= candidates[i]){ 54 | elements.push_back(candidates[i]); 55 | _combinationSum(candidates ,elements , target-candidates[i],i); 56 | elements.pop_back(); 57 | } 58 | } 59 | } 60 | vector> combinationSum(vector& candidates, int target) { 61 | if (candidates.empty()) return {}; 62 | vector elements; 63 | _combinationSum(candidates, elements, target, 0); 64 | return results; 65 | } 66 | } 67 | #endif /* combinationSum_hpp */ 68 | -------------------------------------------------------------------------------- /linkedList/leetcode/middleNode.h: -------------------------------------------------------------------------------- 1 | // 2 | // middleNode.h 3 | // linkedList 4 | // 5 | // Created by junlongj on 2019/7/18. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef middleNode_h 10 | #define middleNode_h 11 | #include "singlyLinkedList.h" 12 | 13 | namespace leetcode { 14 | /* 15 | 876.给定一个带有头结点 head 的非空单链表,返回链表的中间结点。 16 | 17 | 如果有两个中间结点,则返回第二个中间结点。 18 | 19 |   20 | 21 | 示例 1: 22 | 23 | 输入:[1,2,3,4,5] 24 | 输出:此列表中的结点 3 (序列化形式:[3,4,5]) 25 | 返回的结点值为 3 。 (测评系统对该结点序列化表述是 [3,4,5])。 26 | 注意,我们返回了一个 ListNode 类型的对象 ans,这样: 27 | ans.val = 3, ans.next.val = 4, ans.next.next.val = 5, 以及 ans.next.next.next = NULL. 28 | 示例 2: 29 | 30 | 输入:[1,2,3,4,5,6] 31 | 输出:此列表中的结点 4 (序列化形式:[4,5,6]) 32 | 由于该列表有两个中间结点,值分别为 3 和 4,我们返回第二个结点。 33 |   34 | 35 | 提示: 36 | 37 | 给定链表的结点数介于 1 和 100 之间。 38 | 在真实的面试中遇到过这道题? 39 | 40 | 来源:力扣(LeetCode) 41 | 链接:https://leetcode-cn.com/problems/middle-of-the-linked-list 42 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 43 | */ 44 | 45 | ListNode* middleNode(ListNode* head) { 46 | if (!head->next) { 47 | return head; 48 | } 49 | ListNode *fast,*slow; 50 | fast = slow = head; 51 | while (fast->next && fast->next->next) { 52 | fast = fast->next->next; 53 | slow = slow->next; 54 | } 55 | if (fast->next) { 56 | return slow->next; 57 | } 58 | return slow; 59 | } 60 | void test_middleNode(){ 61 | singlyLinkedList ll; 62 | ll.insertTail(1); 63 | ll.insertTail(2); 64 | ll.insertTail(3); 65 | ll.insertTail(4); 66 | ll.insertTail(5); 67 | std::cout << "test_middleNode: " << middleNode(ll.start())->val < 13 | #include "creatlist.h" 14 | /* 15 | 剑指Offer(五十六):删除链表中重复的结点 16 | 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5 17 | 18 | 19 | https://www.nowcoder.com/practice/fc533c45b73a41b0b44ccba763f866ef?tpId=13&tqId=11209&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking 20 | */ 21 | 22 | namespace codinginterviews { 23 | ListNode* deleteDuplication(ListNode* pHead){ 24 | if (!pHead) { 25 | return nullptr; 26 | } 27 | if (!pHead->next) { 28 | return pHead; 29 | } 30 | ListNode *head = new ListNode(-1); 31 | head->next = pHead; 32 | ListNode *last,*ct; 33 | last = head; 34 | ct = last->next; 35 | while (ct) { 36 | //每次遍历的时候,判断当前节点和下一个节点是否相等,如果相等的话,找到第一个不等的值. 37 | if (ct->next && ct->next->val == ct->val) { 38 | int val = ct->val; 39 | while (ct && ct->val == val) { 40 | ct=ct->next; 41 | } 42 | //删除重复节点 43 | last->next = ct; 44 | }else{ 45 | //前进一步 46 | last = ct; 47 | ct = ct->next; 48 | } 49 | } 50 | return head->next; 51 | } 52 | 53 | void test_deleteDuplication(){ 54 | std::cout << "test_deleteDuplication starting........" << std::endl; 55 | ListNode *root = creatLists({1,2,3,3,3,4,4,5})->next; 56 | root = deleteDuplication(root); 57 | root->print(); 58 | } 59 | } 60 | 61 | #endif /* deleteDuplication_hpp */ 62 | -------------------------------------------------------------------------------- /tiny_stl/test/allocator_test.h: -------------------------------------------------------------------------------- 1 | // 2 | // allocator_test.h 3 | // tiny_stl 4 | // 5 | // Created by junl on 2020/11/10. 6 | // Copyright © 2020 junl. All rights reserved. 7 | // 8 | 9 | #ifndef allocator_test_h 10 | #define allocator_test_h 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include "test.h" 17 | #include "allocator.h" 18 | #include "util.h" 19 | namespace tiny{ 20 | namespace test{ 21 | class Object{ 22 | public: 23 | Object(const int tag):tag(tag) {std::cout << "Object()" << std::endl;} 24 | ~Object(){std::cout << "~Object()" << std::endl;} 25 | private: 26 | int tag; 27 | }; 28 | int get(){ 29 | return 1; 30 | } 31 | void overloaded (const int& x) {std::cout << "[lvalue]";} 32 | void overloaded (int&& x) {std::cout << "[rvalue]";} 33 | 34 | // function template taking rvalue reference to deduced type: 35 | template void fn (T&& x) { 36 | overloaded (x); // always an lvalue 37 | overloaded (std::forward(x)); // rvalue if argument is rvalue 38 | } 39 | #define USE_CUSTOM_VERSION 40 | TEST(allocator){ 41 | typedef Object class_name; 42 | #ifdef USE_CUSTOM_VERSION 43 | allocator allocator; 44 | #else 45 | std::allocator allocator; 46 | #endif 47 | size_t n = 3; 48 | class_name *basePtr, *obj; 49 | basePtr = obj = allocator.allocate(n); 50 | for (size_t i =0; i < n; i++) { 51 | std::cout << allocator.address(*obj) << std::endl; 52 | allocator.construct(obj++, get()); 53 | } 54 | obj = basePtr; 55 | for (size_t i = 0; i < n; i++) { 56 | allocator.destroy(obj++); 57 | } 58 | allocator.deallocate(basePtr, n); 59 | 60 | 61 | } 62 | 63 | } 64 | } 65 | #endif /* allocator_test_h */ 66 | -------------------------------------------------------------------------------- /linkedList/coding-interviews/LastRemaining_Solution.h: -------------------------------------------------------------------------------- 1 | // 2 | // LastRemaining_Solution.h 3 | // linkedList 4 | // 5 | // Created by junl on 2020/1/13. 6 | // Copyright © 2020 junl. All rights reserved. 7 | // 8 | 9 | #ifndef LastRemaining_Solution_hpp 10 | #define LastRemaining_Solution_hpp 11 | 12 | #include 13 | namespace codinginterviews{ 14 | class Solution_LastRemaining { 15 | public: 16 | class Node{ 17 | public: 18 | int val; 19 | Node *next; 20 | Node(int v):val(v),next(nullptr){}; 21 | }; 22 | int LastRemaining_Solution(int n, int m) 23 | { 24 | if (n <= 0 || m <=0 || m >= n) 25 | return -1; 26 | Node *head = new Node(0); 27 | Node *node = head; 28 | Node *pre; 29 | for(int i=0;inext = new Node(i); 31 | node = node->next; 32 | } 33 | head = head->next; 34 | node->next = head; 35 | pre = node; 36 | node = head; 37 | int cnt =0; 38 | 39 | while(node->next != node){ 40 | if (cnt == m-1){ 41 | if (pre->next){ 42 | pre->next = pre->next->next; 43 | } 44 | cnt = 0; 45 | node = pre->next; 46 | }else{ 47 | pre = node; 48 | node = node->next; 49 | cnt++; 50 | } 51 | } 52 | return node->val; 53 | } 54 | }; 55 | 56 | void test_Solution_LastRemaining(){ 57 | std::cout << "-----LastRemaining_Solution-------" << std::endl; 58 | class Solution_LastRemaining so; 59 | std::cout << so.LastRemaining_Solution(5,3) << std::endl; 60 | } 61 | }; 62 | #endif /* LastRemaining_Solution_hpp */ 63 | -------------------------------------------------------------------------------- /linkedList/leetcode/removeNthFromEnd.h: -------------------------------------------------------------------------------- 1 | // 2 | // removeNthFromEnd.h 3 | // linkedList 4 | // 5 | // Created by junlongj on 2019/7/18. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef removeNthFromEnd_h 10 | #define removeNthFromEnd_h 11 | #include "singlyLinkedList.h" 12 | 13 | namespace leetcode { 14 | /* 15 | 19.给定一个链表,删除链表的倒数第 n 个节点,并且返回链表的头结点。 16 | 17 | 示例: 18 | 19 | 给定一个链表: 1->2->3->4->5, 和 n = 2. 20 | 21 | 当删除了倒数第二个节点后,链表变为 1->2->3->5. 22 | 说明: 23 | 24 | 给定的 n 保证是有效的。 25 | 26 | 进阶: 27 | 28 | 你能尝试使用一趟扫描实现吗? 29 | 30 | 在真实的面试中遇到过这道题? 31 | 32 | 来源:力扣(LeetCode) 33 | 链接:https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list 34 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 35 | */ 36 | ListNode* removeNthFromEnd(ListNode* head, int n) { 37 | 38 | if (head == nullptr || n <=0){ 39 | return nullptr; 40 | } 41 | //技巧,通过构建哨兵对象,可以极大的降低复杂度。 42 | ListNode *node = new ListNode(0); 43 | node->next = head; 44 | head = node; 45 | 46 | ListNode *p1, *p2; 47 | p1=p2=head; 48 | for(int i=0; inext; 51 | } 52 | while (p2->next!=nullptr){ 53 | p2=p2->next; 54 | p1=p1->next; 55 | } 56 | 57 | p1->next = p1->next->next; 58 | return head->next; 59 | } 60 | void test_removeNthFromEnd(){ 61 | singlyLinkedList ll; 62 | ll.insertTail(1); 63 | ll.insertTail(2); 64 | // ll.insertTail(3); 65 | // ll.insertTail(4); 66 | // ll.insertTail(5); 67 | // ll.insertTail(6); 68 | std::cout << "test_removeNthFromEnd: " <print(); 70 | } 71 | } 72 | 73 | #endif /* removeNthFromEnd_h */ 74 | -------------------------------------------------------------------------------- /bsearch/bsearch.h: -------------------------------------------------------------------------------- 1 | // 2 | // bsearch.h 3 | // bsearch 4 | // 5 | // Created by junl on 2019/7/19. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef bsearch_hpp 10 | #define bsearch_hpp 11 | 12 | #include 13 | 14 | /* 15 | 二分查找又叫折半查找,每次都通过跟区间的中位数作比较,将待查找的区间缩小为之前的一半,直到找到要查找的元素。二分查找是一种十分高效的查找方式,时间复杂度为o(log(n)).这种查找速度是很恐怖的,试想一下在区间0-2^32的范围内查找一个数,最多需要32次比较就能找到。 16 | 17 | 二分查找的局限性: 18 | 19 | 1. 只适用于数组,因为需要数组的随机访问能力 20 | 2. 二分查找针对的是有序数据。如果是静态数据呢,我们可以一次排序,N次查找,来均摊排序所花费的时间。但是如果是动态数据的话,即中途还有可能会向数组插入/删除元素的话,那么就不适用于二分了,因为每次改变都需要重新排序。 21 | 3. 数据量太小不适合用二分查找,比如10次以内的循环,其实直接顺序遍历时间也差不多。但是如果涉及到元素比较比较耗时(比如长字符串直接的比较),那么比较次数越少越好。 22 | 4. 数据量太大也不适用于二分查找。因为二分需要依靠数组,而数组是无法存储大数据的。 23 | 24 | 25 | 下面的几个变种问题,关键点在于:***********如果在已经满足条件的情况下,进一步的去锁定当前是不是第一个或者最后一个元素.********* 26 | 27 | 28 | 二分查找的变种问题写起来是比较费脑的,我们需要注意终止条件,区间上下界更新,返回值选择。二分查找更适合处理一些“近似查找”问题上,比如练习里面的: 29 | 30 | 1. 查找第一个等于定值的元素. 31 | 2. 查找最后一个值等于给定值的元素. 32 | 3. 查找第一个大于等于指定元素的值. 33 | 4. 查找最后一个小于等于给定值的元素. 34 | 35 | 而仅仅是查找某个具体的值,我们也可以使用散列表或二叉查找树来实现。 36 | */ 37 | int bsearch_f1(int nums[], int n,int target){ 38 | int left = 0; 39 | int right = n-1; 40 | while (left<=right) { 41 | int mid = left + (right - left)/2; 42 | if (nums[mid] == target) { 43 | return mid; 44 | }else if (nums[mid] < target){ 45 | left = mid+1; 46 | }else{ 47 | right = mid-1; 48 | } 49 | } 50 | return -1; 51 | } 52 | 53 | 54 | int bsearch_f2(int nums[], int n,int left, int right, int target){ 55 | if (left>right) { 56 | return -1; 57 | } 58 | 59 | int mid = left + (right - left)/2; 60 | if (nums[mid] == target) { 61 | return mid; 62 | }else if (nums[mid] < target){ 63 | return bsearch_f2(nums, n, mid+1, right, target); 64 | }else{ 65 | return bsearch_f2(nums, n, left, mid-1, target); 66 | } 67 | } 68 | #endif /* bsearch_hpp */ 69 | -------------------------------------------------------------------------------- /bsearch/main.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // main.cpp 3 | // bsearch 4 | // 5 | // Created by junl on 2019/7/19. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #include 10 | #include "bsearch.h" 11 | #include "bsearch_findFirstElement.h" 12 | #include "bsearch_findLastElement.h" 13 | #include "searchInRotatedSortedArray.h" 14 | #include "bsearch_findFirstElementGreaterOrEqual.h" 15 | #include "bsearch_findLastElementLessOrEqual.h" 16 | #include "isPerfectSquare.h" 17 | #include "mySqrt.h" 18 | #include "searchRange.h" 19 | #include "powx.h" 20 | #include "search_a_2d_matrix.h" 21 | #include "searchInRotatedSortedArrayII.h" 22 | #include "find_minimum_in_rotated_sorted_array.h" 23 | #include 24 | int main(int argc, const char * argv[]) { 25 | // insert code here... 26 | std::cout << "bsearch starting...............\n"; 27 | int nums[] ={1, 4, 5, 9, 12, 19, 21, 28, 31, 36}; 28 | std::cout << bsearch_f1(nums, 10, 12) << std::endl; 29 | std::cout << bsearch_f2(nums, 10, 0, 9,12) << std::endl; 30 | int nums2[] = {1,3,4,5,6,8,8,8,11,18}; 31 | std::cout << "bsearch_findFirstElement...............\n"; 32 | std::cout << bsearch_findFirstElement(nums2, 10, 8) << std::endl;//5 33 | std::cout << bsearch_findLastElement(nums2, 10, 8) << std::endl;//7 34 | std::cout << bsearch_findLastElement(nums2, 10, 9) << std::endl;//-1 35 | std::cout << bsearch_findFirstElementGreaterOrEqual(nums2, 10, 7) << std::endl;//5 36 | std::cout << bsearch_findLastElementLessOrEqual(nums2, 10, 7) << std::endl;//4 37 | 38 | 39 | std::cout << "search in rotate array...............\n"; 40 | 41 | std::vector a{4,5,6,7,0,1,2}; 42 | std::vector a2{3,1}; 43 | std::cout << search(a, 1) << std::endl; 44 | 45 | std::cout << "isPerfectSquare...............\n"; 46 | std::cout << isPerfectSquare(16) << std::endl; 47 | std::cout << mySqrt(6) << std::endl; 48 | 49 | leetcode::test_pow(); 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /string/coding-interviews/StrToInt.h: -------------------------------------------------------------------------------- 1 | // 2 | // StrToInt.h 3 | // string 4 | // 5 | // Created by junlongj on 2019/8/4. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef StrToInt_hpp 10 | #define StrToInt_hpp 11 | 12 | #include 13 | #include 14 | 15 | /* 16 | 剑指Offer(四十九):把字符串转换成整数 17 | 18 | 将一个字符串转换成一个整数(实现Integer.valueOf(string)的功能,但是string不符合数字要求时返回0),要求不能使用字符串转换整数的库函数。 数值为0或者字符串不是一个合法的数值则返回0。 19 | 输入描述: 20 | 输入一个字符串,包括数字字母符号,可以为空 21 | 输出描述: 22 | 如果是合法的数值表达则返回该数字,否则返回0 23 | https://www.nowcoder.com/practice/1277c681251b4372bdef344468e4f26e?tpId=13&tqId=11202&tPage=3&rp=1&ru=%2Fta%2Fcoding-interviews&qru=%2Fta%2Fcoding-interviews%2Fquestion-ranking 24 | 25 | */ 26 | 27 | namespace codinginterviews { 28 | int StrToInt(std::string &str) { 29 | if (str.empty()) { 30 | return 0; 31 | } 32 | bool negative = false; 33 | std::string vaildStr; 34 | for (int i=0; i= '0' && str[i] <= '9') { 36 | vaildStr += str[i]; 37 | }else{ 38 | if (i == 0 && str[i] == '+') { 39 | negative = false; 40 | }else if (i == 0 && str[i] == '-'){ 41 | negative = true; 42 | }else{ 43 | return 0; 44 | } 45 | } 46 | } 47 | if (vaildStr.empty()) { 48 | return 0; 49 | } 50 | long long num=0; 51 | for (int i=0; i 13 | /* 14 | 硬币找零问题。比如我们现在有硬币1元,3元,5元,我们需要支付w元,那么最少需要多少个硬币. 15 | 思路: 16 | 1. 贪心法,每次首先尝试最大面值的币种 17 | */ 18 | class coinChange { 19 | public: 20 | //贪心法,首先尝试最大面值的币种 21 | void solve(const int coins[], int n, int money, int currentCoinCount){ 22 | if (money == 0 || currentCoinCount == n) { 23 | result = std::min(result, currentCoinCount); 24 | return; 25 | } 26 | for (int i=n-1; i>=0; i--) { 27 | if (money >= coins[i]) { 28 | solve(coins, n, money - coins[i], currentCoinCount+1); 29 | } 30 | } 31 | 32 | } 33 | int solve(const int coins[], int n, int money){ 34 | solve(coins, n, money, 0); 35 | return result; 36 | } 37 | private: 38 | int result = INT_MAX; 39 | }; 40 | 41 | int min(int x, int y){ return x < y ? x : y;} 42 | int coinChange(int* coins, int coinsSize, int amount){ 43 | if (coins == NULL || coinsSize <= 0) return 0; 44 | int st[amount+1]; 45 | memset(st, 0, sizeof(st)); 46 | 47 | for(int i = 1; i <= amount; i++){ 48 | int m_coin = INT_MAX; 49 | for(int j=0; j < coinsSize; j++){ 50 | if (i >= coins[j] && st[i-coins[j]]!= -1){ 51 | m_coin = min(m_coin, st[i-coins[j]] + 1); 52 | } 53 | } 54 | st[i] = m_coin == INT_MAX ? -1 : m_coin; 55 | } 56 | return st[amount]; 57 | } 58 | 59 | 60 | 61 | 62 | 63 | void test_coinChange(){ 64 | std::cout << "------------硬币找零问题----------" << std::endl; 65 | class coinChange so; 66 | int coins[] = {1,3,5}; 67 | std::cout << so.solve(coins, 3, 9) << std::endl; 68 | std::cout << coinChange(coins, 3, 9) << std::endl; 69 | } 70 | 71 | 72 | #endif /* coinChange_hpp */ 73 | -------------------------------------------------------------------------------- /other/leetcode/medium/next_permutation.h: -------------------------------------------------------------------------------- 1 | // 2 | // next_permutation.h 3 | // other 4 | // 5 | // Created by junlongj on 2019/8/26. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef next_permutation_hpp 10 | #define next_permutation_hpp 11 | 12 | #include 13 | #include 14 | /* 15 | 31.下一个排列 16 | 实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。 17 | 18 | 如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。 19 | 20 | 必须原地修改,只允许使用额外常数空间。 21 | 22 | 以下是一些例子,输入位于左侧列,其相应输出位于右侧列。 23 | 1,2,3 → 1,3,2 24 | 3,2,1 → 1,2,3 25 | 1,1,5 → 1,5,1 26 | 27 | 28 | 29 | 来源:力扣(LeetCode) 30 | 链接:https://leetcode-cn.com/problems/next-permutation 31 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 32 | */ 33 | 34 | namespace leetcode { 35 | void reverse(std::vector& nums,int left ,int right){ 36 | while (left < right){ 37 | std::swap(nums[left++],nums[right--]); 38 | } 39 | } 40 | void nextPermutation(std::vector& nums) { 41 | //什么情况下会存在比当前更大一点的序列? 42 | /* 43 | 当nums[i-1] < nums[i]的话,肯定会存在一个比当前更大一点的序列.我们是从最右边遍历过来的,所以nums[i....n]这些数字是按照降序的方式排列的。我们从最右边开始寻找第一个比nums[i-1]大的数,交换它们的值。 44 | 交换之后,最右边仍然是降序排列的。它不是比当前更大的最小的,需要将它翻转。 45 | */ 46 | int size = nums.size(); 47 | if (size <= 1) return ; 48 | int i=size-1; 49 | while (i >= 1 && nums[i-1] >= nums[i]){ 50 | i--; 51 | } 52 | //nums[i-1] < nums[i] 53 | if (i == 0){ 54 | //说明当前是最大的序列,需要翻转0...n 55 | reverse(nums,0, size-1); 56 | }else{ 57 | int j = size-1; 58 | while (j >= i){ 59 | if (nums[j] > nums[i-1]){ 60 | std::swap(nums[j],nums[i-1]); 61 | break; 62 | }else{ 63 | j--; 64 | } 65 | } 66 | //需要翻转i...n的序列 67 | reverse(nums, i, size-1); 68 | } 69 | } 70 | } 71 | #endif /* next_permutation_hpp */ 72 | -------------------------------------------------------------------------------- /other/coding-interviews/GetUglyNumber_Solution.h: -------------------------------------------------------------------------------- 1 | // 2 | // GetUglyNumber_Solution.h 3 | // other 4 | // 5 | // Created by junl on 2019/8/5. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef GetUglyNumber_Solution_hpp 10 | #define GetUglyNumber_Solution_hpp 11 | 12 | #include 13 | /* 14 | 剑指Offer(三十三):丑数 15 | 把只包含质因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含质因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。 16 | https://www.nowcoder.com/practice/6aa9e04fc3794f68acf8778237ba065b?tpId=13&tqId=11186&tPage=2&rp=1&ru=%2Fta%2Fcoding-interviews&qru=%2Fta%2Fcoding-interviews%2Fquestion-ranking 17 | */ 18 | 19 | namespace codinginterviews { 20 | int GetUglyNumber_Solution(int index) { 21 | /* 22 | 丑数 = 另一个丑数 * (2/3/5), 所以我们需要构建一个排序的丑数数组,然后依次把之前丑数列表某个丑数来乘以2/3/5,取最小的一个. 23 | */ 24 | if (index <=0) return 0; 25 | int uglys[index]; 26 | memset(uglys, 0, sizeof(uglys)); 27 | uglys[0]=1; 28 | int index2 = 0; 29 | int index3 = 0; 30 | int index5 = 0; 31 | int i = 1; 32 | while (i < index) { 33 | int new_ugly2 = uglys[index2] * 2; 34 | int new_ugly3 = uglys[index3] * 3; 35 | int new_ugly5 = uglys[index5] * 5; 36 | int min = std::min(new_ugly5, std::min(new_ugly2, new_ugly3)); 37 | uglys[i++] = min; 38 | 39 | if (min == new_ugly2) { //因为之前的丑数*2已经被放进排序数组里了,所以需要新增下标,这样下次将会比较新值. 40 | index2++; 41 | } 42 | if (min == new_ugly3){ 43 | index3++; 44 | } 45 | if (min == new_ugly5){ 46 | index5++; 47 | } 48 | } 49 | return uglys[index-1]; 50 | } 51 | 52 | void test_GetUglyNumber_Solution(){ 53 | std::cout << "GetUglyNumber_Solution starting......." << std::endl; 54 | std::cout << GetUglyNumber_Solution(10) << std::endl; 55 | } 56 | } 57 | #endif /* GetUglyNumber_Solution_hpp */ 58 | -------------------------------------------------------------------------------- /other/coding-interviews/IsContinuous.h: -------------------------------------------------------------------------------- 1 | // 2 | // IsContinuous.h 3 | // other 4 | // 5 | // Created by junl on 2019/8/5. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef IsContinuous_hpp 10 | #define IsContinuous_hpp 11 | 12 | #include 13 | #include 14 | /* 15 | 剑指Offer(四十五):扑克牌顺子 16 | LL今天心情特别好,因为他去买了一副扑克牌,发现里面居然有2个大王,2个小王(一副牌原本是54张^_^)...他随机从中抽出了5张牌,想测测自己的手气,看看能不能抽到顺子,如果抽到的话,他决定去买体育彩票,嘿嘿!!“红心A,黑桃3,小王,大王,方片5”,“Oh My God!”不是顺子.....LL不高兴了,他想了想,决定大\小 王可以看成任何数字,并且A看作1,J为11,Q为12,K为13。上面的5张牌就可以变成“1,2,3,4,5”(大小王分别看作2和4),“So Lucky!”。LL决定去买体育彩票啦。 现在,要求你使用这幅牌模拟上面的过程,然后告诉我们LL的运气如何, 如果牌能组成顺子就输出true,否则就输出false。为了方便起见,你可以认为大小王是0。 17 | 18 | https://www.nowcoder.com/practice/762836f4d43d43ca9deb273b3de8e1f4?tpId=13&tqId=11198&tPage=3&rp=1&ru=%2Fta%2Fcoding-interviews&qru=%2Fta%2Fcoding-interviews%2Fquestion-ranking 19 | */ 20 | 21 | namespace codinginterviews { 22 | bool IsContinuous( std::vector numbers ) { 23 | std::sort(numbers.begin(), numbers.end()); 24 | int zerocount = 0; 25 | int lastnumber= -1; 26 | for (int i=0; i a{1,0,0,1,0}; 49 | std::cout << "test_IsContinuous starting......." < 13 | #include 14 | #include 15 | /* 16 | 剑指Offer(三十一):整数中1出现的次数(从1到n整数中1出现的次数) 17 | 求出1~13的整数中1出现的次数,并算出100~1300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1、10、11、12、13因此共出现6次,但是对于后面问题他就没辙了。ACMer希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中1出现的次数(从1 到 n 中1出现的次数)。 18 | https://www.nowcoder.com/practice/bd7f978302044eee894445e244c7eee6?tpId=13&tqId=11184&tPage=2&rp=1&ru=%2Fta%2Fcoding-interviews&qru=%2Fta%2Fcoding-interviews%2Fquestion-ranking 19 | */ 20 | 21 | namespace codinginterviews { 22 | int NumberOfStr(const char *str); 23 | int countDigitOne(int n){ 24 | if (n <= 0) return 0; 25 | 26 | char s[BUFSIZ]; 27 | sprintf(s, "%d", n); 28 | return NumberOfStr(s); 29 | } 30 | 31 | int NumberOfStr(const char *str){ 32 | //21345 33 | if (str == NULL || *str < '0' || *str > '9'|| *str == '\0') 34 | return 0; 35 | 36 | int highPosition = str[0] - '0'; 37 | size_t len = strlen(str); 38 | if (len == 1 && highPosition == 0) 39 | return 0; 40 | if (len == 1 && highPosition > 0){ 41 | return 1; 42 | } 43 | int highNumber, tailNumber, numRecursive; 44 | if (highPosition == 1){ 45 | highNumber = atoi(str+1) + 1; 46 | }else if(highPosition > 1){ 47 | highNumber = pow(10, len-1); 48 | }else{ 49 | highNumber = 0; 50 | } 51 | tailNumber = highPosition * (len - 1) * pow(10, len-2); 52 | numRecursive = NumberOfStr(str+1); 53 | return highNumber + tailNumber + numRecursive; 54 | } 55 | 56 | void test_countDigitOne(){ 57 | int n = 20000; 58 | printf("test_countDigitOne: %d\n",countDigitOne(n)); 59 | } 60 | } 61 | #endif /* NumberOf1Between1AndN_Solution_hpp */ 62 | -------------------------------------------------------------------------------- /other/leetcode/easy/romanToInt.h: -------------------------------------------------------------------------------- 1 | // 2 | // romanToInt.h 3 | // other 4 | // 5 | // Created by junlongj on 2019/8/12. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef romanToInt_hpp 10 | #define romanToInt_hpp 11 | 12 | #include 13 | #include 14 | #include 15 | /* 16 | 13. 罗马数字转整数 17 | 罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。 18 | 19 | 字符 数值 20 | I 1 21 | V 5 22 | X 10 23 | L 50 24 | C 100 25 | D 500 26 | M 1000 27 | 例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。 27 写做  XXVII, 即为 XX + V + II 。 28 | 29 | 通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况: 30 | 31 | I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。 32 | X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。 33 | C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。 34 | 35 | 来源:力扣(LeetCode) 36 | 链接:https://leetcode-cn.com/problems/roman-to-integer 37 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 38 | */ 39 | 40 | namespace leetcode { 41 | int romanToInt(std::string s) { 42 | if (s.empty()) return 0; 43 | std::map mm; 44 | mm['I'] = 1; 45 | mm['V'] = 5; 46 | mm['X'] = 10; 47 | mm['L'] = 50; 48 | mm['C'] = 100; 49 | mm['D'] = 500; 50 | mm['M'] = 1000; 51 | int i=0; 52 | char lastc=-1; 53 | int result=0; 54 | while(i 13 | #include 14 | #include "reverseStack.h" 15 | /* 16 | 用一个栈实现另一个栈的排序 17 | 18 | 一个栈中元素的类型为整形,现在想将该栈从顶到底c按照从大到小的顺序排序,只允许借助另一个栈,除此之外可以申请临时变量,但不能借助额外的数据结构。如何完成排序? 19 | */ 20 | 21 | 22 | class sortStackByStack { 23 | public: 24 | /* 25 | 思路: 26 | 首先构建一个临时栈,我们按照从大到小的顺序依次将原始数据放进temp_stk去,然后再将temp_stk依次pop进stk,即是答案. 27 | 28 | 那么如果保证temp_stk是有序的呢? 29 | 比如我们要向temp_stk插入newValue,比如当前栈顶元素比newValue小的话,那么将栈顶元素出栈然后重新压入源栈。 30 | 否则的话,直接将newValue压入temp_stk. 31 | */ 32 | void solve(std::stack &stk){ 33 | std::stack temp_stk; 34 | if (stk.empty()) { 35 | return; 36 | } 37 | 38 | while (!stk.empty()) { 39 | int newValue = stk.top(); 40 | stk.pop(); 41 | 42 | if (temp_stk.empty()) { 43 | temp_stk.push(newValue); 44 | }else{ 45 | while (!temp_stk.empty() && temp_stk.top() < newValue) { 46 | stk.push(temp_stk.top()); 47 | temp_stk.pop(); 48 | } 49 | temp_stk.push(newValue); 50 | } 51 | } 52 | 53 | while (!temp_stk.empty()) { 54 | stk.push(temp_stk.top()); 55 | temp_stk.pop(); 56 | } 57 | } 58 | }; 59 | 60 | 61 | void test_sortStackByStack(){ 62 | std::stack stk({5,4,8,7}); 63 | class sortStackByStack so; 64 | std::cout << "------test_test_sortStackByStack---------" << std::endl; 65 | std::cout << "原始数据为:"; 66 | printStack(stk); 67 | so.solve(stk); 68 | std::cout << "排序后数据为:"; 69 | printStack(stk); 70 | } 71 | 72 | 73 | #endif /* sortStackByStack_hpp */ 74 | -------------------------------------------------------------------------------- /base/base.h: -------------------------------------------------------------------------------- 1 | // 2 | // base.hpp 3 | // base 4 | // 5 | // Created by junl on 2019/7/17. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef base_ 10 | #define base_ 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | /* The classes below are exported */ 17 | #pragma GCC visibility push(default) 18 | //#pragma GCC visibility push(hidden) 19 | template 20 | //利用stringstream进行安全的类型转换 21 | void to_string( std::string &result, const T& t){ 22 | std::stringstream stream; 23 | stream << t; 24 | result = stream.str(); 25 | } 26 | template 27 | out_type convert(const in_value & t){ 28 | std::stringstream stream; 29 | stream<>result;//向result中写入值 32 | return result; 33 | } 34 | 35 | /// 创建二位数组 36 | template 37 | void make2Array(T**& a,int row,int column) { 38 | a = new T* [row];//申请行 39 | for (int i=0; i 45 | void delete2Array(T**& a,int row,int column) { 46 | for (int i = 0; i 54 | void changeLength2Array(T**& a ,int oldrow,int oldcolumn,int row,int column) { 55 | T** newArray; 56 | make2Array(newArray, row, column); 57 | int minrow = std::min(oldrow, row); 58 | int mincolumn = std::min(oldcolumn, column); 59 | for (int i=0; i 68 | void makearray(T*& a,int oldlen, int len) { 69 | T* arr = new T [len]; 70 | std::copy(a, a+std::min(oldlen, len), arr); 71 | a = arr; 72 | } 73 | 74 | #pragma GCC visibility pop 75 | #endif 76 | -------------------------------------------------------------------------------- /recursion/leetcode/medium/longestUnivaluePath.h: -------------------------------------------------------------------------------- 1 | // 2 | // longestUnivaluePath.h 3 | // recursion 4 | // 5 | // Created by junlongj on 2019/8/30. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef longestUnivaluePath_hpp 10 | #define longestUnivaluePath_hpp 11 | 12 | #include 13 | #include "btree.h" 14 | /* 15 | 687.687. 最长同值路径 16 | 给定一个二叉树,找到最长的路径,这个路径中的每个节点具有相同值。 这条路径可以经过也可以不经过根节点。 17 | 18 | 注意:两个节点之间的路径长度由它们之间的边数表示。 19 | 20 | 示例 1: 21 | 22 | 输入: 23 | 24 | 5 25 | / \ 26 | 4 5 27 | / \ \ 28 | 1 1 5 29 | 输出: 30 | 31 | 2 32 | 33 | 来源:力扣(LeetCode) 34 | 链接:https://leetcode-cn.com/problems/longest-univalue-path 35 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 36 | */ 37 | 38 | namespace leetcode { 39 | int maxPath = 0; 40 | /* 41 | 思路: 42 | 43 | 最长路径之和等于:左子树到跟的最长值 + 右子树到跟的最长值 44 | 那左子树自己的最长值又如何求呢?r左子树自身也是由它的左子树和右子树构成的,这样递归就形成了。 45 | 46 | 定义问题: 47 | 1.怎样获取一个节点的最长单边路径(左子树到跟的最长值 或者 右子树到跟的最长值) 48 | 2.最长路径 = 两边的最长单边路径之和 49 | 50 | maxUnivaluePath(root)表示节点(左或者)到root根节点的最长距离,比如图中: 51 | 最左叶子节点到根节点:1->4->5 = 0 52 | 最右叶子节点到根节点:5->5->5 = 2 53 | maxUnivaluePath(root) = 最长左边的距离+最长右边的距离 54 | */ 55 | int maxUnivaluePath(TreeNode *root){ 56 | if (!root) 57 | return 0; 58 | int leftPath = maxUnivaluePath(root->lchild); 59 | int rightPath = maxUnivaluePath(root->rchild); 60 | if (root->lchild && root->lchild->val == root->val){ 61 | leftPath++; 62 | }else{ 63 | leftPath = 0; 64 | } 65 | if (root->rchild && root->rchild->val == root->val){ 66 | rightPath++; 67 | }else{ 68 | rightPath=0; 69 | } 70 | maxPath = max(maxPath, leftPath + rightPath); 71 | return max(leftPath,rightPath); 72 | } 73 | int longestUnivaluePath(TreeNode* root) { 74 | maxUnivaluePath(root); 75 | return maxPath; 76 | } 77 | 78 | } 79 | #endif /* longestUnivaluePath_hpp */ 80 | -------------------------------------------------------------------------------- /tree/coding-interviews/GetNext.h: -------------------------------------------------------------------------------- 1 | // 2 | // GetNext.h 3 | // tree 4 | // 5 | // Created by junlongj on 2019/8/3. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef GetNext_hpp 10 | #define GetNext_hpp 11 | 12 | #include 13 | 14 | /* 15 | 剑指Offer(五十七):二叉树的下一个结点 16 | 17 | 给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。 18 | https://www.nowcoder.com/practice/9023a0c988684a53960365b889ceaf5e?tpId=13&tqId=11210&tPage=3&rp=2&ru=%2Fta%2Fcoding-interviews&qru=%2Fta%2Fcoding-interviews%2Fquestion-ranking 19 | */ 20 | namespace codinginterviews { 21 | struct TreeLinkNode { 22 | int val; 23 | struct TreeLinkNode *left; 24 | struct TreeLinkNode *right; 25 | struct TreeLinkNode *next; 26 | TreeLinkNode(int x) :val(x), left(NULL), right(NULL), next(NULL) { 27 | 28 | } 29 | }; 30 | TreeLinkNode* GetNext(TreeLinkNode* pNode) 31 | { 32 | if (pNode == nullptr) { 33 | return nullptr; 34 | } 35 | //如果当前节点存在右子树,那么结果是右子树的最左那个节点 36 | if (pNode->right != nullptr) { 37 | TreeLinkNode *ct = pNode->right; 38 | while (ct && ct->left) { 39 | ct = ct->left; 40 | } 41 | return ct; 42 | }else if (pNode->next != nullptr){ 43 | //如果当前节点没有右子树,那么就要分几种情况了. 44 | //如果当前节点是其父节点的左节点的话,那么下一个就为其父节点。 45 | //如果当前节点是其父节点的右字节的话,需要找到整个左子树的根节点。 46 | if (pNode->next->left == pNode) { 47 | return pNode->next; 48 | }else{ 49 | TreeLinkNode *ct = pNode->next; 50 | //一直找到它的父节点是左节点的情况 51 | while (ct->next && ct->next->left != ct) { 52 | ct = ct->next; 53 | } 54 | if (ct) { 55 | return ct->next; 56 | } 57 | return nullptr; 58 | } 59 | } 60 | return nullptr; 61 | } 62 | } 63 | #endif /* GetNext_hpp */ 64 | -------------------------------------------------------------------------------- /array/leetcode/easy/maxSubArray.h: -------------------------------------------------------------------------------- 1 | // 2 | // maxSubArray.h 3 | // array 4 | // 5 | // Created by junlongj on 2019/8/7. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef maxSubArray_hpp 10 | #define maxSubArray_hpp 11 | 12 | #include 13 | #include 14 | /* 15 | 给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。 16 | 17 | 示例: 18 | 19 | 输入: [-2,1,-3,4,-1,2,1,-5,4], 20 | 输出: 6 21 | 解释: 连续子数组 [4,-1,2,1] 的和最大,为 6。 22 | 23 | 来源:力扣(LeetCode) 24 | 链接:https://leetcode-cn.com/problems/maximum-subarray 25 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 26 | */ 27 | 28 | namespace leetcode { 29 | #pragma mark - o(2n) 30 | /* 31 | 思路: DP[0......i] dp[i]里面存储的是,之前元素到i的连续数组的最大值。 32 | 这样我们可以通过dp[i-1]推导出dp[i]的状态. 33 | 如果 dp[i-1] > 0, dp[i] = dp[i-1] + nums[i]; 34 | 否则 : dp[i] = nums[i]; 35 | */ 36 | int maxSubArray(std::vector& nums) { 37 | if (nums.empty()) return 0; 38 | int dp[nums.size()];//dp里面存储的是到数组i位置以前,最大的子序列和. 39 | dp[0]=nums[0]; 40 | for (int i=1;i 0){ 42 | dp[i] = dp[i-1] + nums[i]; 43 | }else{ 44 | dp[i] = nums[i]; 45 | } 46 | } 47 | //这样dp数组里面存储的都是到当前下标(包括下标)位置之前的最大值.求最大值. 48 | int max = dp[0]; 49 | for (int i=0;i& nums) { 57 | if (nums.empty()) return 0; 58 | int dp[nums.size()];//dp里面存储的是到数组i位置以前,最大的子序列和. 59 | dp[0]=nums[0]; 60 | int max = dp[0]; 61 | for (int i=1;i 0){ 63 | dp[i] = dp[i-1] + nums[i]; 64 | }else{ 65 | dp[i] = nums[i]; 66 | } 67 | max = std::max(max,dp[i]); 68 | } 69 | return max; 70 | } 71 | } 72 | #endif /* maxSubArray_hpp */ 73 | -------------------------------------------------------------------------------- /array/coding-interviews/minNumberInRotateArray.h: -------------------------------------------------------------------------------- 1 | // 2 | // minNumberInRotateArray.h 3 | // array 4 | // 5 | // Created by junlongj on 2019/8/3. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef minNumberInRotateArray_hpp 10 | #define minNumberInRotateArray_hpp 11 | 12 | #include 13 | #include 14 | /* 15 | 剑指Offer(六):旋转数组的最小数字 16 | 17 | 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素。 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转,该数组的最小值为1。 NOTE:给出的所有元素都大于0,若数组大小为0,请返回0。 18 | 19 | https://www.nowcoder.com/practice/9f3231a991af4f55b95579b44b7a01ba?tpId=13&tqId=11159&tPage=1&rp=1&ru=%2Fta%2Fcoding-interviews&qru=%2Fta%2Fcoding-interviews%2Fquestion-ranking 20 | */ 21 | 22 | 23 | namespace codinginterviews { 24 | int minNumberInRotateArray(std::vector rotateArray) { 25 | if (rotateArray.size() == 0) { 26 | return 0; 27 | } 28 | int start=0; 29 | int end = rotateArray.size()-1; 30 | while (start <= end) { 31 | int mid = start + (end-start)/2; 32 | // if (mid == rotateArray.size() - 1) { 33 | // return std::min(rotateArray[mid], rotateArray[start]); 34 | // } 35 | // if (mid == 0) { 36 | // return std::min(rotateArray[mid], rotateArray[end]); 37 | // } 38 | if (rotateArray[mid] < rotateArray[mid-1]) { 39 | return rotateArray[mid]; 40 | } 41 | //注意这里的判断条件,正常排序数组,应该中间节点小于为尾节点的值 42 | if (rotateArray[mid] > rotateArray[end]) { 43 | start=mid+1; 44 | }else 45 | { 46 | end=mid-1; 47 | } 48 | } 49 | return -1; 50 | } 51 | 52 | void test_minNumberInRotateArray(){ 53 | std::vector v{1,2,4,5,0}; 54 | std::cout << "test_minNumberInRotateArray starting......" << std::endl; 55 | std::cout << minNumberInRotateArray(v) << std::endl; 56 | } 57 | } 58 | #endif /* minNumberInRotateArray_hpp */ 59 | -------------------------------------------------------------------------------- /array/leetcode/easy/best_time_to_buy_and_sell_stock_ii.h: -------------------------------------------------------------------------------- 1 | // 2 | // best_time_to_buy_and_sell_stock_ii.h 3 | // array 4 | // 5 | // Created by junlongj on 2019/8/9. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef best_time_to_buy_and_sell_stock_ii_hpp 10 | #define best_time_to_buy_and_sell_stock_ii_hpp 11 | 12 | #include 13 | #include 14 | /* 15 | 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。 16 | 17 | 设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。 18 | 19 | 注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。 20 | 21 | 示例 1: 22 | 23 | 输入: [7,1,5,3,6,4] 24 | 输出: 7 25 | 解释: 在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。 26 |   随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6-3 = 3 。 27 | 28 | 来源:力扣(LeetCode) 29 | 链接:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii 30 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 31 | */ 32 | 33 | namespace leetcode { 34 | int maxProfit_II(std::vector& prices) { 35 | //思路:寻找波峰后的上升区间,然后全部加起来,这样是最赚钱的。 36 | int low=-1; 37 | int max=0; 38 | for(int i=0;i+1prices[i+1] && low >= 0){ 44 | max+=(prices[i]-prices[low]); 45 | low=-1; 46 | } 47 | } 48 | if (low>=0){ 49 | max+=(prices[prices.size()-1]-prices[low]); 50 | } 51 | return max; 52 | } 53 | /* 54 | 思路:分析上面那张找波峰和波谷的方法,我们可以知道,其实只要prices[i+1]>prices[i],那么每一截相加的值其实就等于波峰减去波谷。 55 | */ 56 | int maxProfit_III(std::vector& prices) { 57 | if (prices.empty()) return 0; 58 | int max=0; 59 | for(int i=0;iprices[i]){ 61 | max+=prices[i+1]-prices[i]; 62 | } 63 | } 64 | return max; 65 | } 66 | } 67 | #endif /* best_time_to_buy_and_sell_stock_ii_hpp */ 68 | -------------------------------------------------------------------------------- /string/leetcode/easy/romanToInt.h: -------------------------------------------------------------------------------- 1 | // 2 | // romanToInt.h 3 | // string 4 | // 5 | // Created by junlongj on 2019/8/14. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef romanToInt_hpp 10 | #define romanToInt_hpp 11 | 12 | #include 13 | #include 14 | #include 15 | /* 16 | 13. 罗马数字转整数 17 | 罗马数字包含以下七种字符: I, V, X, L,C,D 和 M。 18 | 19 | 字符 数值 20 | I 1 21 | V 5 22 | X 10 23 | L 50 24 | C 100 25 | D 500 26 | M 1000 27 | 例如, 罗马数字 2 写做 II ,即为两个并列的 1。12 写做 XII ,即为 X + II 。 27 写做  XXVII, 即为 XX + V + II 。 28 | 29 | 通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况: 30 | 31 | I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。 32 | X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。 33 | C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。 34 | 给定一个罗马数字,将其转换成整数。输入确保在 1 到 3999 的范围内。 35 | 36 | 来源:力扣(LeetCode) 37 | 链接:https://leetcode-cn.com/problems/roman-to-integer 38 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 39 | */ 40 | namespace leetcode { 41 | int romanToInt(std::string s) { 42 | if (s.empty()) return 0; 43 | std::map mm; 44 | mm['I'] = 1; 45 | mm['V'] = 5; 46 | mm['X'] = 10; 47 | mm['L'] = 50; 48 | mm['C'] = 100; 49 | mm['D'] = 500; 50 | mm['M'] = 1000; 51 | int i=0; 52 | char lastc=-1; 53 | int result=0; 54 | while(i 13 | /* 14 | 剑指Offer(五十二):正则表达式匹配 15 | 16 | 请实现一个函数用来匹配包括'.'和'*'的正则表达式。模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但是与"aa.a"和"ab*a"均不匹配 17 | 18 | https://www.nowcoder.com/practice/45327ae22b7b413ea21df13ee7d6429c?tpId=13&tqId=11205&tPage=3&rp=1&ru=%2Fta%2Fcoding-interviews&qru=%2Fta%2Fcoding-interviews%2Fquestion-ranking 19 | */ 20 | 21 | namespace codinginterviews { 22 | #pragma mark - 有bug 23 | bool match(char* str, char* pattern) 24 | { 25 | int i=0;//指向sstr 26 | int j=0;//指向pattern 27 | char lastc = -1; 28 | while (pattern[j] != '\0' && str[i] != '\0') { 29 | char p = pattern[j]; 30 | char s = str[i]; 31 | if (p == '.') { 32 | j++;i++; 33 | }else if (p == '*'){ 34 | if (j == 0) { 35 | return false; 36 | } 37 | while (str[i] == lastc && str[i+1]!= pattern[j+1]) { 38 | i++; 39 | } 40 | j++; 41 | }else{ 42 | if (p == s) { 43 | i++; 44 | j++; 45 | }else{ 46 | if (pattern[j+1] != '*') { 47 | return false; 48 | } 49 | j++; 50 | } 51 | } 52 | 53 | lastc = p; 54 | } 55 | return str[i] == '\0' && pattern[j] == '\0'; 56 | } 57 | 58 | void test_match(){ 59 | 60 | char *s1 = "ab*ac*a"; 61 | char *s2 = "aaa"; 62 | std::cout << "match starting........." << std::endl; 63 | std::cout << match(s2, s1) << std::endl; 64 | } 65 | } 66 | #endif /* match_hpp */ 67 | -------------------------------------------------------------------------------- /array/leetcode/medium/3sum.h: -------------------------------------------------------------------------------- 1 | // 2 | // 3sum.h 3 | // array 4 | // 5 | // Created by junlongj on 2019/8/19. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef _sum_hpp 10 | #define _sum_hpp 11 | 12 | #include 13 | #include 14 | /* 15 | 15.三数之和 16 | 给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。 17 | 18 | 注意:答案中不可以包含重复的三元组。 19 | 20 | 例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4], 21 | 22 | 满足要求的三元组集合为: 23 | [ 24 | [-1, 0, 1], 25 | [-1, -1, 2] 26 | ] 27 | 28 | 29 | 来源:力扣(LeetCode) 30 | 链接:https://leetcode-cn.com/problems/3sum 31 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 32 | */ 33 | 34 | namespace leetcode { 35 | /* 36 | 思路: 将三数问题降维到二数问题 37 | 先将数组排好序, 比如: 38 | -1,0,1,2,-1,-4, 39 | 排完序就是-4,-1,-1,0,1,2 40 | 41 | 双层循环,外层固定第一个数,然后通过数组的有序性,将后两数之和和固定的数进行比较来挪动位置. 42 | 43 | 这题提交了几次,关键在于异常情况没考虑到位,比如下面代码1.处。 44 | */ 45 | std::vector> threeSum(std::vector& nums) { 46 | int size = nums.size(); 47 | if (size < 3) 48 | return {}; 49 | std::vector> results; 50 | std::sort(nums.begin(),nums.end()); 51 | for (int i=0;i= 1 && a == nums[i-1]) 54 | continue; 55 | for (int j=i+1,k =size-1;j < k ;){ 56 | int b = nums[j]; 57 | int c = nums[k]; 58 | if (b + c == -a){ 59 | results.push_back({a,b,c}); 60 | //注意后面需要过滤掉重复的数字 1. 61 | while (j < k && nums[j] == b) 62 | j++; 63 | while (j < k && nums[k] == c) 64 | k--; 65 | }else if (b + c > -a){ 66 | k--; 67 | }else{ 68 | j++; 69 | } 70 | } 71 | } 72 | return results; 73 | } 74 | } 75 | #endif /* _sum_hpp */ 76 | -------------------------------------------------------------------------------- /other/coding-interviews/FindNumbersWithSum.h: -------------------------------------------------------------------------------- 1 | // 2 | // FindNumbersWithSum.h 3 | // other 4 | // 5 | // Created by junl on 2019/8/5. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef FindNumbersWithSum_hpp 10 | #define FindNumbersWithSum_hpp 11 | 12 | #include 13 | #include 14 | /* 15 | 剑指Offer(四十二):和为S的两个数字 16 | 题目描述 17 | 输入一个递增排序的数组和一个数字S,在数组中查找两个数,使得他们的和正好是S,如果有多对数字的和等于S,输出两个数的乘积最小的。 18 | 输出描述: 19 | 对应每个测试案例,输出两个数,小的先输出。 20 | 21 | https://www.nowcoder.com/practice/390da4f7a00f44bea7c2f3d19491311b?tpId=13&tqId=11195&tPage=3&rp=1&ru=%2Fta%2Fcoding-interviews&qru=%2Fta%2Fcoding-interviews%2Fquestion-ranking 22 | */ 23 | 24 | namespace codinginterviews { 25 | std::vector FindNumbersWithSum(std::vector array,int sum) { 26 | if (array.empty()) return {}; 27 | int i=0; 28 | int j=array.size()-1; 29 | std::vector result; 30 | while (i < j) { 31 | int ctv = array[i] + array[j]; 32 | if (ctv == sum) { 33 | if (result.empty()) { 34 | result.push_back(array[i]); 35 | result.push_back(array[j]); 36 | }else{ 37 | if (array[i] * array[j] < result[0] * result[1]) { 38 | result[0] = array[i]; 39 | result[1] = array[j]; 40 | } 41 | } 42 | i++; 43 | j--; 44 | }else if(ctv < sum){ 45 | i++; 46 | }else{ 47 | j--; 48 | } 49 | } 50 | return result; 51 | } 52 | 53 | void test_FindNumbersWithSum(){ 54 | std::cout << "FindNumbersWithSum starting........" << std::endl; 55 | std::vector a{1,2,3,4,5,7,8}; 56 | std::vector result = FindNumbersWithSum(a, 7); 57 | if (!result.empty()) { 58 | std::cout << result[0] << ", " << result[1] << std::endl; 59 | } 60 | } 61 | } 62 | #endif /* FindNumbersWithSum_hpp */ 63 | -------------------------------------------------------------------------------- /backtracking/eightQueens.h: -------------------------------------------------------------------------------- 1 | // 2 | // eightQueens.h 3 | // backtracking 4 | // 5 | // Created by junl on 2019/7/25. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef eightQueens_hpp 10 | #define eightQueens_hpp 11 | 12 | #include 13 | #include 14 | /* 15 | 8皇后问题,8*8的棋盘,希望放8个旗子,要求是每个旗子所在的行,列,对角线都不能有另一个旗子. 16 | 17 | Q,*,*,*,*,*,*,*, 18 | *,*,*,*,Q,*,*,*, 19 | *,*,*,*,*,*,*,Q, 20 | *,*,*,*,*,Q,*,*, 21 | *,*,Q,*,*,*,*,*, 22 | *,*,*,*,*,*,Q,*, 23 | *,Q,*,*,*,*,*,*, 24 | *,*,*,Q,*,*,*,*, 25 | 26 | */ 27 | 28 | void backtrack(int *nums, int n, int level); 29 | void printQueues(int *nums, int n); 30 | bool isOk(int *nums, int row, int col, int n); 31 | void eightQueue(int n){ 32 | int nums[n]; 33 | memset(nums, 0, sizeof(nums)); 34 | 35 | backtrack(nums, n, 0); 36 | }; 37 | 38 | void backtrack(int *nums, int n, int level){ 39 | if (level == n){ 40 | //print queues 41 | printQueues(nums, n); 42 | return; 43 | }; 44 | 45 | for(int i=0; i < n;i++){ 46 | if (isOk(nums, level, i, n)){ 47 | nums[level] = i; 48 | backtrack(nums, n, level+1); 49 | nums[level] = 0; 50 | } 51 | } 52 | } 53 | bool isOk(int *nums, int row, int col, int n){ 54 | int leftup = col - 1; 55 | int rightup = col + 1; 56 | for (int i = row-1; i>=0; i--) { 57 | if (nums[i] == col) return false; 58 | if (leftup>=0 && nums[i] == leftup) return false; 59 | if (rightup <= n-1 && nums[i] == rightup) return false; 60 | 61 | leftup--;rightup++; 62 | } 63 | return true; 64 | } 65 | 66 | void printQueues(int *nums, int n){ 67 | for(int i=0; i < n; i++){ 68 | for(int j = 0; j < n; j++){ 69 | if (nums[i] == j) { 70 | printf("1 "); 71 | }else{ 72 | printf("0 "); 73 | } 74 | } 75 | printf("\n"); 76 | } 77 | printf("-----------------\n"); 78 | printf("-----------------\n"); 79 | } 80 | #endif /* eightQueens_hpp */ 81 | -------------------------------------------------------------------------------- /backtracking/leetcode/medium/subsets_ii.h: -------------------------------------------------------------------------------- 1 | // 2 | // subsets_ii.h 3 | // backtracking 4 | // 5 | // Created by junl on 2019/9/26. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef subsets_ii_hpp 10 | #define subsets_ii_hpp 11 | 12 | #include 13 | /* 14 | 90.子集II 15 | 给定一个可能包含重复元素的整数数组 nums,返回该数组所有可能的子集(幂集)。 16 | 17 | 说明:解集不能包含重复的子集。 18 | 19 | 示例: 20 | 21 | 输入: [1,2,2] 22 | 输出: 23 | [ 24 | [2], 25 | [1], 26 | [1,2,2], 27 | [2,2], 28 | [1,2], 29 | [] 30 | ] 31 | 32 | 来源:力扣(LeetCode) 33 | 链接:https://leetcode-cn.com/problems/subsets-ii 34 | 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 35 | */ 36 | namespace leetcode { 37 | class Solution90{ 38 | public: 39 | vector> subsetsWithDup(vector& nums) { 40 | //如果前一个选中的话,后一个不选. 41 | if (nums.empty()) return {}; 42 | //先排个序方便过滤重复数字 43 | sort(nums.begin(), nums.end()); 44 | vector> results; 45 | vector st; 46 | vector elements; 47 | st.resize(nums.size()); 48 | subsetsWithDup(nums, results,0,st,elements); 49 | return results; 50 | 51 | } 52 | 53 | void subsetsWithDup(vector& nums, vector>& results, int index, vector st,vector elements){ 54 | 55 | if (index == nums.size()){ 56 | results.push_back(elements); 57 | return; 58 | } 59 | subsetsWithDup(nums, results,index+1,st,elements); 60 | //过滤掉重复的值,比如【1,2,2】的序列,之前第2轮已经选择了2的话,那么第三轮可以继续选择2,或者不选择.那么就可以得到[1,2,2]或者[1,2]. 如果之前没有选择2的话,那么第三轮不能在选择2,得到[1] 61 | if(index>0 && nums[index-1] == nums[index] && !st[index-1]) 62 | return; 63 | 64 | elements.push_back(nums[index]); 65 | st[index]=true; 66 | subsetsWithDup(nums, results,index+1,st,elements); 67 | elements.pop_back(); 68 | st[index]=false; 69 | } 70 | }; 71 | } 72 | #endif /* subsets_ii_hpp */ 73 | -------------------------------------------------------------------------------- /string/matching.h: -------------------------------------------------------------------------------- 1 | // 2 | // matching.h 3 | // string 4 | // 5 | // Created by junlongj on 2019/7/22. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef matching_h 10 | #define matching_h 11 | 12 | #include 13 | #include 14 | /* 15 | 字符串匹配算法: 16 | 17 | BF算法:Brute Force的缩写,暴力匹配算法。思想很简单: 18 | 在主串里,从起始位置分别是0,1,2....n-m且长度为m的n-m+1个子串,分别和substr自己字符匹配.这种算法在实际场景中比较常用,主要原因有二: 19 | 1. 实际场景中,模式串和主串不会太长,并且只要中途没匹配到就会停止,所以比理想o(n*m)要高很多. 20 | 2. 匹配算法思想简单,代码实现也非常简单。满足Keep is Simple and Stupid原则。 21 | 22 | */ 23 | size_t BF_matching(std::string &str, std::string &substr){ 24 | size_t len = str.size(); 25 | size_t len2 = substr.size(); 26 | if (len == 0 || len2 == 0 || len < len2){ 27 | return -1; 28 | } 29 | 30 | for (int i=0; i 13 | 14 | /* 15 | 堆的概念: 16 | 1. 它是完全二叉树,所有可以用数组来存储 17 | 2. 分为大顶堆和小顶堆;大顶堆中每个节点的值都大于等于子树所有节点的值. 18 | 堆的主要操作: 19 | 1.插入一个元素 20 | 2.删除堆顶元素 21 | ***因为堆是完全二叉树,所有为了保护完全二叉树的结构(完全二叉树值得是除了叶子节点,其他节点都是满的),我们都是操作数组末尾元素,然后将整个堆进行堆化.**** 22 | 23 | */ 24 | 25 | 26 | class heap{ 27 | public: 28 | void insert(int val){ 29 | if (count >= capacity) { 30 | return; 31 | } 32 | count++; 33 | elements[count] = val; 34 | //堆结构化 35 | int i=count; 36 | //如果父节点小于当前节点,交换 37 | while (i/2 > 0 && elements[i/2] < elements[i]) { 38 | std::swap(elements[i/2], elements[i]); 39 | i = i/2; 40 | } 41 | } 42 | void removemax(){ 43 | if (count == 0) 44 | return; 45 | //先将末尾节点移到堆头部,然后删除尾结点 46 | elements[1] = elements[count]; 47 | count--; 48 | 49 | //堆结构化 50 | int i=1; 51 | while (2*i+1<=count) { 52 | int maxindex = i; 53 | if (elements[2*i] > elements[2*i+1]) { 54 | maxindex = 2*i; 55 | }else if (elements[2*i] < elements[2*i+1]){ 56 | maxindex = 2*i+1; 57 | } 58 | if (maxindex != i) { 59 | std::swap(elements[i], elements[maxindex]); 60 | i = maxindex; 61 | }else{ 62 | break; 63 | } 64 | } 65 | } 66 | heap(int capacity_=10){ 67 | capacity = capacity_; 68 | count = 0; 69 | elements = new int[capacity_]; 70 | } 71 | ~heap(){ 72 | delete [] elements; 73 | } 74 | void print(){ 75 | for(int i=1;i<=count;i++){ 76 | printf("%i ,",elements[i]); 77 | } 78 | putchar('\n'); 79 | } 80 | protected: 81 | int capacity; 82 | int *elements; 83 | int count; 84 | }; 85 | 86 | 87 | #endif /* heap_hpp */ 88 | -------------------------------------------------------------------------------- /tree/coding-interviews/HasSubtree.h: -------------------------------------------------------------------------------- 1 | // 2 | // HasSubtree.h 3 | // tree 4 | // 5 | // Created by junl on 2019/8/2. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef HasSubtree_hpp 10 | #define HasSubtree_hpp 11 | 12 | #include 13 | /* 14 | 剑指Offer(十七):树的子结构 15 | 16 | 输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构) 17 | https://www.nowcoder.com/practice/6e196c44c7004d15b1610b9afca8bd88?tpId=13&tqId=11170&tPage=1&rp=1&ru=%2Fta%2Fcoding-interviews&qru=%2Fta%2Fcoding-interviews%2Fquestion-ranking 18 | */ 19 | 20 | namespace codinginterviews { 21 | /* 22 | 分析:三种情况: 23 | 1. 当前A和B val一样,需要dfs判断它们的左右子树是不是一样的. 24 | 2. 当前A和B val不一样,判断A的左子树是否包含B 25 | 3. 当前A和B val不一样,判断A的右子树是否包含B 26 | */ 27 | bool dfs(TreeNode* A, TreeNode* B); 28 | bool isSubStructure(TreeNode* A, TreeNode* B){ 29 | if (A == NULL || B == NULL) return false; 30 | 31 | return dfs(A, B) || isSubStructure(A->lchild, B) || isSubStructure(A->rchild, B); 32 | } 33 | 34 | bool dfs(TreeNode* A, TreeNode* B){ 35 | if (B == NULL) return true; 36 | if (A == NULL) return false; 37 | if (A->val != B->val) return false; 38 | return dfs(A->lchild, B->lchild) && dfs(A->rchild, B->rchild); 39 | } 40 | 41 | void test_HasSubtree(){ 42 | TreeNode *node4 = new TreeNode(4); 43 | TreeNode *node2 = new TreeNode(2); 44 | TreeNode *node7 = new TreeNode(7); 45 | TreeNode *node1 = new TreeNode(1); 46 | TreeNode *node3 = new TreeNode(3); 47 | TreeNode *node6 = new TreeNode(6); 48 | TreeNode *node9 = new TreeNode(9); 49 | node4->lchild = node2; 50 | node4->rchild = node7; 51 | node2->lchild = node1; 52 | node2->rchild = node3; 53 | node7->lchild = node6; 54 | node7->rchild = node9; 55 | node6->lchild = new TreeNode(8); 56 | 57 | 58 | TreeNode *pRoot2 = createnode(6); 59 | pRoot2->lchild = createnode(8); 60 | 61 | std::cout << "test_HasSubtree starting........." << std::endl; 62 | std::cout << isSubStructure(node4, pRoot2) << std::endl; 63 | } 64 | } 65 | #endif /* HasSubtree_hpp */ 66 | -------------------------------------------------------------------------------- /array/DSArray.h: -------------------------------------------------------------------------------- 1 | // 2 | // DSArray.hpp 3 | // ALG-DS 4 | // 5 | // Created by junl on 2019/4/22. 6 | // Copyright © 2019 junl. All rights reserved. 7 | // 8 | 9 | #ifndef DSArray_hpp 10 | #define DSArray_hpp 11 | #include 12 | #include "DSIterator.h" 13 | #include "linearList.h" 14 | void testDSArray(); 15 | 16 | // 实现数组 17 | template 18 | class arrayList : public linearList { 19 | protected: 20 | T *elements; //储存结构 21 | int arrayLength;//数组长度 22 | int capacity;//数组容量 23 | void checkIndex(int index) const; 24 | void resize(int size); 25 | public: 26 | arrayList(int capacity = 2); 27 | arrayList(const arrayList& ); 28 | //ADT 29 | bool empty() const { 30 | return arrayLength == 0; 31 | }; 32 | int size() const { 33 | return arrayLength; 34 | }; 35 | T& get(int index) ; 36 | int indexOf(const T& element) const; 37 | void earse(int index); 38 | void push_back(const T& element); 39 | void insert(int index, const T& element); 40 | /// 使数组的长度arrayLength等于capacity 41 | void trimToSize(); 42 | /// 使线性表的长度=size 43 | void setSize(int size); 44 | void swap(arrayList& other); 45 | /// 把数组容量修改为capacity 46 | void reserve(int capacity); 47 | /// 修改下标元素 48 | T& set(int index,const T& element); 49 | /// 清空数组 50 | void clear(); 51 | void removeRange(int start ,int end); 52 | /// 返回指定元素出现的最后一个索引 53 | int lastIndexOf(const T& element); 54 | ~arrayList(); 55 | void output() const; 56 | //返回迭代器,自定义迭代器以后,DSArray就能够使用STL里面的标准算法了. 57 | DSIterator begin(){ 58 | return DSIterator(elements); 59 | }; 60 | DSIterator end(){ 61 | return DSIterator(elements+arrayLength); 62 | } 63 | //下标 64 | T& operator[](int index); 65 | //当且仅当所有元素相等时,才为真 66 | bool operator==(const arrayList& other); 67 | bool operator!=(const arrayList& other); 68 | bool operator<(const arrayList& other); 69 | friend std::ostream& operator<< (std::ostream &out, arrayList& array); 70 | }; 71 | 72 | template 73 | std::ostream& operator<< (std::ostream &out, arrayList& array); 74 | 75 | #endif /* DSArray_hpp */ 76 | --------------------------------------------------------------------------------