├── .github └── workflows │ ├── go.yml │ └── maven.yml ├── .gitignore ├── 000、什么是数据结构,都有哪些数据结构.md ├── 002、二进制的运算.md ├── 003、运算符(java例子).md ├── 009、理解时间复杂度 O(log n).md ├── 00、Hash算法总结.md ├── 00、基础知识 ├── 01、基础 │ ├── 01、递归 Recursion.md │ ├── 02、递归的执行过程.md │ └── 03、LFU、LRU、TinyLFU 、W-TinyLFU.md ├── 02、排序算法 │ ├── 02、冒泡排序.md │ ├── 03、鸡尾酒排序.md │ ├── 04、直接选择排序.md │ ├── 05、希尔排序.md │ ├── 06、直接插入排序.md │ ├── 07、快速排序.md │ ├── 08、归并排序.md │ ├── 10、堆排序.md │ └── 50、对两个数组进行merge 排序.md └── 05、动态规划 │ ├── 03、Kadane算法.md │ ├── 07、动态规划.md │ ├── 08、动态规划总结.md │ └── 09、DP(动态规划) VS 回溯 VS 贪心.md ├── 010.算法梳理:初级篇.md ├── 011.算法梳理:中级篇.md ├── 012.算法梳理:高级篇.md ├── 01、数据结构 ├── 01、数据结构概述.md ├── 02、数据结构.md ├── 10、二叉树遍历(先序、中序、后序).md └── 13、广度优先和深度优先搜索.md ├── 020、递归执行过程详解.md ├── 02、算法复杂度 └── 02、Master Theorem-主定理与时间复杂度.md ├── 03、散列表的工作原理.md ├── 03、树 ├── 00、树列表.md ├── 01、二叉查找树.md ├── 01、二叉树.md ├── 02、二分搜索.md ├── 03、01. 平衡树.md ├── 03、02.为什么费尽苦心保证树的平衡性.md ├── 04、AVL树.md ├── 04、为什么STL和linux都使用红黑树作为平衡树的实现?.md ├── 04、从Trie树(字典树)谈到后缀树.md ├── 05、为什么这样设计红黑树.md ├── 05、红黑树.md ├── 06、 红黑树-维基百科.md ├── 07、红黑树深入剖析及Java实现.md ├── 08、漫画:什么是红黑树?.md ├── 11、AVL树与红黑树区别.md ├── 31、B+树介绍.md ├── 32、B树和B+树的插入、删除图文详解.md └── 33、什么是B树?.md ├── 04、图 └── 10、图的两种存储方式-邻接矩阵和邻接表.md ├── 05、链表 ├── 03、反转一个单链表&判断链表是否有环.md └── 05、一个链表,求中间结点.md ├── 11、leetcode ├── 104、104. Maximum Depth of Binary Tree.md ├── 111、111. Minimum Depth of Binary Tree.md ├── 11、盛水最大的容器.md ├── 121. Best Time to Buy and Sell Stock.md ├── 122. Best Time to Buy and Sell Stock II.md ├── 167、167. Two Sum II - Input array is sorted.md ├── 169、169. Majority Element.md ├── 184、184.LeetCode:Department Highest Salary - 部门内最高工资.md ├── 202、202. Happy Number.md ├── 21、21. Merge Two Sorted Lists.md ├── 233. Number of Digit One.md ├── 235、235. Lowest Common Ancestor of a Binary Search Tree.md ├── 239、239. Sliding Window Maximum.md ├── 241、242. Valid Anagram.md ├── 35、35. Search Insert Position.md ├── 387、387. First Unique Character in a String(从一个字符串中找出第一个不重复字符).md ├── 38、38.Count and Say (计数和发言) 解题思路和方法.md ├── 50、50. Pow(x, n).md ├── 53、53. Maximum Subarray.md ├── 670、670. Maximum Swap.md ├── 69. Sqrt(x).md ├── 703. Kth Largest Element in a Stream.md ├── 83、83. Remove Duplicates from Sorted List.md ├── 88、88. Merge Sorted Array.md ├── 98、98. Validate Binary Search Tree.md └── README.md ├── 15、搞定BAT面试——几道常见的子符串算法题.md ├── 20、几个面试经典算法题Java解答 ├── 01、几个面试经典算法题Java解答.md └── 02、用队列实现栈&用栈实现队列.md ├── 21、海量数据处理 ├── 04、海量数据处理 - 10亿个数中找出最大的10000个数(top K问题).md └── 05、一个1TB的文件,你有什么最快的办法能够求出重复次数最多的TOP5行数据?.md ├── 30、其他算法 └── 03、Base64编码原理与应用.md ├── README.md ├── algorithm.md ├── algorithms-go-example ├── BubbleSortDemo.go ├── go.mod ├── leetcode │ ├── 1_TwoSum.go │ ├── 225_Implement_Stack_using_Queues.go │ └── go.mod └── test │ ├── 1_TwoSum_test.go │ ├── 225_Implement_Stack_using_Queues_test.go │ └── go.mod ├── algorithms-java-example ├── pom.xml ├── production │ └── algorithms │ │ └── java │ │ └── space.mamba │ │ └── leetcode │ │ └── database │ │ └── Duplicate_Emails.sql └── src │ ├── main │ └── java │ │ ├── space.mamba │ │ ├── basis │ │ │ ├── IntegerExample.java │ │ │ ├── LRUCache.java │ │ │ ├── LRUCache_LinkedList_HashMap.java │ │ │ ├── LRU_Example01.java │ │ │ ├── LinearTableDemo.java │ │ │ ├── LinkedListDemo.java │ │ │ ├── MergeListSortExample.java │ │ │ ├── Node.java │ │ │ ├── dynamic_programing │ │ │ │ └── FibExample01.java │ │ │ ├── hash │ │ │ │ └── HashDemo.java │ │ │ └── space │ │ │ │ └── mamba │ │ │ │ └── basis │ │ │ │ └── Demo001.java │ │ ├── binarytree │ │ │ └── Demo.java │ │ ├── coding │ │ │ └── interviews │ │ │ │ ├── AssignmentOperatorFunctionDemo01.java │ │ │ │ ├── BinaryTreeNode.java │ │ │ │ ├── BitCountExample01.java │ │ │ │ ├── DeleteWhitespace.java │ │ │ │ ├── FibonacciSolutionExample01.java │ │ │ │ ├── ListNode.java │ │ │ │ ├── MaxNumExample01.java │ │ │ │ ├── MinNumberInRotateArray.java │ │ │ │ ├── No11_DoublePower.java │ │ │ │ ├── No12_Print1ToMaxOfNDigitsSimple.java │ │ │ │ ├── No12_PrintToMaxOfDigitsSimpke2.java │ │ │ │ ├── No13_DeleteNode.java │ │ │ │ ├── No14_GetLeastNumbersSolutionExample01.java │ │ │ │ ├── No14_GetLeastNumbersSolutionExample02_quickSort.java │ │ │ │ ├── No14_ReorderOddEven.java │ │ │ │ ├── No15_FindList_Last_K_Node.java │ │ │ │ ├── No16_ReverseList.java │ │ │ │ ├── No17_MergeSortListNode.java │ │ │ │ ├── No18_HasSubTree.java │ │ │ │ ├── No19_ClockwisePrintingMatrix.java │ │ │ │ ├── No21_StackMin.java │ │ │ │ ├── No22_IsPopOrder.java │ │ │ │ ├── No23_PrintTreeFromTopToBottom.java │ │ │ │ ├── No23_printTreeInLine.java │ │ │ │ ├── No25_FindBinaryTreePath.java │ │ │ │ ├── No30_KLeastNumbers.java │ │ │ │ ├── No31_FindGreatestSumOfSubArray.java │ │ │ │ ├── No32_CountNumber.java │ │ │ │ ├── No33_ArrayConvertSmallestNumber.java │ │ │ │ ├── No34_UglyNumber.java │ │ │ │ ├── No35_FirstFindOnceChar.java │ │ │ │ ├── No36_InversePairsCore.java │ │ │ │ ├── No37_IntersectionNode.java │ │ │ │ ├── No38_GetSortArrayNumCount.java │ │ │ │ ├── No39_DepthInBTree.java │ │ │ │ ├── No40_FindNumsAppearOnce.java │ │ │ │ ├── No41_FindContinuousSequences.java │ │ │ │ ├── No42_ReverseSentence.java │ │ │ │ ├── No45_LastRemaining.java │ │ │ │ ├── No46_SumSolution.java │ │ │ │ ├── No47_Add.java │ │ │ │ ├── No48_FinallClass.java │ │ │ │ ├── No49_StringToInteger.java │ │ │ │ ├── No51_DuplicateNum.java │ │ │ │ ├── No52_Multiply.java │ │ │ │ ├── No53_Pattern.java │ │ │ │ ├── No54_isNumber.java │ │ │ │ ├── No56_DetectCycle.java │ │ │ │ ├── No58GetNextBinaryTree.java │ │ │ │ ├── No60PrintBinaryTree.java │ │ │ │ ├── No61PrintBinaryTree_1.java │ │ │ │ ├── No61PrintBinaryTree_2.java │ │ │ │ ├── No62_SerializeBinaryTree.java │ │ │ │ ├── No63BinarySearchTreeKNode.java │ │ │ │ ├── No7QueueWithTwoStacks.java │ │ │ │ ├── No8_RevertArray.java │ │ │ │ ├── P44_FindInPartiallySortedMatrix.java │ │ │ │ ├── P58_PrintListInReversedOrder.java │ │ │ │ ├── RotateSmallestNumberOfArrays.java │ │ │ │ ├── SingletonDemo02.java │ │ │ │ ├── TopNDemo.java │ │ │ │ └── TreeNode.java │ │ ├── interview │ │ │ ├── ArrayFindSum.java │ │ │ └── ClockwiseOutput.java │ │ ├── leetcode │ │ │ ├── TwoSum.java │ │ │ ├── algorithms │ │ │ │ ├── No07_ReverseInteger.java │ │ │ │ ├── No100_Same_Tree.java │ │ │ │ ├── No104_Maximum_Depth_of_Binary_Tree.java │ │ │ │ ├── No1108_DefangingIPAddress.java │ │ │ │ ├── No111_Minimum_Depth_of_Binary_Tree.java │ │ │ │ ├── No118_Pascal_s_Triangle.java │ │ │ │ ├── No119_Pascal_s_Triangle_I_I.java │ │ │ │ ├── No11MaxArea.java │ │ │ │ ├── No121_Best_Time_to_Buy_and_Sell_Stock.java │ │ │ │ ├── No122_Best_Time_to_Buy_and_Sell_Stock_2.java │ │ │ │ ├── No136_SingleNumber.java │ │ │ │ ├── No141_Linked_List_Cycle.java │ │ │ │ ├── No155_MinStack.java │ │ │ │ ├── No167_Two_Sum_II_Input_array_is_sorted.java │ │ │ │ ├── No169_Majority_Element.java │ │ │ │ ├── No202_Happy_Number.java │ │ │ │ ├── No20Valid_Parentheses_Array.java │ │ │ │ ├── No20Valid_Parentheses_Stack.java │ │ │ │ ├── No21_Merge_Two_Sorted_Lists.java │ │ │ │ ├── No225_Implement_Stack_using_Queues.java │ │ │ │ ├── No22_Generate_Parentheses.java │ │ │ │ ├── No235_Lowest_Common_Ancestor_of_a_Binary_Search_Tree.java │ │ │ │ ├── No239_Sliding_Window_Maximum.java │ │ │ │ ├── No35_SearchInsert.java │ │ │ │ ├── No387_First_Unique_Character_In_a_String.java │ │ │ │ ├── No38_CountAndSay.java │ │ │ │ ├── No50_Pow.java │ │ │ │ ├── No53_maxSubArray.java │ │ │ │ ├── No670_Maximum_Swap.java │ │ │ │ ├── No69_Sqrt.java │ │ │ │ ├── No703_KthLargest.java │ │ │ │ ├── No71_Simplify_Path.java │ │ │ │ ├── No82_Remove_Duplicates_from_Sorted_List_II.java │ │ │ │ ├── No88_Merge_Sorted_Array.java │ │ │ │ ├── No98_Validate_Binary_Search_Tree.java │ │ │ │ ├── No_169MajorityElement.java │ │ │ │ ├── No_232_Implement_Queue_using_Stacks.java │ │ │ │ ├── No_242ValidAnagram.java │ │ │ │ ├── No_83_Remove_Duplicates_from_Sorted_List.java │ │ │ │ └── TreeNode.java │ │ │ └── database │ │ │ │ └── Duplicate_Emails.sql │ │ ├── logic_operation │ │ │ ├── BitwiseAndExample01.java │ │ │ ├── BitwiseOrExample01.java │ │ │ ├── InverseOperatorExample01.java │ │ │ ├── LeftShiftOperator.java │ │ │ ├── LogicAndExample01.java │ │ │ ├── LogicalOrExample01.java │ │ │ ├── RightShiftOperator.java │ │ │ ├── UnsignedRightShiftOperatorExample01.java │ │ │ └── XOR_Example01.java │ │ └── string │ │ │ ├── LongestCommonPrefixDemo.java │ │ │ ├── ReplaceSpace.java │ │ │ ├── RevoreDemo.java │ │ │ └── Test001.java │ │ └── space │ │ └── mamba │ │ └── niubi │ │ └── StackArithmeticExample.java │ └── test │ └── java │ └── space │ └── mamba │ ├── coding │ └── interviews │ │ └── No49_StringToIntegerTest.java │ └── leetcode │ ├── No387_First_Unique_Character_In_a_StringTest.java │ └── TwoSumTest.java ├── algorithms-python-example ├── __init__.py └── basic │ ├── BubbleSortDemo.py │ └── __init__.py ├── images ├── O │ ├── a-sorted-array-of-16-elements.png │ ├── basic_O.png │ ├── common-formula.png │ ├── general-formula.png │ ├── keep-half.png │ ├── log-formula.png │ ├── repeat-steps.png │ ├── select-mid-as-pivot.png │ ├── separating-the-power.png │ ├── simplify-formula.png │ └── till-find-result.png ├── basic │ ├── 600px-Greedy_algorithm_36_cents.png │ ├── BFS_DFS.png │ ├── Bubble_sort_animation.gif │ ├── CountMinSketch_1.jpg │ ├── CountMinSketch_2.jpg │ ├── LFU.jpg │ ├── SLRU.jpg │ ├── Sorting_shaker_sort_anim.gif │ ├── TinyLFU.png │ ├── W-TinyLFU.jpg │ ├── greedy_algorithm_package_1.png │ ├── greedy_algorithm_package_2.png │ ├── lru.jpg │ ├── merge_sort.png │ └── merge_sort_conquer.png ├── coding_offer │ ├── Multiply.jpg │ ├── RotateSmallestNumberOfArrays.jpg │ ├── no_11_print_number.png │ ├── stack_1.png │ └── stack_2.png ├── interview │ ├── 1.png │ ├── 10.png │ ├── 1_1.png │ ├── 3.png │ ├── 4.png │ ├── 5.png │ ├── 6.png │ ├── 7.png │ ├── 8.png │ └── 9.png ├── recursive │ ├── Recursive_1.png │ ├── Recursive_2.png │ ├── Recursive_4.png │ ├── Recursive_5.png │ └── Recursive_stack.png └── tree │ ├── 1.png │ ├── 10.jpg │ ├── 11.jpg │ ├── 12.jpg │ ├── 13.jpg │ ├── 14.jpg │ ├── 15.jpg │ ├── 16.jpg │ ├── 17.jpg │ ├── 2.jpg │ ├── 3.jpg │ ├── 4.png │ ├── 5.png │ ├── 6.png │ ├── 7.png │ ├── 8.png │ ├── 9.png │ ├── BST.jpeg │ ├── B_tree.png │ ├── Binary_Search_Tree.jpeg │ ├── Binary_search_tree_1.png │ ├── Binary_tree.png │ ├── b+_11.png │ ├── balanced_search_tree.jpeg │ ├── red_block │ ├── red_block_tree_11.jpg │ ├── red_block_tree_12.jpg │ ├── red_block_tree_13.jpg │ ├── red_block_tree_14.jpg │ ├── red_block_tree_15.jpg │ ├── red_block_tree_16.jpg │ ├── red_block_tree_17.jpg │ ├── red_block_tree_18.jpg │ ├── red_block_tree_19.jpg │ ├── red_block_tree_2.jpg │ ├── red_block_tree_20.jpg │ ├── red_block_tree_21.jpg │ ├── red_block_tree_22.jpg │ ├── red_block_tree_23.jpg │ ├── red_block_tree_24.jpg │ ├── red_block_tree_25.jpg │ ├── red_block_tree_26.jpg │ ├── red_block_tree_27.jpg │ ├── red_block_tree_28.jpg │ ├── red_block_tree_29.jpg │ ├── red_block_tree_30.jpg │ ├── red_block_tree_31.jpg │ ├── red_block_tree_32.jpg │ ├── red_block_tree_33.jpg │ ├── red_block_tree_34.jpg │ ├── red_block_tree_35.jpg │ ├── red_block_tree_36.jpg │ ├── red_block_tree_37.jpg │ ├── red_block_tree_38.jpg │ ├── red_block_tree_39.jpg │ ├── red_block_tree_40.jpg │ ├── red_block_tree_41.jpg │ ├── red_block_tree_42.jpg │ ├── red_block_tree_43.jpg │ ├── red_block_tree_44.jpg │ ├── red_block_tree_45.jpg │ ├── red_block_tree_46.jpg │ ├── red_block_tree_47.jpg │ ├── red_block_tree_48.jpg │ ├── red_block_tree_49.jpg │ ├── red_block_tree_50.jpg │ ├── red_block_tree_51.jpg │ ├── red_block_tree_52.jpg │ ├── red_block_tree_53.jpg │ ├── red_block_tree_54.jpg │ ├── red_block_tree_55.jpg │ ├── red_block_tree_56.jpg │ ├── red_block_tree_57.jpg │ ├── red_block_tree_58.jpg │ ├── red_block_tree_59.jpg │ ├── red_block_tree_60.jpg │ ├── red_block_tree_61.jpg │ ├── red_block_tree_62.jpg │ ├── red_block_tree_63.jpg │ └── red_block_tree_64.jpg │ ├── red_block_left.jpg │ ├── red_block_left_gif.gif │ ├── red_block_right.jpg │ ├── red_block_right_gif.gif │ └── red_block_tree.png ├── pom.xml ├── 几种淘汰算法.md ├── 剑指offer ├── 01、剑指offer.md ├── 05、从尾到头打印链表.md ├── 07、用两个栈实现队列.md ├── 08、求旋转数组的最小数字.md ├── 09、斐波那契数列的第n项(青蛙跳台阶).md ├── 10、求二进制数中1的个数.md ├── 11、数值的整数次方.md ├── 12、打印1到最大的n位数.md ├── 13、O(1)时间删除链表节点.md ├── 14、使数组中的奇数位于偶数前面.md ├── 15、找链表中倒数第K个节点.md ├── 16、输出反转后的链表.md ├── 17、合并两个有序链表.md ├── 18、判断二叉树A中是否包含子树B.md ├── 20、顺时针打印矩阵.md ├── 21、包含min函数的栈.md ├── 22、判断一个栈是否是另一个栈的弹出序列.md ├── 23、1.层序遍历二叉树.md ├── 23、2.分行从上到下打印二叉树.md ├── 24、后序遍历二叉搜索树.md ├── 25、二叉树中和为某值的路径.md ├── 26、复杂链表的复制.md ├── 30、找出最小的K个数.md ├── 31、连续子数组的最大和.md ├── 32、从1到整数n中1出现的次数.md ├── 33、把数组中的数排成一个最小的数.md ├── 34、求第N个丑数.md.md ├── 35、第一个出现一次的字符.md ├── 36、数组中逆序对的个数.md ├── 37、两个链表的第一个公共节点.md ├── 38、字符串的排列.md ├── 38、数字在排序数组中出现的次数.md ├── 39、二叉树的深度.md ├── 40、数组中只出现一次的两个数,而其他数都出现两次.md ├── 41、和为s的连续正数序列.md ├── 42、翻转字符串.md ├── 43、n个骰子的点数及出现的概率.md ├── 45、圆圈中最后剩下的数.md ├── 46、1+2+3+…+n的和.md ├── 47、不用加减乘除做加法.md ├── 48、不能被继承的类.md ├── 49、字符串转换为整数.md ├── 50、树中两个节点的最低公共祖先.md ├── 51、找出重复的数.md ├── 52、构建-乘积数组.md ├── 53、正则表达式匹配.md ├── 54、表示数值的字符串.md ├── 55、字符流中第一个不重复的字符.md ├── 56、链表中环的入口节点.md ├── 58、二叉树的下一个节点.md ├── 60、按之字形顺序打印二叉树.md ├── 61、I-从上到下打印二叉树.md ├── 61、II-把二叉树打印成多行.md ├── 62、序列化二叉树.md ├── 63、二叉搜索树的第k大节点.md └── 64、数据流中的中位数.md ├── 常见算法题目 ├── 0002、最小堆.md ├── 0003、Top-N算法的实现.md ├── 0005、分组Top N问题(一) - java实现Top n算法基础.md ├── 0010、N皇后问题.md ├── 0030、贪心算法.md ├── 0032、经典算法-背包问题.md ├── 0060、 有两个int型的整数:x,y;不使用"if","? :","switch"等判断语句!找出a、b中最大的数!.md ├── 0110、给你1到100万的连续整数,我从中取出一个数然后打乱数组,你给我求出被取出的是什么数.md └── 0111、有两个int类型的数a和b,你能写出几种交换它们值的办法?越多越好.md └── 框架算法 └── 06、选举算法.md /.github/workflows/go.yml: -------------------------------------------------------------------------------- 1 | name: Go CI with Lint and test #Actions名称 2 | on: 3 | push: 4 | branches: 5 | - master # 只在master上push触发 6 | pull_request: 7 | branches: 8 | - master 9 | jobs: 10 | lint: # 使用golangci-lint 进行静态检查 11 | name: Lint 12 | runs-on: ubuntu-18.04 13 | steps: 14 | - name: Set up Go 1.12 15 | uses: actions/setup-go@v1 16 | with: 17 | go-version: 1.12 18 | id: go 19 | - name: Code 20 | uses: actions/checkout@v1 21 | - name: Intsall Golangci-lint 22 | run: curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh| sh -s -- -b . latest 23 | - name: Lint 24 | run: ./golangci-lint run ./... 25 | 26 | test: 27 | name: Unit Testing # go test 28 | runs-on: ${{ matrix.os }} 29 | strategy: 30 | matrix: 31 | os: [ubuntu-latest] # 选择系统类型 32 | steps: 33 | - name: Set up Go 1.13 34 | uses: actions/setup-go@v1 35 | with: 36 | go-version: 1.13 37 | id: go 38 | - name: Code 39 | uses: actions/checkout@v1 40 | - name: Go Get dependencies 41 | run: go get -v -t -d ./... 42 | - name: Go Test 43 | run: go test -v ./... 44 | -------------------------------------------------------------------------------- /.github/workflows/maven.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a Java project with Maven 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven 3 | 4 | name: Java CI with Maven #Actions名称 5 | 6 | on: 7 | push: 8 | branches: [ master ] 9 | pull_request: 10 | branches: [ master ] 11 | 12 | jobs: 13 | UnitTest: 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - uses: actions/checkout@v2 18 | - name: Set up JDK 13 19 | uses: actions/setup-java@v1 #使用官方脚本创建java环境 20 | with: 21 | java-version: 13 22 | - name: Cache Maven packages 23 | uses: actions/cache@v2 24 | with: 25 | path: ~/.m2 26 | key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }} 27 | restore-keys: ${{ runner.os }}-m2 28 | - name: test with Maven 29 | run: mvn test --file pom.xml 30 | -------------------------------------------------------------------------------- /002、二进制的运算.md: -------------------------------------------------------------------------------- 1 | 2 | ## [原文](https://www.jianshu.com/p/08b1df5fffa2) 3 | 4 | # 二进制的运算 5 | 6 | 转成二进制主要有以下几种:正整数转二进制,负整数转二进制,小数转二进制 7 | 8 | 在说明换算之前,先介绍一下次方和负次方的概念(面向新手): 9 | 10 | 11 | -------------------------------------------------------------------------------- /00、基础知识/01、基础/01、递归 Recursion.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # 递归 recursion 4 | 5 | 6 | ## 举个例子 7 | 8 | 计算 n! 9 | 10 | n!= 1 * 2 * 3 * n 11 | 12 | ```java 13 | long factorial(long n) { 14 | // 递归的终止条件 15 | if (n <= 1) { 16 | return 1; 17 | } 18 | return n * factorail(n - 1); 19 | } 20 | ``` 21 | - 递归执行顺序 22 | 23 | factorial(6) 24 | 25 | 6 * factorial(5) 26 | 27 | 6 * (5 * factorial(4)) 28 | 29 | 6 * (5 * (4 * factorial(3)))) 30 | 31 | 6 * (5 * (4 * (3 * factorial(2))))) 32 | 33 | 6 * (5 * (4 * (3 * (2 * factorial(1))))) 34 | 35 | 6 * (5 * (4 * (3 * (2 * 1)))) 36 | 37 | 6 * (5 * (4 * (3 * 2))) 38 | 39 | 6 * (5 * (4 * 6)) 40 | 41 | 6 * (5 * 24) 42 | 43 | 6 * 120 44 | 45 | 720 46 | 47 | 48 | ## 结论 49 | 50 | 对于递归我们应该知道的是,方法的调用其实是入栈与出栈 51 | 52 | > 回溯 53 | 54 | ## [动画演示](https://www.mathwarehouse.com/programming/gifs.php) 55 | 56 | -------------------------------------------------------------------------------- /00、基础知识/01、基础/02、递归的执行过程.md: -------------------------------------------------------------------------------- 1 | ## [递归调用的过程](https://www.coursera.org/lecture/c-chengxu-sheji/di-gui-diao-yong-de-guo-cheng-3JLR6) 2 | 3 | 4 | 5 | # 递归的执行过程 6 | 7 | -------------------------------------------------------------------------------- /00、基础知识/02、排序算法/03、鸡尾酒排序.md: -------------------------------------------------------------------------------- 1 | 2 | ## [原文](https://zh.wikipedia.org/wiki/%E9%B8%A1%E5%B0%BE%E9%85%92%E6%8E%92%E5%BA%8F) 3 | 4 | # 鸡尾酒排序 5 | 6 | 鸡尾酒排序,也就是定向冒泡排序,鸡尾酒搅拌排序,搅拌排序(也可以视作选择排序的一种变形),涟漪排序, 7 | 来回排序或快乐小时排序,是冒泡排序的一种变形。 8 | 此算法与冒泡排序的不同处在于排序时是以双向在序列中进行排序。 9 | 10 | ![](../../images/basic/Sorting_shaker_sort_anim.gif) 11 | 12 | ## 与冒泡排序不同的地方 13 | 14 | 鸡尾酒排序等于是冒泡排序的轻微变形。 15 | 不同的地方在于从低到高然后从高到低,而冒泡排序则仅从低到高去比较序列里的每个元素。 16 | 他可以得到比冒泡排序稍微好一点的性能,原因是冒泡排序只从一个方向进行比对(由低到高), 17 | 每次循环只移动一个项目。 18 | 19 | 以序列(2,3,4,5,1)为例,鸡尾酒排序只需要访问一次序列就可以完成排序,但如果使用冒泡排序则需要四次。 20 | 但是在随机数序列的状态下,鸡尾酒排序与冒泡排序的效率都很差劲。 -------------------------------------------------------------------------------- /00、基础知识/02、排序算法/04、直接选择排序.md: -------------------------------------------------------------------------------- 1 | 2 | # 直接选择排序 -------------------------------------------------------------------------------- /00、基础知识/02、排序算法/05、希尔排序.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # 希尔排序 -------------------------------------------------------------------------------- /00、基础知识/02、排序算法/06、直接插入排序.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # 直接插入排序 -------------------------------------------------------------------------------- /00、基础知识/02、排序算法/07、快速排序.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # 快速排序 4 | -------------------------------------------------------------------------------- /00、基础知识/02、排序算法/10、堆排序.md: -------------------------------------------------------------------------------- 1 | 2 | ##### [原文](https://www.cnblogs.com/chengxiao/p/6129630.html) 3 | 4 | # 堆排序 5 | 6 | -------------------------------------------------------------------------------- /00、基础知识/02、排序算法/50、对两个数组进行merge 排序.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # 对两个数组进行merge 排序 4 | 5 | 6 | ## [代码]() -------------------------------------------------------------------------------- /00、基础知识/05、动态规划/03、Kadane算法.md: -------------------------------------------------------------------------------- 1 | [动态规划法(八)最大子数组问题(maximum subarray problem)](https://segmentfault.com/a/1190000015205978) 2 | 3 | # Kadane算法 4 | 5 | - 最大子数组问题(maximum subarray problem) 6 | 7 | - 8 | 9 | Kadane算法的简单想法就是寻找所有连续的正的子数组(max_ending_here就是用来干这事的), 10 | 同时,记录所有这些连续的正的子数组中的和最大的连续数组。 11 | 每一次我们得到一个正数,就将它与max_so_far比较,如果它的值比max_so_far大,则更新max_so_far的值。 12 | 13 | -------------------------------------------------------------------------------- /00、基础知识/05、动态规划/07、动态规划.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # 07、动态规划(dynamic programming) 4 | 5 | ## 动态规划的解法 6 | 7 | 1. 递归 + 记忆化 -> 递推 8 | 2. 状态的定义 :opt[n],dp[n],fib[n] 9 | 3. 状态转移方程: opt[n] = best_of(opt[n-1],opt[n - 2],...) 10 | 4. 最优子结构 11 | 12 | 13 | 14 | ## 例子 15 | 16 | ### 1、动态规划解决 斐波拉契 17 | [Program for Fibonacci numbers](/space/pankui/basis/dynamic_programing/FibExample01.java) 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /00、基础知识/05、动态规划/09、DP(动态规划) VS 回溯 VS 贪心.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # DP(动态规划) VS 回溯 VS 贪心 4 | 5 | - 回溯(递归) - 重复计算 6 | - 贪心 - 永远局部最优 7 | - DP - 记录局部最优子结构/多种记录值 -------------------------------------------------------------------------------- /01、数据结构/01、数据结构概述.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # 数据结构概述 4 | 5 | ## 数据结构概述: 6 | 7 | 程序设计 = 数据结构 + 算法 8 | 9 | 数据结构 = 数据的逻辑结构 + 数据的存储结构 + 数据的运算(算法) 10 | 11 | 数据结构:数据元素之间存在所有特定关系的集合, 12 | 13 | 数据结构可以分为物理结构和逻辑结构 14 | 15 | ## 逻辑结构: 16 | 17 | - 集合结构——元素同属于一个集合 18 | 19 | - 线性结构——一对一的关系 20 | 21 | - 树形结构——一对多的关系 22 | 23 | - 图形结构——多对多的关系 24 | 25 | ## 物理结构:数据元素存储到存储器上 26 | 27 | 1、数据元素 28 | 29 | 顺序存储结构——地址连续存储,逻辑地址和物理地址相同(如数组结构) 30 | 链式存储结构——地址不一定是连续的,逻辑地址和物理地址不对应, 31 | 所以存储是需要存储元素的地址(如链表) 32 | 33 | 34 | ## 常见的数据结构 35 | 36 | - 数组(Array) 37 | 38 | - 栈(Stack) 39 | 40 | - 队列(Queue) 41 | 42 | - 链表(Linked List) 43 | 44 | - 树(Tree) 45 | 46 | - 图(Graph) 47 | 48 | - 堆(Heap) 49 | 50 | - 散列表(Hash) 51 | 52 | ### 从逻辑上分为: 53 | 54 | - 线性结构 55 | - 线性表(表,栈,队列等) 56 | 57 | - 非线性结构 58 | - 树(二叉树,Huffman树等) 59 | - 图(有向图,无向图等 60 | 61 | ## 算法分析 62 | 63 | 算法分析主要涉及时间复杂度和空间复杂度。一般情况我们讨论时间复杂度。 64 | 65 | - 频度:某语句在算法中被执行的次数。 66 | 67 | - T(n):所有语句的频度之和,n为问题规模。 68 | 69 | - 时间复杂度:当n趋于无穷大时,T(n)的数量级。记作T(n)=O(f(n)), O的含义是T(n)的数量级。 70 | 71 | - 用数量级O(f(n))表示算法执行时间T(n)时,f(n)一般去简单形式:O(1) 72 | 73 | 74 | ### 时间复杂度的关系如下: 75 | 76 | O(1) < O(log * 2n) < O(n) < O(n *log * 2n) < O(n^2) < O(n^3) < O(2^n) 77 | 78 | 79 | [原文](https://www.huweihuang.com/article/arithmetic/data-structure-overview/) 80 | 81 | 82 | [原文](https://www.jianshu.com/p/01a12bac4709) 83 | -------------------------------------------------------------------------------- /01、数据结构/02、数据结构.md: -------------------------------------------------------------------------------- 1 | 2 | # 数据结构 3 | 4 | 算法 + 数据结构 = 程序 5 | 6 | ## 什么是数据结构? 7 | 数据结构是计算机存储、组织数据的方式。对于特定的数据结构(比如数组),有些操作效率很高(读某个数组元素), 8 | 有些操作的效率很低(删除某个数组元素)。程序员的目标是为当前的问题选择最优的数据结构。 9 | 10 | ## 为什么我们需要数据结构? 11 | 数据是程序的核心要素,因此数据结构的价值不言而喻。 12 | 无论你在写什么程序,你都需要与数据打交道,比如员工工资、股票价格、杂货清单或者电话本。 13 | 在不同场景下,数据需要以特定的方式存储,我们有不同的数据结构可以满足我们的需求。 14 | 15 | ## 8种常用数据结构 16 | 17 | - 数组 18 | - 栈 19 | - 队列 20 | - 链表 21 | - 图 22 | - 树 23 | - 前缀树 24 | - 哈希表 25 | 26 | ## 数组 Array 27 | 28 | 优点:插入快,如果知道下标可以非常快的存取; 29 | 30 | 缺点:查找慢,删除满,大小固定; 31 | 32 | ### 有序数组 33 | 34 | 优点:比无序数组查找快; 35 | 36 | 缺点:删除和插入慢,大小固定 37 | 38 | # 栈 Stack 39 | 40 | 优点:提供后进先出的存取; 41 | 42 | 缺点:存取其他项很慢; 43 | 44 | ## 队列 Queue 45 | 46 | 优点:提供后进先出的存取; 47 | 48 | 缺点:存取其他项很慢; 49 | 50 | ### 优先队列 PriorityQueue 51 | 52 | ## 链表 53 | 54 | 优点:插入快,删除快 55 | 56 | 缺点:查找慢 57 | 58 | ## 二叉树: 59 | 60 | 优点:查找,插入,删除都快(如果树保持平衡) 61 | 62 | 缺点:删除算法复杂;红黑树:优点:查找,插入,删除都快,树总是平衡的; 63 | 64 | 缺点:算法复杂;2-3-4 65 | 66 | ## 树 67 | 68 | 优点:查找,插入,删除都快,树总是平衡的;(类似于树对磁盘存储有用) 69 | 70 | 缺点:算法复杂; 71 | 72 | ## 哈希表 73 | 74 | 优点:如果已知关键字贼存取极快,插入快 75 | 76 | 缺点:删除慢,如果不知道关键字存取很慢,对存储空间使用不充分; 77 | 78 | ## 堆 79 | 80 | 优点:插入,删除快,对最大数据项的存取很快 81 | 82 | 缺点:对其他数据项存取慢; 83 | 84 | ## 图 85 | 86 | 优点:对现实世界建模; 87 | 88 | 缺点:有些算法慢且复杂; 89 | -------------------------------------------------------------------------------- /01、数据结构/10、二叉树遍历(先序、中序、后序).md: -------------------------------------------------------------------------------- 1 | 2 | ## [原文](https://www.jianshu.com/p/456af5480cee) 3 | 4 | 5 | # 二叉树遍历(先序、中序、后序) 6 | 7 | 8 | 前序遍历:根结点 ---> 左子树 ---> 右子树 9 | 10 | 中序遍历:左子树---> 根结点 ---> 右子树 11 | 12 | 后序遍历:左子树 ---> 右子树 ---> 根结点 13 | 14 | 层次遍历:只需按层次遍历即可 15 | -------------------------------------------------------------------------------- /01、数据结构/13、广度优先和深度优先搜索.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # 广度优先和深度优先搜索 4 | 5 | 6 | 7 | ![](../images/basic/BFS_DFS.png) -------------------------------------------------------------------------------- /02、算法复杂度/02、Master Theorem-主定理与时间复杂度.md: -------------------------------------------------------------------------------- 1 | ## [主定理](https://zh.wikipedia.org/wiki/%E4%B8%BB%E5%AE%9A%E7%90%86) 2 | 3 | # 02、Master Theorem-主定理与时间复杂度 4 | 5 | ![](/images/O/basic_O.png) 6 | 7 | 8 | 9 | 10 | - [算法的时间复杂度](https://www.jianshu.com/p/f4cca5ce055a) 11 | 12 | 13 | - [如何清晰的理解算法中的时间复杂度?](https://www.zhihu.com/question/20196775/answer/693388880) 14 | -------------------------------------------------------------------------------- /03、散列表的工作原理.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/03、散列表的工作原理.md -------------------------------------------------------------------------------- /03、树/00、树列表.md: -------------------------------------------------------------------------------- 1 | 2 | # 树列表 3 | 4 | - b+树 5 | 6 | - AVL树 7 | 8 | - BKD树 9 | -------------------------------------------------------------------------------- /03、树/01、二叉查找树.md: -------------------------------------------------------------------------------- 1 | 2 | ## [原文](https://zh.wikipedia.org/wiki/%E4%BA%8C%E5%85%83%E6%90%9C%E5%B0%8B%E6%A8%B9) 3 | 4 | ## [参考](https://blog.csdn.net/heyue_99/article/details/74833808) 5 | 6 | # 二叉排序树(二叉查找树)英语:Binary Search Tree 7 | 8 | > 二叉查找树(英语:Binary Search Tree),也称为二叉搜索树、有序二叉树(ordered binary tree) 9 | 或排序二叉树(sorted binary tree),是指一棵空树或者具有下列性质的二叉树: 10 | 11 | 12 | 二叉排序树:或者是一棵空树,或者是具有下列性质的二叉树: 13 | 14 | 1. 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 15 | 16 | 2. 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 17 | 18 | 3. 它的左、右子树也分别为二叉排序树。 19 | 20 | 4. 没有键值相等的节点。 21 | 22 | 23 | 二叉查找树相比于其他数据结构的优势在于查找、插入的时间复杂度较低。 24 | 为 O(log n)。二叉查找树是基础性数据结构,用于构建更为抽象的数据结构,如集合、多重集、关联数组等。 25 | 26 | 二叉查找树的查找过程和次优二叉树类似,通常采取二叉链表作为二叉查找树的存储结构。 27 | 中序遍历二叉查找树可得到一个关键字的有序序列, 28 | 一个无序序列可以通过构造一棵二叉查找树变成一个有序序列,构造树的过程即为对无序序列进行查找的过程。 29 | 每次插入的新的结点都是二叉查找树上新的叶子结点,在进行插入操作时,不必移动其它结点,只需改动某个结点的指针,由空变为非空即可。 30 | 搜索、插入、删除的复杂度等于树高,期望 O(log n),最坏 O(n)(数列有序,树退化成线性表)。 31 | 32 | 虽然二叉查找树的最坏效率是 O(n),但它支持动态查询, 33 | 且有很多改进版的二叉查找树可以使树高为 O(log n),从而将最坏效率降至 O(log n),如AVL树、红黑树等。 34 | 35 | > 平衡树是计算机科学中的一类改进的二叉查找树 36 | 37 | ![](../images/tree/Binary_Search_Tree.jpeg) 38 | 39 | > 最优BST树形结构和最差BST树形(左边的二叉查找树退化成链表) 40 | 41 | 42 | ![](../images/tree/BST.jpeg) 43 | 44 | > 最差时候会是 O(n),比如插入的元素是有序的,生成的二叉排序树就是一个链表,这种情况下,需要遍历全部元素才行 -------------------------------------------------------------------------------- /03、树/01、二叉树.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/03、树/01、二叉树.md -------------------------------------------------------------------------------- /03、树/02、二分搜索.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## [参考](https://zh.wikipedia.org/wiki/%E4%BA%8C%E5%88%86%E6%90%9C%E7%B4%A2%E7%AE%97%E6%B3%95) 4 | 5 | # 二分搜索 -------------------------------------------------------------------------------- /03、树/03、01. 平衡树.md: -------------------------------------------------------------------------------- 1 | 2 | ## [原文](https://zh.wikipedia.org/wiki/%E5%B9%B3%E8%A1%A1%E6%A0%91) 3 | 4 | ## [原文](https://www.jianshu.com/p/cf202771cb6c) 5 | 6 | # 平衡树 balanced search tree 7 | 8 | 平衡树是计算机科学中的一类数据结构。 9 | 10 | 平衡树是计算机科学中的一类改进的二叉查找树。 11 | 12 | 一般的二叉查找树的查询复杂度是跟目标结点到树根的距离(即深度)有关, 13 | 因此当结点的深度普遍较大时,查询的均摊复杂度会上升,为了更高效的查询,平衡树应运而生了。 14 | 15 | 在这里,平衡指所有叶子的深度趋于平衡,更广义的是指在树上所有可能查找的均摊复杂度偏低。 16 | 17 | 18 | 平衡二叉排序树如其名字在二叉树上约定了平衡条件, 19 | 通过下图这个平衡二叉树和非平衡二叉树来说明平衡二叉树的平衡条件。 20 | 21 | ![](../images/tree/balanced_search_tree.jpeg) 22 | 图 平衡和非平衡二叉树 23 | 24 |     平衡性,是指每个节点的左子树高度和右子树高度之差不超过1, 25 | 即 Math.abs(Hieght(node.left) –Height(node.right))<1。 26 | 对于图中的平衡二叉树而言,其上每个节点都满足这个性质。 27 | 图中的非平衡树,之所以不是平衡树,是因为在根节点处平衡性遭到了破坏, 28 | 其左子树高度和右子树高度之差为2。 29 | 30 | 31 | ## 基本操作 32 | 几乎所有平衡树的操作都基于树旋转操作,通过旋转操作可以使得树趋于平衡。 33 | 对一棵查找树(search tree)进行查询、新增、删除等动作,所花的时间与树的高度h成比例,并不与树的容量 n 成比例。 34 | 如果可以让树维持矮矮胖胖的好身材,也就是让h维持在 O(log n)的左右,完成上述工作就很省时间。 35 | 能够一直维持好身材,不因新增删除而长歪的搜寻树,叫做平衡树(balanced search tree)。 36 | 37 | 旋转(Rotate) —— 不破坏左小右大特性的小手术 38 | 39 | ## 各种平衡树 40 | 41 | - AVL树,经典平衡树, 所有操作的最坏复杂度都是 O(log n)的。 42 | 43 | - Treap,利用随机堆的期望深度来优化树的深度,达到较优的期望复杂度。 44 | 45 | - 伸展树,使得经常查找的结点深度较小,从而降低均摊复杂度。 46 | 47 | - 红黑树。 48 | 49 | - 加权平衡树。 50 | 51 | - 2-3树 52 | 53 | - AA树 54 | 55 | - 替罪羊树 56 | 57 | - 节点大小平衡树 -------------------------------------------------------------------------------- /03、树/03、02.为什么费尽苦心保证树的平衡性.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # 为什么费尽苦心保证数的平衡性 4 | 5 | > 因为树的查找性能取决于树的高度,让树尽可能的平衡是为了降低树的高度. -------------------------------------------------------------------------------- /03、树/04、AVL树.md: -------------------------------------------------------------------------------- 1 | 2 | ## [原文](https://www.jianshu.com/p/65c90aa1236d) 3 | 4 | ## [原文](https://blog.csdn.net/heyue_99/article/details/74833808 ) 5 | 6 | # AVL树 7 | 8 | ## 什么是AVL树 9 | 10 | AVL树,是一种平衡(balanced)的二叉搜索树(binary search tree, 简称为BST)。 11 | 由两位科学家在1962年发表的论文《An algorithm for the organization of information》当中提出, 12 | 作者是发明者G.M. Adelson-Velsky和 E.M. Landis]。它具有以下两个性质: 13 | 14 | - 任意一个结点的key,比它的左孩子key大,比它的右孩子key小; 15 | - 任意结点的孩子结点之间高度差距最大为1。 16 | 17 | 18 | 本身首先是一棵二叉查找树。带有平衡条件:每个结点的左右子树的高度之差的绝对值(平衡因子)最多为1。 19 | 20 | 最小不平衡树:距离插入结点最近的,且平衡因子的绝对值大于1的结点为根的子树。 21 | 22 | 平衡二叉树的构建:在构建二叉排序树的过程中,每当插入一个结点,先检查是否破坏了树的平衡性, 23 | 若是,找出最小的不平衡树,通过右旋(顺时针,BF>0)、左旋(逆时针,BF<0),使之成为新的平衡子树。 24 | 25 | 查找、插入、删除时间复杂度O(log n)。 26 | 27 | 平衡二叉树的追求的是全局均衡,如在做插入,删除操作时,需要调整整棵树(旋转树), 28 | 显然这是费时的,因此希望在做调整时,是局部调整,因此提出了红黑树,这样一种高效的数据结构(也是最变态的一种数据结构)。 29 | 30 | 31 | ## [AVL树的Java实现](https://www.cnblogs.com/skywang12345/p/3577479.html) 32 | 33 | ### [AVL树平衡性调整策略](https://www.jianshu.com/p/cf202771cb6c) -------------------------------------------------------------------------------- /03、树/04、为什么STL和linux都使用红黑树作为平衡树的实现?.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## [原文](https://www.zhihu.com/question/20545708/answer/58717264) 4 | 5 | # 为什么C ++ STL和linux都使用红黑树作为平衡树的实现? 6 | 7 | 8 | 1. 如果插入一个node引起了树的不平衡,AVL和RB-Tree都是最多只需要2次旋转操作,即两者都是O(1); 9 | 但是在删除node引起树的不平衡时,最坏情况下,AVL需要维护从被删node到root这条路径上所有node的平衡性, 10 | 因此需要旋转的量级O(logN),而RB-Tree最多只需3次旋转,只需要O(1)的复杂度。 11 | 12 | 2. 其次,AVL的结构相较RB-Tree来说更为平衡,在插入和删除node更容易引起Tree的unbalance, 13 | 因此在大量数据需要插入或者删除时,AVL需要rebalance的频率会更高。 14 | 因此,RB-Tree在需要大量插入和删除node的场景下,效率更高。 15 | 自然,由于AVL高度平衡,因此AVL的search效率更高。 16 | 17 | 3. map的实现只是折衷了两者在search、insert以及delete下的效率。 18 | 总体来说,RB-tree的统计性能是高于AVL的 19 | 20 | 21 | > 红黑树除了旋转有可能还需要由下而上修正节点颜色,旋转和改颜色开销差不多的。 22 | -------------------------------------------------------------------------------- /03、树/04、从Trie树(字典树)谈到后缀树.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## [原文](https://blog.csdn.net/v_july_v/article/details/6897097) 4 | 5 | # 从Trie树(字典树)谈到后缀树 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /03、树/05、为什么这样设计红黑树.md: -------------------------------------------------------------------------------- 1 | ## [原文]() 2 | 3 | # 为什么这样设计红黑树 4 | 5 | 为了解决二叉排序树的这种退化的情况, 6 | 在其基础上提出了平衡二叉排序树,实现平衡二叉排序树的方法有很多种, 7 | 如AVL树、红黑树等. 8 | 9 | 10 | ## [为什么费尽苦心保证树的平衡性](03、02.为什么费尽苦心保证树的平衡性.md) 11 | 12 | 因为树的查找性能取决于树的高度,让树尽可能的平衡是为了降低树的高度. -------------------------------------------------------------------------------- /03、树/05、红黑树.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## [原文](https://www.jianshu.com/p/fc5e16b5c674) 4 | 5 | # 红黑树 6 | 7 | 红黑树又称红-黑二叉树,它首先是一颗二叉树,它具体二叉树所有的特性。同时红黑树更是一颗自平衡的排序二叉树。 8 | 9 | 我们知道一颗基本的二叉树他们都需要满足一个基本性质: 10 | 即树中的任何节点的值大于它的左子节点,且小于它的右子节点。 11 | 12 | 按照这个基本性质使得树的检索效率大大提高。 13 | 我们知道在生成二叉树的过程是非常容易失衡的,最坏的情况就是一边倒(只有右/左子树), 14 | 这样势必会导致二叉树的检索效率大大降低(O(n)), 15 | 所以为了维持二叉树的平衡,大牛们提出了各种实现的算法,如:AVL,SBT,伸展树,TREAP ,红黑树等等。 16 | 17 | 平衡二叉树必须具备如下特性:它是一棵空树或它的左右两个子树的高度差的绝对值不超过1, 18 | 并且左右两个子树都是一棵平衡二叉树。也就是说该二叉树的任何一个等等子节点,其左右子树的高度都相近。 19 | 20 | ![](../images/tree/Binary_tree.png) 21 | 22 | 红黑树顾名思义就是节点是红色或者黑色的平衡二叉树,它通过颜色的约束来维持着二叉树的平衡。 23 | 对于一棵有效的红黑树二叉树而言我们必须增加如下规则: 24 | 25 | - 每个节点都只能是红色或者黑色 26 | 27 | - 根节点是黑色 28 | 29 | - 每个叶节点(NIL节点,空节点)是黑色的。 30 | 31 | - 如果一个结点是红的,则它两个子节点都是黑的。也就是说在一条路径上不能出现相邻的两个红色结点。 32 | 33 | - 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。 34 | 35 | 红黑树示意图如下: 36 | 37 | ![](../images/tree/red_block_tree.png) 38 | 39 | 上面的规则前4条都好理解,第5条规则到底是什么情况, 40 | 下面简单解释下,比如图中红8到1左边的叶子节点的路径包含两个黑色节点,到6下面的叶子节点的路径也包含两个黑色节点。 41 | 42 | 但是在在添加或删除节点后,红黑树就发生了变化,可能不再满足上面的5个特性, 43 | 为了保持红黑树的以上特性,就有了三个动作:左旋、右旋、着色。 44 | 45 | 下面来看下什么是红黑树的左旋和右旋: 46 | 47 | ![](../images/tree/red_block_left.jpg) 48 | 对x进行左旋,意味着"将x变成一个左节点"。 49 | 50 | ![](../images/tree/red_block_right.jpg) 51 | 对y进行右旋,意味着"将y变成一个右节点"。 52 | 53 | 54 | 如果还是没看明白,下面找了两张左旋和右旋的动态图 55 | 56 | ![](../images/tree/red_block_left_gif.gif) 57 | 58 | ![](../images/tree/red_block_right_gif.gif) 59 | 60 | ok,对二叉树、红黑树的概念有所了解后,我们来看下红黑树的两个主要逻辑添加和删除,看看TreeMap是怎么实现的。 61 | 62 | 63 | ## 应用 64 | 65 | 1. 广泛用于C ++的STL中,地图和集都是用红黑树实现的; 66 | 67 | 2. 着名的Linux的的进程调度完全公平调度程序,用红黑树管理进程控制块,进程的虚拟内存区域都存储在一颗红黑树上, 68 | 每个虚拟地址区域都对应红黑树的一个节点,左指针指向相邻的地址虚拟存储区域,右指针指向相邻的高地址虚拟地址空间; 69 | 70 | 3. IO多路复用的epoll的的的实现采用红黑树组织管理的的的sockfd,以支持快速的增删改查; 71 | 72 | 4. Nginx的的的中用红黑树管理定时器,因为红黑树是有序的,可以很快的得到距离当前最小的定时器; 73 | 74 | 5. Java的的的中TreeMap中的中的实现; 75 | -------------------------------------------------------------------------------- /03、树/07、红黑树深入剖析及Java实现.md: -------------------------------------------------------------------------------- 1 | 2 | ## [原文](https://tech.meituan.com/redblack_tree.html) 3 | 4 | # 红黑树深入剖析及Java实现 -------------------------------------------------------------------------------- /03、树/11、AVL树与红黑树区别.md: -------------------------------------------------------------------------------- 1 | 2 | ## [原文](https://blog.csdn.net/zhangkunrun/article/details/38336543) 3 | 4 | ## [原文](https://www.zhihu.com/question/19856999/answer/42185147) 5 | 6 | # AVL树与红黑树区别 7 | 8 | 红黑树比 AVL 树具体更高效在旋转次数比AVL少。 9 | 10 | 11 | ## 红黑树与AVL树的比较: 12 | 13 | AVL是严格的平衡树,因此在增加或者删除节点的时候,根据不同情况,旋转的次数比红黑树要多; 14 | 15 | 红黑树是用非严格的平衡来换取增删节点时候旋转次数的降低开销; 16 | 17 | 所以简单说,如果你的应用中,搜索的次数远远大于插入和删除,那么选择AVL树, 18 | 19 | 如果搜索,插入删除次数几乎差不多,应选择红黑树。即,有时仅为了排序(建立-遍历-删除),不查找或查找次数很少,R-B树合算一些。 20 | 21 | 22 | 23 | 红黑树与AVL树的调整平衡的实现机制不同,AVL靠平衡因子和旋转, 24 | 红黑树靠节点颜色以及一些约定再加上旋转。因此,存在去掉颜色的红黑树后它不是AVL树, 25 | 比如左子树都是黑的,右子树都是红黑相间的,这样整个树高度2n的时候,根节点的左右层数差可以到n 26 | -------------------------------------------------------------------------------- /03、树/31、B+树介绍.md: -------------------------------------------------------------------------------- 1 | 2 | ## [原文](https://zh.wikipedia.org/wiki/B%2B%E6%A0%91) 3 | 4 | ## [原文](https://www.cnblogs.com/wade-luffy/p/6292784.html) 5 | 6 | # B+树介绍 7 | 8 | B+ 树是一种树数据结构,通常用于数据库和操作系统的文件系统中。B+ 树的特点是能够保持数据稳定有序, 9 | 其插入与修改拥有较稳定的对数时间复杂度。B+ 树元素自底向上插入,这与二叉树恰好相反。 10 | 11 | B+ 树在节点访问时间远远超过节点内部访问时间的时候,比可作为替代的实现有着实在的优势。 12 | 这通常在多数节点在次级存储比如硬盘中的时候出现。通过最大化在每个内部节点内的子节点的数目减少树的高度,平衡操作不经常发生, 13 | 而且效率增加了。这种价值得以确立通常需要每个节点在次级存储中占据完整的磁盘块或近似的大小。 14 | 15 | 16 | B+树和二叉树、平衡二叉树一样,都是经典的数据结构。B+树由B树和索引顺序访问方法(ISAM,是不是很熟悉?对, 17 | 这也是MyISAM引擎最初参考的数据结构)演化而来,但是在实际使用过程中几乎已经没有使用B树的情况了。 18 | 19 | B+树的定义十分复杂,因此只简要地介绍B+树:B+树是为磁盘或其他直接存取辅助设备而设计的一种平衡查找树, 20 | 在B+树中,所有记录节点都是按键值的大小顺序存放在同一层的叶节点中,各叶节点指针进行连接。 21 | 22 | 我们先来看一个B+树,其高度为2,每页可存放4条记录,扇出(fan out)为5 23 | 24 | ![](../images/tree/b+_11.png) 25 | 26 | 可以看出,所有记录都在叶节点中,并且是顺序存放的,如果我们从最左边的叶节点开始顺序遍历, 27 | 可以得到所有键值的顺序排序:5、10、15、20、25、30、50、55、60、65、75、80、85、90。 28 | 29 | 30 | ## B + 树和 B 树的区别 31 | 32 | 区别就是就是 B树会在每个节点都保存数据, 33 | 在B+树中,所有记录节点都是按键值的大小顺序存放在同一层的叶节点中,各叶节点指针进行连接,所有记录都在叶节点中 -------------------------------------------------------------------------------- /03、树/32、B树和B+树的插入、删除图文详解.md: -------------------------------------------------------------------------------- 1 | 2 | ## [原文](https://www.cnblogs.com/nullzx/p/8729425.html) 3 | 4 | # B树和B+树的插入、删除图文详解 5 | -------------------------------------------------------------------------------- /04、图/10、图的两种存储方式-邻接矩阵和邻接表.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # 图的两种存储方式-邻接矩阵和邻接表 4 | 5 | 6 | 7 | 当你会用图数据库的时候,就一直在考虑,我的这么多数据(定点、边、属性之类)到底是`咋存储的呢`? 8 | 就比如我问你关系型数据库mysql里数据咋存储的,大家都知道索引的话就是B+树结构 9 | 10 | ## 邻接矩阵 11 | 12 | 二维数组来存储 13 | 14 | ## 邻接表 15 | 16 | 那为什么要引入邻接表呢? 17 | 18 | 考虑下:对于边数相对顶点较少的图,这种结构是存在对存储空间的极大浪费的。 19 | 因此我们考虑另外一种存储结构方式:邻接表(Adjacency List),即数组与链表相结合的存储方法。 20 | 21 | 22 | 使用链表来存储 23 | -------------------------------------------------------------------------------- /05、链表/03、反转一个单链表&判断链表是否有环.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # 反转一个单链表&判断链表是否有环 4 | 5 | 6 | ## 实战题目 7 | 8 | leetcode 9 | 10 | ### 206 11 | 12 | ### 24 13 | 14 | ### 141 链表是否有环 15 | 16 | 实现方法 17 | 18 | - 硬做,遍历0.5s 如何还没有完成,说明有环,否则是NULL 就没有【如果一个环很长超过0.5S】 19 | 20 | - 使用Set 来保存每个链表的节点,如果有重复,说明有环。 21 | 22 | - 使用快慢指针【龟兔赛跑,如果追上了说明有环】 -------------------------------------------------------------------------------- /05、链表/05、一个链表,求中间结点.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # 一个链表,求中间结点 4 | 5 | -------------------------------------------------------------------------------- /11、leetcode/104、104. Maximum Depth of Binary Tree.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # [104. Maximum Depth of Binary Tree](https://leetcode.com/problems/maximum-depth-of-binary-tree/) 4 | 5 | Given a binary tree, find its maximum depth. 6 | 7 | The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node. 8 | 9 | Note: A leaf is a node with no children. 10 | 11 | Example: 12 | 13 | Given binary tree [3,9,20,null,null,15,7], 14 | ``` 15 | 3 16 | / \ 17 | 9 20 18 | / \ 19 | 15 7 20 | ``` 21 | return its depth = 3. 22 | 23 | 24 | 25 | 题目大概意思:给定二叉树,找到其最大深度 26 | 27 | 因此我们可以使用下面三种方法解决,每次记录最大的 28 | 29 | - BFS 广度优先 30 | 31 | - DFS 深度优先 32 | 33 | - 递归 34 | 35 | ## 实现代码 36 | 37 | [No104_Maximum_Depth_of_Binary_Tree](/algorithms-java-example/src/main/java/space.mamba/leetcode/algorithms/No104_Maximum_Depth_of_Binary_Tree.java) 38 | 39 | 40 | ## 相似题目 41 | 42 | [111. Minimum Depth of Binary Tree.md](111、111.%20Minimum%20Depth%20of%20Binary%20Tree.md) 43 | -------------------------------------------------------------------------------- /11、leetcode/111、111. Minimum Depth of Binary Tree.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # [111. Minimum Depth of Binary Tree](https://leetcode.com/problems/minimum-depth-of-binary-tree/) 4 | 5 | 6 | Given a binary tree, find its minimum depth. 7 | 8 | The minimum depth is the number of nodes along the shortest path from the root node down to the nearest leaf node. 9 | 10 | Note: A leaf is a node with no children. 11 | 12 | Example: 13 | 14 | Given binary tree [3,9,20,null,null,15,7], 15 | ``` 16 | 3 17 | / \ 18 | 9 20 19 | / \ 20 | 15 7 21 | ``` 22 | return its minimum depth = 2. 23 | 24 | 25 | 题目大概意思:给定二叉树,找到其最小深度 26 | 27 | 因此我们可以使用下面三种方法解决,每次记录最小的 28 | 29 | - BFS 广度优先 30 | 31 | - DFS 深度优先 32 | 33 | - 递归 34 | 35 | 36 | ## 代码实现 37 | 38 | 39 | 40 | 下面这个题目也是一样的问题 41 | 42 | ## [104. Maximum Depth of Binary Tree](https://leetcode.com/problems/maximum-depth-of-binary-tree/) -------------------------------------------------------------------------------- /11、leetcode/11、盛水最大的容器.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | # 盛最多水的容器 5 | 6 | -------------------------------------------------------------------------------- /11、leetcode/121. Best Time to Buy and Sell Stock.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # [121. Best Time to Buy and Sell Stock](https://leetcode.com/problems/best-time-to-buy-and-sell-stock/) 4 | 5 | 6 | [JAVA解决](/algorithms-java-example/src/main/java/space.mamba/leetcode/algorithms/No121_Best_Time_to_Buy_and_Sell_Stock.java) 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /11、leetcode/122. Best Time to Buy and Sell Stock II.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # [122. Best Time to Buy and Sell Stock II](https://leetcode.com/problems/best-time-to-buy-and-sell-stock-ii/) 4 | 5 | 说了在某一天可以买卖任意次股票 6 | 7 | 参考: 8 | 9 | [JAVA解决](/algorithms-java-example/src/main/java/space.mamba/leetcode/algorithms/No122_Best_Time_to_Buy_and_Sell_Stock_2.java) 10 | 11 | 典型的贪心算法的思想 12 | 13 | 14 | -------------------------------------------------------------------------------- /11、leetcode/167、167. Two Sum II - Input array is sorted.md: -------------------------------------------------------------------------------- 1 | 2 | ## [原文](https://leetcode.com/problems/two-sum-ii-input-array-is-sorted/) 3 | 4 | # 167. Two Sum II - Input array is sorted 5 | 6 | 7 | 8 | Given an array of integers that is already sorted in ascending order, find two numbers such that they add up to a specific target number. 9 | 10 | The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. 11 | 12 | Note: 13 | 14 | Your returned answers (both index1 and index2) are not zero-based. 15 | You may assume that each input would have exactly one solution and you may not use the same element twice. 16 | Example: 17 | ```java 18 | 19 | Input: numbers = [2,7,11,15], target = 9 20 | Output: [1,2] 21 | 22 | ``` 23 | Explanation: The sum of 2 and 7 is 9. Therefore index1 = 1, index2 = 2. 24 | 25 | ## 思路 26 | 27 | 左边 + 右边与target 比较, 如果大于那么就左边自增,小于就右边自增 28 | 29 | ## [答案](/algorithms-java-example/src/main/java/space.mamba/leetcode/algorithms/No167_Two_Sum_II_Input_array_is_sorted.java) 30 | -------------------------------------------------------------------------------- /11、leetcode/169、169. Majority Element.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # 169. Majority Element 4 | 5 | 6 | 7 | 8 | 9 | Given an array of size n, find the majority element. 10 | The majority element is the element that appears more than ⌊ n/2 ⌋ times. 11 | 12 | You may assume that the array is non-empty and the majority element always exist in the array. 13 | > 因为一定存在。所以只需要判断出现次数最多的 14 | 15 | Example 1: 16 | 17 | Input: [3,2,3] 18 | Output: 3 19 | Example 2: 20 | 21 | Input: [2,2,1,1,1,2,2] 22 | Output: 2 23 | 24 | 25 | [实现例子 No169_Majority_Element](/algorithms-java-example/src/main/java/space.mamba/leetcode/algorithms/No169_Majority_Element.java) 26 | -------------------------------------------------------------------------------- /11、leetcode/184、184.LeetCode:Department Highest Salary - 部门内最高工资.md: -------------------------------------------------------------------------------- 1 | 2 | ## [原文](https://leetcode.com/problems/department-highest-salary/) 3 | 4 | # LeetCode:Department Highest Salary - 部门内最高工资 5 | 6 | 7 | ```mysql 8 | select d.name AS Department,e.Name AS Employee ,e.Salary AS Salary 9 | from Employee e join Department d on e.DepartmentId = d.id 10 | where e.Salary in ( 11 | select Max(Salary) from Employee e2 where e.DepartmentId = e2.DepartmentId 12 | ) 13 | ``` 14 | 15 | -------------------------------------------------------------------------------- /11、leetcode/202、202. Happy Number.md: -------------------------------------------------------------------------------- 1 | 2 | ## [原文](https://leetcode.com/problems/happy-number) 3 | 4 | ## [参考](https://www.cnblogs.com/yrbbest/p/4493542.html) 5 | 6 | # 202. Happy Number 7 | 8 | 9 | ## 题目: 10 | 11 | Write an algorithm to determine if a number is "happy". 12 | 13 | A happy number is a number defined by the following process: Starting with any positive integer, 14 | replace the number by the sum of the squares of its digits, 15 | and repeat the process until the number equals 1 (where it will stay), 16 | or it loops endlessly in a cycle which does not include 1. 17 | Those numbers for which this process ends in 1 are happy numbers. 18 | 19 | Example: 19 is a happy number 20 | ``` 21 | 12 + 92 = 82 22 | 82 + 22 = 68 23 | 62 + 82 = 100 24 | 12 + 02 + 02 = 1 25 | ``` 26 | 27 | 28 | ## 题解: 29 | 30 | 判断一个数字是否为Happy Number。这道题跟求无限循环小数很像,最好维护一个HashSet, 31 | 假如遇见重复,则返回false。否则替换n为digits square root sum,当n == 1时循环结束返回true。 32 | 33 | Time Complexity - O(n), Space Complexity - O(n)。 34 | 35 | 36 | ## [代码答案](/algorithms-java-example/src/main/java/space.mamba/leetcode/algorithms/No202_Happy_Number.java) 37 | 38 | -------------------------------------------------------------------------------- /11、leetcode/21、21. Merge Two Sorted Lists.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # 21. Merge Two Sorted Lists 4 | 5 | Merge two sorted linked lists and return it as a new list. 6 | The new list should be made by splicing together the nodes of the first two lists. 7 | 8 | Example: 9 | ``` 10 | Input: 1->2->4, 1->3->4 11 | Output: 1->1->2->3->4->4 12 | ``` 13 | 14 | ## 思路分析: 15 | 题目的意思是合并2个有序的链表。 16 | 17 | 思路是用2个指针分别指向2个链表,比较2个节点,将较小的节点放入结果链表中并且指针后移 18 | 19 | ## 思路: 20 | 21 | ### 一、用循环来做: 22 | 这道题目比较简单,考察链表的基本用法, 23 | 从头到尾分别扫描两个链表,比较元素大小,小的元素即插入新的链表中。 24 | 注意特殊值的判断,如果两个链表中有一个为空,则直接返回另一个链表即可。 25 | 26 | #### [例子](/algorithms-java-example/src/main/java/space.mamba/leetcode/algorithms/No21_Merge_Two_Sorted_Lists.java) 27 | 28 | ### 二、用递归来做: 29 | > 递归输出有死循环 30 | 31 |         分析两个链表合并的过程,从合并两个链表的头结点开始, 32 | 新的链表的头结点是原来两个链表中值较小的头结点;继续合并剩余的结点, 33 | 在剩余的两个链表中剩下的结点依然是排序的,我们还是比较两个头结点的值, 34 | 我们将值较小的头结点的值和前面合并得到的链表的尾结点链接起来,依次类推, 35 | 这是典型的递归问题。 36 | 37 | 注意鲁棒性问题,要对空链表做特殊处理。 38 | 39 | 40 | ## [Similar Questions](21、21. Merge Two Sorted Lists.md) 41 | 42 | -------------------------------------------------------------------------------- /11、leetcode/233. Number of Digit One.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # 233. Number of Digit One 4 | 5 | Given an integer n, count the total number of digit 1 appearing in all non-negative integers less than or equal to n. 6 | 7 | Example: 8 | ``` 9 | Input: 13 10 | Output: 6 11 | ``` 12 | Explanation: Digit 1 occurred in the following numbers: 1, 10, 11, 12, 13. 13 | 14 | 15 | 16 | 17 | ### [解决方案](/剑指offer/32、从1到整数n中1出现的次数.md) 18 | 19 | -------------------------------------------------------------------------------- /11、leetcode/235、235. Lowest Common Ancestor of a Binary Search Tree.md: -------------------------------------------------------------------------------- 1 | ## [原文](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-tree/) 2 | 3 | # 235. Lowest Common Ancestor of a Binary Search Tree 4 | 5 | Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BST. 6 | 7 | According to the definition of LCA on Wikipedia: 8 | “The lowest common ancestor is defined between two nodes p and q 9 | as the lowest node in T that has both p and q as descendants 10 | (where we allow a node to be a descendant of itself).” 11 | 12 | Given binary search tree: root = [6,2,8,0,4,7,9,null,null,3,5] 13 | 14 | 15 | 查询 p and q 的最近root 16 | 17 | ## 解决方案 18 | 19 | 通过了解二叉搜索树,我们知道 左子树小于root,root小于右子树。 20 | 因此只需要判断 p 与root.val的值来确认是在左还是在右,q 也是一样。 21 | 如果都小于,那么它们都在左边。如果都大于那么都在右边,否则它们一个左一个右,当前 root就是目前的root. 22 | 23 | ### 代码实现 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /11、leetcode/239、239. Sliding Window Maximum.md: -------------------------------------------------------------------------------- 1 | ## [\[Leetcode\] Sliding Window Maximum 滑动窗口最大值](https://segmentfault.com/a/1190000003903509) 2 | 3 | # 239. Sliding Window Maximum 4 | 5 | 6 | Given an array nums, there is a sliding window of size k which is moving 7 | from the very left of the array to the very right. 8 | You can only see the k numbers in the window. 9 | Each time the sliding window moves right by one position. Return the max sliding window. 10 | 11 | Example: 12 | ``` 13 | Input: nums = [1,3,-1,-3,5,3,6,7], and k = 3 14 | Output: [3,3,5,5,6,7] 15 | ``` 16 | Explanation: 17 | ``` 18 | Window position Max 19 | --------------- ----- 20 | [1 3 -1] -3 5 3 6 7 3 21 | 1 [3 -1 -3] 5 3 6 7 3 22 | 1 3 [-1 -3 5] 3 6 7 5 23 | 1 3 -1 [-3 5 3] 6 7 5 24 | 1 3 -1 -3 [5 3 6] 7 6 25 | 1 3 -1 -3 5 [3 6 7] 7 26 | ``` 27 | 28 | Note: 29 | You may assume k is always valid, 1 ≤ k ≤ input array's size for non-empty array. 30 | 31 | Follow up: 32 | Could you solve it in linear time? 33 | 34 | 35 | 36 | ## 实现 37 | 38 | ## 双向队列 39 | 40 | ### 复杂度 41 | 时间 O(N) 空间 O(K) 42 | 43 | ### 思路 44 | 我们用双向队列可以在O(N)时间内解决这题。当我们遇到新的数时,将新的数和双向队列的末尾比较,如果末尾比新数小,则把末尾扔掉, 45 | 直到该队列的末尾比新数大或者队列为空的时候才住手。 46 | 这样,我们可以保证队列里的元素是从头到尾降序的, 47 | 由于队列里只有窗口内的数,所以他们其实就是窗口内第一大,第二大,第三大...的数。 48 | 保持队列里只有窗口内数的方法和上个解法一样,也是每来一个新的把窗口最左边的扔掉, 49 | 然后把新的加进去。然而由于我们在加新数的时候,已经把很多没用的数给扔了, 50 | 这样队列头部的数并不一定是窗口最左边的数。这里的技巧是,我们队列中存的是那个数在原数组中的下标, 51 | 这样我们既可以直到这个数的值,也可以知道该数是不是窗口最左边的数。这里为什么时间复杂度是O(N)呢? 52 | 因为每个数只可能被操作最多两次,一次是加入队列的时候,一次是因为有别的更大数在后面,所以被扔掉,或者因为出了窗口而被扔掉。 53 | 54 | 55 | ## 优先队列 56 | 57 | ### 复杂度 58 | 时间 O(NlogK) 空间 O(K) 59 | 60 | ### 思路 61 | 维护一个大小为K的最大堆,依此维护一个大小为K的窗口,每次读入一个新数,都把堆中窗口最左边的数扔掉,再把新数加入堆中,这样堆顶就是这个窗口内最大的值。 62 | 63 | ### 注意 64 | -结果数组的大小是nums.length + 1 - k, 赋值时下标也是i + 1 - k -------------------------------------------------------------------------------- /11、leetcode/241、242. Valid Anagram.md: -------------------------------------------------------------------------------- 1 | ## [原文](https://leetcode.com/problems/valid-anagram/) 2 | 3 | # Valid Anagram 4 | 5 | 6 | Given two strings s and t , write a function to determine if t is an anagram of s. 7 | 8 | Example 1: 9 | ``` 10 | Input: s = "anagram", t = "nagaram" 11 | Output: true 12 | ``` 13 | Example 2: 14 | ``` 15 | Input: s = "rat", t = "car" 16 | Output: false 17 | ``` 18 | 19 | Note: 20 | You may assume the string contains only lowercase alphabets. 21 | 22 | ## 实现 23 | 24 | [No_242ValidAnagram](/algorithms-java-example/src/main/java/space.mamba/leetcode/algorithms/No_242ValidAnagram.java) 25 | 26 | -------------------------------------------------------------------------------- /11、leetcode/35、35. Search Insert Position.md: -------------------------------------------------------------------------------- 1 | ## [原文](https://leetcode.com/problems/search-insert-position/) 2 | 3 | # 35. Search Insert Position 4 | 5 | Given a sorted array and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order. 6 | 7 | You may assume no duplicates in the array. 8 | 9 | 翻译: 给一个排好序的数组,给一个值返回这个值在数组的序号, 10 | 如果不存在则插入且返回当前所在数组的序号。 11 | 12 | Example 1: 13 | ``` 14 | Input: [1,3,5,6], 5 15 | Output: 2 16 | ``` 17 | Example 2: 18 | ``` 19 | Input: [1,3,5,6], 2 20 | Output: 1 21 | ``` 22 | Example 3: 23 | ``` 24 | Input: [1,3,5,6], 7 25 | Output: 4 26 | ``` 27 | Example 4: 28 | ``` 29 | Input: [1,3,5,6], 0 30 | Output: 0 31 | ``` 32 | 33 | ## [代码答案](/algorithms-java-example/src/main/java/space.mamba/leetcode/algorithms/No35_SearchInsert.java) 34 | -------------------------------------------------------------------------------- /11、leetcode/387、387. First Unique Character in a String(从一个字符串中找出第一个不重复字符).md: -------------------------------------------------------------------------------- 1 | 2 | ## []() 3 | 4 | # 从一个字符串中找出第一个不重复字符 5 | 6 | 7 | ## 解决方法- 8 | 9 | > 最优解 10 | 11 | 很简单的解法,因为只包含字母(26),所以可以用int数组作为简单的哈希表。 12 | 13 | ## 解决办法二 14 | 15 | 如果这个字符第一次出现的位置和最后出现的位置相等,就说明字符串中它只出现了一次 16 | 17 | ## 解决办法三 18 | 19 | 使用 Map 来实现,如果出现一次记录1 ,出现两次累计,最后取第一个出现一次的 20 | 21 | ## [答案](/algorithms-java-example/src/main/java/space.mamba/leetcode/algorithms/No387_First_Unique_Character_In_a_String.java) 22 | -------------------------------------------------------------------------------- /11、leetcode/38、38.Count and Say (计数和发言) 解题思路和方法.md: -------------------------------------------------------------------------------- 1 | 2 | ## [原文](https://leetcode.com/problems/count-and-say/) 3 | 4 | ## [参考](https://blog.csdn.net/xygy8860/article/details/46821417) 5 | 6 | # 38.Count and Say (计数和发言) 解题思路和方法 7 | 8 | ``` 9 | Count and Say  10 | 11 | The count-and-say sequence is the sequence of integers beginning as follows: 12 | 1, 11, 21, 1211, 111221, ... 13 | 14 | 1 is read off as "one 1" or 11. 15 | 11 is read off as "two 1s" or 21. 16 | 21 is read off as "one 2, then one 1" or 1211. 17 | Given an integer n, generate the nth sequence. 18 | 19 | Note: The sequence of integers will be represented as a string. 20 | ``` 21 | 22 | 23 | 思路:题意实在太难理解了,尤其是英文又不好,只能参看下别人的资料,理解下规则。 24 | 25 | 终于理解,题意是n=1时输出字符串1;n=2时,数上次字符串中的数值个数,因为上次字符串有1个1,所以输出11;n=3时, 26 | 由于上次字符是11,有2个1,所以输出21;n=4时,由于上次字符串是21,有1个2和1个1,所以输出1211。 27 | 依次类推,写个countAndSay(n)函数返回字符串。 28 | 29 | 题意理解之后就好办了,是典型的递归问题,其代码很简单,如下: 30 | 31 | 32 | n=2是把n=1结果读出来,n=3是把n=2结果读出来,n=4是把n=3结果读出来……m个x读作mx。 33 | 34 | 35 | ## [代码实现](/algorithms-java-example/src/main/java/space.mamba/leetcode/algorithms/No38_CountAndSay.java) 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /11、leetcode/50、50. Pow(x, n).md: -------------------------------------------------------------------------------- 1 | ## [原文](https://leetcode.com/problems/powx-n/) 2 | 3 | # 50. Pow(x, n) 4 | 5 | Implement pow(x, n), which calculates x raised to the power n (xn). 6 | 7 | [leetcode 50. Pow(x, n)-细说边界问题](https://blog.csdn.net/happyaaaaaaaaaaa/article/details/51655964) 8 | 9 | [[LeetCode] 50. Pow(x, n) 求x的n次方](https://www.cnblogs.com/grandyang/p/4383775.html) 10 | 11 | 12 | 题解: 13 | 14 | pow(x,n)就是求x的n次方。x的N次方可以看做:x^n = x^(n/2)*x^(n/2)*x^(n%2)。所以利用递归求解,当n==1的时候,x^n=x。 15 | 16 | 当然n是可以小于0的,2^(-3) = 1/(2^3)。按照上面那个规律就可以解决了。 17 | 18 | 19 | 20 | ## 代码实现 21 | 22 | [No50_Pow](/algorithms-java-example/src/main/java/space.mamba/leetcode/algorithms/No50_Pow.java) 23 | 24 | -------------------------------------------------------------------------------- /11、leetcode/53、53. Maximum Subarray.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # [53. Maximum Subarray](https://leetcode.com/problems/maximum-subarray/) 4 | > 找出最大子数组 5 | 6 | Given an integer array nums, find the contiguous subarray (containing at least one number) 7 | which has the largest sum and return its sum. 8 | 9 | 这道题要求 求连续的数组值,加和最大。 10 | 11 | Example: 12 | ``` 13 | Input: [-2,1,-3,4,-1,2,1,-5,4], 14 | Output: 6 15 | Explanation: [4,-1,2,1] has the largest sum = 6. 16 | ``` 17 | Follow up: 18 | 19 | If you have figured out the O(n) solution, 20 | try coding another solution using the divide and conquer approach, which is more subtle. 21 | 22 | 23 | ## 解析 24 | 25 | 常见的解决方法是计算每个子数组并比较大小,时间复杂度为O(n^2)。 26 | 27 | 本文使用一种时间复杂度为O(n)的方法解决: 28 | 步骤:从数组第一个元素开始遍历并做累加,若累加值小于0则抛弃,重新累加。 29 | 30 | 31 | 32 | ## 最大子数列和问题 33 | 34 | ### 暴力求解 35 | 最暴力的算法是枚举,双重for循环,枚举所有的子数列。这样时间复杂度为O(n^2),相对而言是比较慢的,但是是最简单的一种方法。 36 | 37 | ### Kadane算法 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /11、leetcode/670、670. Maximum Swap.md: -------------------------------------------------------------------------------- 1 | ## [Maximum Swap](https://leetcode.com/problems/maximum-swap/) 2 | 3 | # Maximum Swap 4 | 5 | Given a non-negative integer, you could swap two digits at most once to get the maximum valued number. 6 | Return the maximum valued number you could get. 7 | 8 | Example 1: 9 | ``` 10 | Input: 2736 11 | Output: 7236 12 | ``` 13 | Explanation: Swap the number 2 and the number 7. 14 | 15 | Example 2: 16 | 17 | ``` 18 | Input: 9973 19 | Output: 9973 20 | ``` 21 | 22 | Explanation: No swap. 23 | 24 | ## Note: 25 | The given number is in the range [0, 10^8] 26 | 27 | 28 | 29 | 30 | 思路:这道题如果遍历每一种情况,时间复杂度是很高的,所以我们采用贪心算法,一次遍历O(n)即可解决问题。 31 | 32 | 基于贪心算法的基本观察是,从后向前遍历,如果遇到更大的值maxValue,那么保存这个值的下标(index)和值(value), 33 | 如果在这个值的左边遇到比maxValue小的数,那么保存对应的值leftValue和leftIndex,这两个配对组成一组候选值。 34 | 从右向左遍历数组,遇到满足上述条件的值就覆盖更新对应的值,最后交换leftValue和maxValue对应的下标即可。 35 | 36 | [No670_Maximum_Swap](/algorithms-java-example/src/main/java/space.mamba/leetcode/algorithms/No670_Maximum_Swap.java) 37 | 38 | -------------------------------------------------------------------------------- /11、leetcode/69. Sqrt(x).md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # 69. Sqrt(x) 4 | 5 | -------------------------------------------------------------------------------- /11、leetcode/703. Kth Largest Element in a Stream.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # 703. Kth Largest Element in a Stream 4 | 5 | -------------------------------------------------------------------------------- /11、leetcode/83、83. Remove Duplicates from Sorted List.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # 83. Remove Duplicates from Sorted List 4 | 5 | 6 | Given a sorted linked list, delete all duplicates such that each element appear only once. 7 | 8 | > 删除重复的值 9 | 10 | Example 1: 11 | ``` 12 | Input: 1->1->2 13 | Output: 1->2 14 | 15 | ``` 16 | Example 2: 17 | ``` 18 | Input: 1->1->2->3->3 19 | Output: 1->2->3 20 | ``` 21 | 22 | ## [答案](/algorithms-java-example/src/main/java/space.mamba/leetcode/algorithms/No_83_Remove_Duplicates_from_Sorted_List.java) 23 | -------------------------------------------------------------------------------- /11、leetcode/88、88. Merge Sorted Array.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # [88. Merge Sorted Array](https://leetcode.com/problems/merge-sorted-array/) 4 | 5 | Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array. 6 | 7 | Note: 8 | 9 | - The number of elements initialized in nums1 and nums2 are m and n respectively. 10 | - You may assume that nums1 has enough space (size that is greater or equal to m + n) to hold additional elements from nums2. 11 | 12 | Example: 13 | 14 | Input: 15 | ``` 16 | nums1 = [1,2,3,0,0,0], m = 3 17 | nums2 = [2,5,6], n = 3 18 | ``` 19 | Output: [1,2,2,3,5,6] 20 | 21 | 22 | ## [答案](/algorithms-java-example/src/main/java/space.mamba/leetcode/algorithms/No88_Merge_Sorted_Array.java) 23 | 24 | - [参考](http://www.cnblogs.com/grandyang/p/4059650.html) 25 | 26 | - [参考](https://github.com/gaochengcheng/LeetCode/blob/master/LeetCode%E5%88%B7%E9%A2%98%E7%AC%94%E8%AE%B0%EF%BC%88%E6%8E%92%E5%BA%8F%E9%83%A8%E5%88%86%EF%BC%89.md#toc1) 27 | 28 | - [参考](http://www.scutmath.com/leetcode_88.html) 29 | 30 | 31 | ## [Similar Questions](21、21. Merge Two Sorted Lists.md) 32 | 33 | -------------------------------------------------------------------------------- /11、leetcode/98、98. Validate Binary Search Tree.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # 98. Validate Binary Search Tree 4 | 5 | 6 | ## 解决办法 7 | 8 | 9 | ### 递归实现 10 | 11 | [递归实现](/algorithms-java-example/src/main/java/space.mamba/leetcode/algorithms/No98_Validate_Binary_Search_Tree.java) 12 | 13 | ### 中序遍历 之后,数组是否有序的。 14 | 15 | 16 | 用递归的中序遍历,但不同之处是不将遍历结果存入一个数组遍历完成再比较, 17 | 而是每当遍历到一个新节点时和其上一个节点比较, 18 | 如果不大于上一个节点那么则返回 false,全部遍历完成后返回 true 19 | 20 | 需要用到栈,因为中序遍历可以非递归来实现,所以只要在其上面稍加改动便可,代码如下: 21 | 22 | ```java 23 | public class Solution { 24 | public boolean isValidBST(TreeNode root) { 25 | Stack s = new Stack(); 26 | TreeNode p = root, pre = null; 27 | while (p != null || !s.empty()) { 28 | while (p != null) { 29 | s.push(p); 30 | p = p.left; 31 | } 32 | p = s.pop(); 33 | if (pre != null && p.val <= pre.val) return false; 34 | pre = p; 35 | p = p.right; 36 | } 37 | return true; 38 | } 39 | } 40 | ``` 41 | 42 | 43 | -------------------------------------------------------------------------------- /11、leetcode/README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # 4 | 5 | -------------------------------------------------------------------------------- /20、几个面试经典算法题Java解答/02、用队列实现栈&用栈实现队列.md: -------------------------------------------------------------------------------- 1 | 2 | # 用队列实现栈&用栈实现队列 3 | 4 | ## 两个队列实现一个栈 5 | 6 | 7 | ## 两个栈实现一个队列 -------------------------------------------------------------------------------- /21、海量数据处理/05、一个1TB的文件,你有什么最快的办法能够求出重复次数最多的TOP5行数据?.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # 一个1TB的文件,你有什么最快的办法能够求出重复次数最多的TOP5行数据? -------------------------------------------------------------------------------- /30、其他算法/03、Base64编码原理与应用.md: -------------------------------------------------------------------------------- 1 | ## [原文](http://blog.xiayf.cn/2016/01/24/base64-encoding/) 2 | 3 | # Base64编码原理与应用 4 | 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![example workflow name](https://github.com/hi-mamba/algorithms/workflows/Java%20CI%20with%20Maven/badge.svg) 2 | 3 | # algorithms 4 | 5 | 6 | 算法的重要性不是在日益减小,而是在日益加强。👨‍💻‍🤖🤣 7 | -------------------------------------------------------------------------------- /algorithms-go-example/BubbleSortDemo.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sort" 6 | ) 7 | 8 | // main 函数必须被放在main包中. 9 | func main() { 10 | // fmt.Println("Hello World") - 使用fmt包中的Println用来输出文字到标准输出设备 11 | fmt.Println("Hello World") 12 | 13 | // declare a array 14 | // this array must implenet sort.Inerface 15 | data := sort.IntSlice{22, 34, 3, 40, 18, 4} 16 | BubbleSort(data) 17 | fmt.Println("排序后:", data) 18 | } 19 | 20 | // BubbleSort 冒泡排序. data必须实现sort包中的Interface接口 21 | func BubbleSort(data sort.Interface) { 22 | n := data.Len() 23 | for i := 0; i < n-1; i++ { 24 | isChange := false 25 | for j := 0; j < n-1-i; j++ { 26 | if data.Less(j, j+1) { 27 | data.Swap(j, j+1) 28 | isChange = true 29 | } 30 | } 31 | if !isChange { 32 | break 33 | } 34 | } 35 | } 36 | 37 | -------------------------------------------------------------------------------- /algorithms-go-example/go.mod: -------------------------------------------------------------------------------- 1 | module go-example 2 | 3 | go 1.14 4 | -------------------------------------------------------------------------------- /algorithms-go-example/leetcode/1_TwoSum.go: -------------------------------------------------------------------------------- 1 | package leetcode 2 | 3 | /* 4 | 5 | https://leetcode.com/problems/two-sum/ 6 | 7 | Example: 8 | 9 | Given nums = [2, 7, 11, 15], target = 9, 10 | 11 | Because nums[0] + nums[1] = 2 + 7 = 9, 12 | return [0, 1]. 13 | 14 | 15 | 使用MAP 来实现 16 | 17 | */ 18 | 19 | func TwoSum(nums []int, target int) []int { 20 | 21 | mapExample := make(map[int]int) 22 | 23 | for i := 0; i < len(nums); i++ { 24 | if _, ok := mapExample[nums[i]]; ok { 25 | return []int{mapExample[nums[i]], i} 26 | } else { 27 | mapExample[target-nums[i]] = i 28 | } 29 | } 30 | return []int{} 31 | } -------------------------------------------------------------------------------- /algorithms-go-example/leetcode/225_Implement_Stack_using_Queues.go: -------------------------------------------------------------------------------- 1 | package leetcode 2 | 3 | 4 | type MyStack struct { 5 | q_temp []int 6 | q_main []int 7 | } 8 | 9 | func Constructor() MyStack { 10 | return MyStack{} 11 | } 12 | 13 | func (this *MyStack) Push(x int) { 14 | this.q_temp = append(this.q_temp, x) 15 | for _ = range this.q_main { 16 | this.q_temp = append(this.q_temp,this.q_main[0]) 17 | this.q_main = this.q_main[1:] 18 | 19 | } 20 | for len(this.q_temp) > 0 { 21 | this.q_main = append(this.q_main , this.q_temp[0]) 22 | this.q_temp = this.q_temp[1:] 23 | } 24 | } 25 | 26 | /** Removes the element on top of the stack and returns that element. */ 27 | func (this *MyStack) Pop() int { 28 | v := this.q_main[0] 29 | this.q_main = this.q_main[1:] 30 | return v 31 | } 32 | 33 | 34 | /** Get the top element. */ 35 | func (this *MyStack) Top() int { 36 | return this.q_main[0] 37 | } 38 | 39 | 40 | /** Returns whether the stack is empty. */ 41 | func (this *MyStack) Empty() bool { 42 | return len(this.q_main) == 0 43 | } -------------------------------------------------------------------------------- /algorithms-go-example/leetcode/go.mod: -------------------------------------------------------------------------------- 1 | module leetcode 2 | 3 | go 1.14 4 | -------------------------------------------------------------------------------- /algorithms-go-example/test/1_TwoSum_test.go: -------------------------------------------------------------------------------- 1 | package test 2 | 3 | import ( 4 | "../leetcode" // 导入同一项目下的mypackage包 5 | "fmt" 6 | "testing" //引入go 的testing框架包 7 | ) 8 | 9 | //编写测试用例,测试getSum是否正确 10 | func TestTwoSum(t *testing.T) { 11 | var nums = []int{2, 7, 11, 15} 12 | target := 9 13 | actual := leetcode.TwoSum(nums, target) 14 | fmt.Print(actual) 15 | if actual[0] != 0 || actual[1] != 1 { 16 | t.Fatal("actual = ", actual) 17 | } 18 | } 19 | 20 | func TestTwoSumResultIsNull(t *testing.T) { 21 | var nums = []int{2, 7, 11, 15} 22 | target := 99 23 | actual := leetcode.TwoSum(nums, target) 24 | if len(actual) !=0 { 25 | t.Fatal("actual = ", actual) 26 | } 27 | } 28 | 29 | 30 | -------------------------------------------------------------------------------- /algorithms-go-example/test/225_Implement_Stack_using_Queues_test.go: -------------------------------------------------------------------------------- 1 | package test 2 | 3 | import ( 4 | "../leetcode" // 导入同一项目下的mypackage包 5 | "testing" //引入go 的testing框架包 6 | ) 7 | 8 | //编写测试用例,测试getSum是否正确 9 | func TestPush(t *testing.T) { 10 | 11 | obj := leetcode.Constructor() 12 | obj.Push(1) 13 | obj.Push(2) 14 | obj.Push(3) 15 | //param_2 := obj.Pop() 16 | //param_3 := obj.Top() 17 | //param_4 := obj.Empty() 18 | 19 | if obj.Pop() != 3 { 20 | t.Error("Pop() ne 3") 21 | } 22 | if obj.Pop() != 2 { 23 | t.Error("Pop() ne 2") 24 | } 25 | 26 | } 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /algorithms-go-example/test/go.mod: -------------------------------------------------------------------------------- 1 | module test 2 | 3 | go 1.14 4 | -------------------------------------------------------------------------------- /algorithms-java-example/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | algorithms 7 | space.mamba 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | algorithms-java-example 13 | 14 | 15 | 16 | org.apache.maven.plugins 17 | maven-compiler-plugin 18 | 19 | 9 20 | 9 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | org.junit.jupiter 29 | junit-jupiter-api 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /algorithms-java-example/production/algorithms/java/space.mamba/leetcode/database/Duplicate_Emails.sql: -------------------------------------------------------------------------------- 1 | 182. Duplicate Emails 2 | 3 | Write a SQL query to find all duplicate emails in a table named Person. 4 | 5 | +----+---------+ 6 | | Id | Email | 7 | +----+---------+ 8 | | 1 | a@b.com | 9 | | 2 | c@d.com | 10 | | 3 | a@b.com | 11 | +----+---------+ 12 | For example, your query should return the following for the above table: 13 | 14 | +---------+ 15 | | Email | 16 | +---------+ 17 | | a@b.com | 18 | +---------+ 19 | Note: All emails are in lowercase. 20 | 21 | 22 | Mysql 答案: 23 | 24 | select Email 25 | from Person 26 | group by Email 27 | having count(Email) > 1; 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/basis/IntegerExample.java: -------------------------------------------------------------------------------- 1 | package space.mamba.basis; 2 | 3 | /** 4 | * @author meta a 5 | * @date 2022/3/4 6 | *
 7 |  *
 8 |  * 
9 | */ 10 | public class IntegerExample { 11 | 12 | public static void main(String[] args) { 13 | Integer a = 1; 14 | String b = "+123"; 15 | String c = "-234"; 16 | 17 | //debug a length 18 | //debug b parseInt 19 | //debug c parseInt 20 | System.out.println(a.toString()); 21 | System.out.println(Integer.parseInt(b)); 22 | System.out.println(Integer.parseInt(c)); 23 | 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/basis/LRU_Example01.java: -------------------------------------------------------------------------------- 1 | package space.mamba.basis; 2 | 3 | import java.util.LinkedHashMap; 4 | import java.util.Map; 5 | 6 | /** 7 | * @author meta a 8 | * @date 2022/3/9 9 | *
10 |  *      LinkedHashMap已经实现了LRU缓存淘汰算法
11 |  *
12 |  * 
13 | */ 14 | public class LRU_Example01 { 15 | 16 | 17 | //LinkedHashMap会自动扩容,如果想 实现限制容量删除队列顶端元素, 18 | //需要重写removeEldestEntry()方法,当map里面的元素个数大于了缓存最大容量, 19 | //删除链表的顶端元素。 20 | 21 | 22 | public static void main(String[] args) { 23 | LRULinkedHashMap obj = new LRULinkedHashMap(5); 24 | 25 | for (int i = 0; i < 10; i++) { 26 | obj.put(i, i); 27 | } 28 | System.out.println(obj); 29 | } 30 | } 31 | 32 | class LRULinkedHashMap extends LinkedHashMap { 33 | 34 | 35 | private int capacity; 36 | 37 | LRULinkedHashMap(int capacity) { 38 | // 初始大小,0.75是装载因子,true是表示按照访问时间排序 39 | super(capacity, 0.75f, true); 40 | //传入指定的缓存最大容量 41 | this.capacity = capacity; 42 | } 43 | 44 | @Override 45 | public boolean removeEldestEntry(Map.Entry eldest) { 46 | return size() > capacity; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/basis/MergeListSortExample.java: -------------------------------------------------------------------------------- 1 | package space.mamba.basis; 2 | 3 | 4 | /** 5 | * @author pankui 6 | * @date 2019-03-27 7 | *
 8 |  *      对两个数组进行merge 排序:
 9 |  * 
10 | */ 11 | public class MergeListSortExample { 12 | 13 | public static void main(String[] args) { 14 | MergeListSortExample solution = new MergeListSortExample(); 15 | int[] num1 = {1, 2, 3, 0, 0, 0}; 16 | int[] num2 = {2, 5, 6}; 17 | int[]arr = solution.mergeList(num1, num2); 18 | 19 | System.out.println("\n====华丽分割线\n"); 20 | for (int k = 0; k < arr.length; k++) { 21 | System.out.print(arr[k]+" "); 22 | } 23 | } 24 | 25 | /**这种不是排序好的。不行 */ 26 | public int[] mergeList(int[] a, int[] b) { 27 | 28 | int[] c = new int[a.length + b.length]; 29 | int i = 0, j = 0, k = 0; 30 | while (i < a.length && j < b.length) { 31 | if (a[i] > b[j]) { 32 | c[k] = b[j]; 33 | j++; 34 | k++; 35 | } else { 36 | c[k] = a[i]; 37 | i++; 38 | k++; 39 | } 40 | } 41 | 42 | while (i < a.length) { 43 | c[k] = a[i]; 44 | i++; 45 | k++; 46 | } 47 | while (j < b.length) { 48 | c[k] = b[j]; 49 | j++; 50 | k++; 51 | } 52 | 53 | return c; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/basis/Node.java: -------------------------------------------------------------------------------- 1 | package space.mamba.basis; 2 | 3 | /** 4 | * @author pankui 5 | * @date 25/04/2018 6 | *
 7 |  *  结点类
 8 |  * 
9 | */ 10 | 11 | public class Node { 12 | 13 | /** 14 | * 指针域 15 | */ 16 | private Node next; 17 | /** 18 | * 数据域 19 | */ 20 | private E data; 21 | 22 | public Node() { 23 | } 24 | 25 | /** 26 | * 头结点的构造方法 27 | * 28 | * @param data 29 | */ 30 | public Node(E data) { 31 | this.data = data; 32 | } 33 | 34 | /** 35 | * 非头结点的构造方法 36 | */ 37 | public Node(Node next, E data) { 38 | this.next = next; 39 | this.data = data; 40 | } 41 | 42 | public Node getNext() { 43 | return next; 44 | } 45 | 46 | public void setNext(Node next) { 47 | this.next = next; 48 | } 49 | 50 | public E getData() { 51 | return data; 52 | } 53 | 54 | public void setData(E data) { 55 | this.data = data; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/basis/hash/HashDemo.java: -------------------------------------------------------------------------------- 1 | package space.mamba.basis.hash; 2 | 3 | /** 4 | * @author pankui 5 | * @date 2018/10/15 6 | *
 7 |  *
 8 |  * 
9 | */ 10 | public class HashDemo { 11 | 12 | public static void main(String[] args) { 13 | 14 | System.out.println(2 >>> 2); 15 | System.out.println(2 << 2); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/basis/space/mamba/basis/Demo001.java: -------------------------------------------------------------------------------- 1 | package space.mamba.basis; 2 | 3 | /** 4 | * @author pankui 5 | * @date 01/05/2018 6 | *
 7 |  *     https://www.jianshu.com/p/7988e646a37e
 8 |  *
 9 |  *     http://gityuan.com/2015/10/24/jvm-bytecode-grammar/
10 |  *
11 |  *     https://www.jianshu.com/p/c11f98269b00
12 |  *
13 |  * 
14 | */ 15 | public class Demo001 { 16 | 17 | public static void main(String[] args) { 18 | 19 | int j = 0; 20 | int t = 0; 21 | for (int i = 0; i < 100; i++) { 22 | j = j++; 23 | t++; 24 | } 25 | System.out.println(j); 26 | System.out.println(t); 27 | 28 | 29 | 30 | int i = 0; 31 | i = i++; 32 | 33 | int k = i; 34 | System.out.println(i+" "+k); 35 | 36 | } 37 | 38 | 39 | } 40 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/binarytree/Demo.java: -------------------------------------------------------------------------------- 1 | package space.mamba.binarytree; 2 | 3 | /** 4 | * @author pankui 5 | * @date 24/04/2018 6 | *
 7 |  *
 8 |  * 
9 | */ 10 | public class Demo { 11 | } 12 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/coding/interviews/DeleteWhitespace.java: -------------------------------------------------------------------------------- 1 | package space.mamba.coding.interviews; 2 | 3 | /** 4 | * @author pankui 5 | * @date 2019-01-19 6 | *
 7 |  *
 8 |  *
 9 |  * ## Java去除字符串中的空格
10 |  *
11 |  * 特别注意了
12 |  *
13 |  * 1、strim或者Trip都是只能去除头部和尾部的空字符串。中间的部分是不能够去除的!
14 |  *
15 |  * 2、推荐使用ApacheCommonse的 StringUtils.deleteWhitespace("a b c"); 删除所有空格。
16 |  *
17 |  * 3、如果我自己写,我会采用foreache遍历每一个字符串中的字符然后利用StringBuilder追加 或者使用 Replace进行替换,
18 |  *
19 |  * 4、替换的时候对于多个空格可能匹配有问题,利用正则表达式?
20 |  *
21 |  * 
22 | */ 23 | public class DeleteWhitespace { 24 | 25 | public static void main(String[] args) { 26 | String s = "a b d c"; 27 | s = s.replaceAll(" ",""); 28 | System.out.println(s); 29 | 30 | String s2 = "a b d c"; 31 | s2 = deleteWhitespace(s2); 32 | System.out.println(s2); 33 | 34 | } 35 | 36 | /**StringUtils.deleteWhitespace 的方法*/ 37 | public static String deleteWhitespace(String str) { 38 | if (isEmpty(str)) { 39 | return str; 40 | } else { 41 | int sz = str.length(); 42 | char[] chs = new char[sz]; 43 | int count = 0; 44 | 45 | for(int i = 0; i < sz; ++i) { 46 | if (!Character.isWhitespace(str.charAt(i))) { 47 | chs[count++] = str.charAt(i); 48 | } 49 | } 50 | 51 | if (count == sz) { 52 | return str; 53 | } else { 54 | return new String(chs, 0, count); 55 | } 56 | } 57 | } 58 | 59 | public static boolean isEmpty(CharSequence cs) { 60 | return cs == null || cs.length() == 0; 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/coding/interviews/FibonacciSolutionExample01.java: -------------------------------------------------------------------------------- 1 | package space.mamba.coding.interviews; 2 | 3 | /** 4 | * @author pankui 5 | * @date 2019-01-21 6 | *
 7 |  *
 8 |  * 
9 | */ 10 | public class FibonacciSolutionExample01 { 11 | 12 | static long fibonacciSolution1(int n) { 13 | if (n <= 0) { 14 | return 0; 15 | } 16 | 17 | if (n == 1) { 18 | return 1; 19 | } 20 | return fibonacciSolution1(n - 1) + fibonacciSolution1(n - 2); 21 | } 22 | 23 | public static void main(String[] args) { 24 | System.out.println(fibonacciSolution1(0)); 25 | System.out.println(fibonacciSolution1(1)); 26 | System.out.println(fibonacciSolution1(2)); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/coding/interviews/No14_GetLeastNumbersSolutionExample01.java: -------------------------------------------------------------------------------- 1 | package space.mamba.coding.interviews; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Arrays; 5 | import java.util.List; 6 | 7 | /** 8 | * @author pankui 9 | * @date 2019-04-03 10 | *
11 |  *      题目:输入n个整数,找出其中最小的k个数。例如输入4、5、1、6、2、7、3、8这8个数字,则最小的4个数字是1、2、3、4。
12 |  * 
13 | */ 14 | public class No14_GetLeastNumbersSolutionExample01 { 15 | 16 | 17 | public static void main(String[] args) { 18 | 19 | int[] arr = {5, 6, 4, 8, 6, 1, 9}; 20 | List list = GetLeastNumbers_Solution(arr, 3); 21 | System.out.println(list); 22 | 23 | System.out.println("#### "); 24 | } 25 | 26 | /** 27 | * 28 | * @param input 29 | * @param k 30 | * @return 31 | */ 32 | public static ArrayList GetLeastNumbers_Solution(int[] input, int k) { 33 | ArrayList result = new ArrayList<>(); 34 | if (input == null || k <= 0 || k > input.length) { 35 | return result; 36 | } 37 | //做排序 38 | Arrays.sort(input); 39 | for (int i = 0; i < k; i++) { 40 | result.add(input[i]); 41 | } 42 | return result; 43 | } 44 | 45 | 46 | } 47 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/coding/interviews/No14_ReorderOddEven.java: -------------------------------------------------------------------------------- 1 | package space.mamba.coding.interviews; 2 | 3 | /** 4 | * @author pankui 5 | * @date 2019-04-06 6 | *
 7 |  *      调整数组顺序使奇数位于偶数前面
 8 |  * 
9 | */ 10 | public class No14_ReorderOddEven { 11 | 12 | public static void main(String[] args) { 13 | 14 | // int[] array = {1, 1,2, 3, 4, 5, 6, 7}; 15 | int[] array = {1, 1, 3, 5, 6, 7}; 16 | int[] arr = reorderOdd(array); 17 | for (int i = 0; i < arr.length; i++) { 18 | System.out.print(arr[i] + " "); 19 | } 20 | } 21 | 22 | public static int[] reorderOdd(int[] data) { 23 | 24 | if (data == null || data.length < 2) { 25 | return data; 26 | } 27 | 28 | int left = 0; 29 | int right = data.length - 1; 30 | while (left < right) { 31 | //摸2 不等于就自增,否则就交换 32 | while (left < right && !isEven(data[left])) { 33 | left++; 34 | } 35 | while (left < right && isEven(data[right])) { 36 | right--; 37 | } 38 | 39 | if (left < right) { 40 | int temp = data[left]; 41 | data[left] = data[right]; 42 | data[right] = temp; 43 | } 44 | 45 | } 46 | return data; 47 | } 48 | 49 | /** 50 | * 偶数返回true 51 | */ 52 | public static boolean isEven(int n) { 53 | return (n & 1) == 0; 54 | } 55 | } 56 | 57 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/coding/interviews/No15_FindList_Last_K_Node.java: -------------------------------------------------------------------------------- 1 | package space.mamba.coding.interviews; 2 | 3 | /** 4 | * @author pankui 5 | * @date 2019-04-07 6 | *
 7 |  *      找链表中倒数第K个节点
 8 |  *
 9 |  *
10 |  *      用两个指针,第一个指针先走k-1步,然后两个指针一起走,
11 |  *      当第一个指针走到尾节点的时候。第二个指针指向的就是倒数第k个节点。
12 |  *
13 |  * 
14 | */ 15 | public class No15_FindList_Last_K_Node { 16 | 17 | public static void main(String[] args) { 18 | ListNode ln1 = ListNode.initData(); 19 | 20 | ListNode kListNode = findListNode(ln1, 3); 21 | 22 | ListNode.printListNode(ln1); 23 | 24 | System.out.println(kListNode.data); 25 | 26 | } 27 | 28 | //查找链表中倒数第k个结点 29 | 30 | public static ListNode findListNode(ListNode head, int k) { 31 | 32 | 33 | // 判断链表是否为空以及k是否为小于0的数 34 | if (head == null || k < 0) { // 链表不能为空,查找的倒数第k个结点k不能小于0 35 | return null; 36 | } 37 | // 开始时声明两个结点使其都指向头结点 38 | ListNode aNode = head; 39 | ListNode bNode = head; 40 | // 使aNode达到第k个结点 41 | for (int i = 0; i < k - 1; i++) { 42 | if (aNode.next != null) { 43 | aNode = aNode.next; 44 | } else { 45 | return null; // 链表太短,打不到k个结点 46 | } 47 | } 48 | while (aNode.next != null) { 49 | aNode = aNode.next; 50 | bNode = bNode.next; 51 | } 52 | return bNode; // bNode即为倒数第k个结点 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/coding/interviews/No21_StackMin.java: -------------------------------------------------------------------------------- 1 | package space.mamba.coding.interviews; 2 | 3 | import java.util.Stack; 4 | 5 | /** 6 | * @author pankui 7 | * @date 2019-04-07 8 | *
 9 |  *       包含min函数的栈
10 |  * 
11 | */ 12 | public class No21_StackMin { 13 | 14 | public static void main(String[] args) { 15 | 16 | StackSolution stackSolution = new StackSolution(); 17 | stackSolution.push(3); 18 | stackSolution.push(4); 19 | stackSolution.push(1); 20 | 21 | System.out.println(stackSolution.min()); 22 | 23 | } 24 | 25 | } 26 | 27 | class StackSolution { 28 | 29 | Stack stack = new Stack(); 30 | Stack min = new Stack(); 31 | 32 | public void push(int node) { 33 | 34 | stack.push(node); 35 | if (min.isEmpty() || node <= min.peek()) { 36 | min.push(node); 37 | } else { 38 | min.push(min.peek()); 39 | } 40 | } 41 | 42 | public void pop() { 43 | stack.pop(); 44 | min.pop(); 45 | } 46 | 47 | public int top() { 48 | return stack.peek(); 49 | } 50 | 51 | public int min() { 52 | return min.peek(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/coding/interviews/No23_PrintTreeFromTopToBottom.java: -------------------------------------------------------------------------------- 1 | package space.mamba.coding.interviews; 2 | 3 | import java.util.LinkedList; 4 | import java.util.Queue; 5 | 6 | /** 7 | * @author pankui 8 | * @date 2019-04-09 9 | *
10 |  *      层序遍历二叉树(从上到下打印二叉树)
11 |  *
12 |  *
13 |  *      运行结果:
14 |  *          1   2   3   4   5   6   7
15 |  * 
16 | */ 17 | public class No23_PrintTreeFromTopToBottom { 18 | 19 | public static void main(String[] args) { 20 | // 1 21 | // / \ 22 | // 2 3 23 | // / \ / \ 24 | // 4 5 6 7 25 | TreeNode root = TreeNode.initTreeNode(); 26 | printFromTopToBottom(root); 27 | } 28 | 29 | public static void printFromTopToBottom(TreeNode root) { 30 | if (root == null) { 31 | return; 32 | } 33 | 34 | //使用一个队列,进行广度优先遍历即可 35 | Queue queue = new LinkedList<>(); 36 | queue.offer(root); 37 | TreeNode temp; 38 | while (!queue.isEmpty()) { 39 | //弹出 40 | temp = queue.poll(); 41 | // 输出队首元素的值 42 | System.out.print(temp.val); 43 | System.out.print('\t'); 44 | // 如果左子结点不为空,则左子结点入队 45 | if (temp.left != null) { 46 | queue.offer(temp.left); 47 | } 48 | // 如果右子结点不为空,则左子结点入队 49 | if (temp.right != null) { 50 | queue.offer(temp.right); 51 | } 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/coding/interviews/No23_printTreeInLine.java: -------------------------------------------------------------------------------- 1 | package space.mamba.coding.interviews; 2 | 3 | import java.util.LinkedList; 4 | import java.util.Queue; 5 | 6 | /** 7 | * @author pankui 8 | * @date 2019-04-09 9 | *
10 |  *
11 |  * 
12 | */ 13 | public class No23_printTreeInLine { 14 | 15 | /** 16 | * Created by ryder on 2017/7/18. 17 | * 分行从上到下打印二叉树 18 | */ 19 | public static void printTreeInLine(TreeNode root) { 20 | if (root == null) { 21 | return; 22 | } 23 | Queue queue = new LinkedList<>(); 24 | queue.offer(root); 25 | TreeNode temp; 26 | while (!queue.isEmpty()) { 27 | for (int size = queue.size(); size > 0; size--) { 28 | temp = queue.poll(); 29 | System.out.print(temp.val); 30 | System.out.print("\t"); 31 | if (temp.left != null) { 32 | queue.offer(temp.left); 33 | } 34 | if (temp.right != null) { 35 | queue.offer(temp.right); 36 | } 37 | } 38 | System.out.println(); 39 | } 40 | } 41 | 42 | public static void main(String[] args) { 43 | // 1 44 | // / \ 45 | // 2 3 46 | // / \ / \ 47 | // 4 5 6 7 48 | TreeNode root = TreeNode.initTreeNode(); 49 | printTreeInLine(root); 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/coding/interviews/No35_FirstFindOnceChar.java: -------------------------------------------------------------------------------- 1 | package space.mamba.coding.interviews; 2 | 3 | import java.util.Map; 4 | import java.util.TreeMap; 5 | 6 | /** 7 | * @author mamba 8 | * @date 2020/6/26 15:23 9 | *

10 | * 第一个出现一次的字符 11 | */ 12 | public class No35_FirstFindOnceChar { 13 | 14 | public static void main(String[] args) { 15 | String str = "abcdefghjklhfeagjlascbdk"; 16 | System.out.println(getFirstFindOnceChar(str.toCharArray())); 17 | System.out.println("-------"); 18 | System.out.println(firstNotRepeatingChar(str)); 19 | } 20 | 21 | private static char getFirstFindOnceChar(char[] chars) { 22 | Map map = new TreeMap<>(); 23 | 24 | for (char c : chars) { 25 | if (map.containsKey(c)) { 26 | map.put(c, map.get(c) + 1); 27 | } else { 28 | map.put(c, 1); 29 | } 30 | } 31 | for (Map.Entry entry : map.entrySet()) { 32 | if (map.get(entry.getKey()) == 1) { 33 | char c = entry.getKey(); 34 | return c; 35 | } 36 | } 37 | return 0; 38 | } 39 | 40 | private static char firstNotRepeatingChar(String str) { 41 | int len = str.length(); 42 | if (len <= 0) { 43 | return 0; 44 | } 45 | 46 | char[] s = str.toCharArray(); 47 | char[] charArray = new char[256]; 48 | 49 | for (int i = 0; i < len; i++) { 50 | // 保存出现的字符 51 | charArray[s[i]]++; 52 | } 53 | 54 | for (int i = 0; i < len; i++) { 55 | if (charArray[s[i]] == 1) { 56 | return s[i]; 57 | } 58 | } 59 | return 0; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/coding/interviews/No40_FindNumsAppearOnce.java: -------------------------------------------------------------------------------- 1 | package space.mamba.coding.interviews; 2 | 3 | import java.util.Arrays; 4 | 5 | /** 6 | * @author mamba 7 | * @date 2020/7/9 08:02 8 | *

9 | * 一个整型数组里除了两个数字之外,其他的数字都出现了两次。 10 | * 请写程序找出这两个只出现一次的数字。`要求时间复杂度是O(n),空间复杂度是O(1)`。 11 | *

12 | * 说明不能使用额外的空间来存 13 | */ 14 | public class No40_FindNumsAppearOnce { 15 | 16 | public static void main(String[] args) { 17 | int[] arr = {1, 2, 1, 2, 4, 3}; 18 | // findNumsAppearOnce(arr); 19 | System.out.println(Arrays.asList(findNumsAppearOnce(arr))); 20 | } 21 | 22 | private static int[] findNumsAppearOnce(int[] arr) { 23 | if (arr == null || arr.length == 0) { 24 | return null; 25 | } 26 | int xorNumber = arr[0]; 27 | for (int i = 0; i < arr.length; i++) { 28 | xorNumber ^= arr[i]; 29 | System.out.println(xorNumber); 30 | } 31 | System.out.println("--" + xorNumber); 32 | int onePosition = xorNumber & (-xorNumber); 33 | int ans1 = 0, ans2 = 0; 34 | for (int i = 0; i < arr.length; i++) { 35 | if ((arr[i] & onePosition) == onePosition) { 36 | ans1 ^= arr[i]; 37 | } else { 38 | ans2 ^= arr[i]; 39 | } 40 | } 41 | 42 | System.out.println("----"); 43 | System.out.println((ans1 ^ 0) + ", " + (ans2 ^ 0)); 44 | return new int[]{ans1 ^ 0, ans2 ^ 0}; 45 | 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/coding/interviews/No45_LastRemaining.java: -------------------------------------------------------------------------------- 1 | package space.mamba.coding.interviews; 2 | 3 | /** 4 | * @author mamba 5 | * @ 2020/7/26 6 | * 7 | * 圆圈中最后剩下的数(约瑟夫环问题) 8 | * 9 | */ 10 | public class No45_LastRemaining { 11 | 12 | 13 | public static void main(String[] args) { 14 | ListNode listNode = ListNode.initRing(); 15 | System.out.println(getLastRemaining(listNode, 3)); 16 | System.out.println("---------"); 17 | System.out.println(lastRemaining(7, 3)); 18 | } 19 | 20 | public static int getLastRemaining(ListNode firstNode,int m) { 21 | 22 | ListNode currNode = firstNode; 23 | while (currNode.next != currNode) { 24 | ListNode prev = null; 25 | for (int i = 0; i < m - 1; i++) { 26 | // 这里是不断让环断开,把不符合条件的连接起来 27 | prev = currNode; 28 | // currNode 就是要删除的点 29 | currNode = currNode.next; 30 | System.out.println(currNode.data +",prev="+prev.data); 31 | } 32 | System.out.println("=="); 33 | 34 | // ListNode.printListNode(currNode); 35 | 36 | prev.next = currNode.next; 37 | currNode = null; 38 | currNode = prev.next; // 让循环继续 39 | } 40 | return currNode.data; 41 | } 42 | 43 | static int lastRemaining(int n, int m) { 44 | int p = 0; 45 | for (int i = 2; i <= n; i++) { 46 | p = (p + m) % i; 47 | } 48 | return p + 1; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/coding/interviews/No46_SumSolution.java: -------------------------------------------------------------------------------- 1 | package space.mamba.coding.interviews; 2 | 3 | /** 4 | * @author mamba 5 | * @ 2020/7/24 6 | *

7 | * 求1+2+3+...+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。 8 | */ 9 | public class No46_SumSolution { 10 | 11 | 12 | public static void main(String[] args) { 13 | System.out.println(sumNums(3)); 14 | System.out.println(sumNums(5)); 15 | System.out.println(sumNums(10)); 16 | } 17 | 18 | private static int sumNums(int n) { 19 | 20 | if (n == 1) { 21 | return 1; 22 | } 23 | n += sumNums(n - 1); 24 | return n; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/coding/interviews/No47_Add.java: -------------------------------------------------------------------------------- 1 | package space.mamba.coding.interviews; 2 | 3 | import java.util.Arrays; 4 | 5 | /** 6 | * @author mamba 7 | * @ 2020/7/26 8 | * 9 | * 不用加减乘除做加法 10 | * 11 | * https://leetcode-cn.com/problems/bu-yong-jia-jian-cheng-chu-zuo-jia-fa-lcof/solution/mian-shi-ti-65-bu-yong-jia-jian-cheng-chu-zuo-ji-7/ 12 | * 13 | */ 14 | public class No47_Add { 15 | 16 | public static void main(String[] args) { 17 | System.out.println(add(1,7)); 18 | System.out.println(add(3,11)); 19 | System.out.println("--"); 20 | System.out.println(add2(3,11)); 21 | } 22 | 23 | /** 24 | * 不用加减乘除做加法 25 | * 26 | * 1、加法其实质为各位相加结果(不考虑进位)+ 进位值 27 | * 28 | * 2、各位相加结果(不考虑进位)等价于 加数二进制异或结果 29 | * 30 | * 进位值等价于加数按位与并向左移动一位 31 | * 32 | * 3、第一步和第二部反复迭代,最终没有进位,那么各位相加结果(不考虑进位)则是最终结果 33 | * */ 34 | private static int add(int a, int b) { 35 | while (b != 0) { 36 | int tmp = a; 37 | a = a ^ b; 38 | b = (tmp & b) << 1; 39 | } 40 | return a; 41 | } 42 | 43 | public static int sum(int...a){ 44 | return Arrays.stream(a).sum(); 45 | } 46 | public static int add2(int a, int b) { 47 | return sum(a,b); 48 | } 49 | 50 | 51 | } 52 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/coding/interviews/No48_FinallClass.java: -------------------------------------------------------------------------------- 1 | package space.mamba.coding.interviews; 2 | 3 | 4 | /** 5 | * @author mamba 6 | * @ 2020/7/26 7 | * 8 | * 不用加减乘除做加法 9 | */ 10 | public class No48_FinallClass { 11 | 12 | } 13 | 14 | // class DemoExample extends FinalDemo {} 15 | 16 | final class FinalDemo { 17 | } 18 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/coding/interviews/No49_StringToInteger.java: -------------------------------------------------------------------------------- 1 | package space.mamba.coding.interviews; 2 | 3 | 4 | /** 5 | * @author mamba 6 | * @ 2020/7/26 7 | *

8 | * 不用加减乘除做加法 9 | * @see No49_StringToIntegerTest 10 | */ 11 | public class No49_StringToInteger { 12 | 13 | 14 | public int strToInteger(String str) { 15 | if (str == null || str.trim().equals("")) { 16 | return 0; 17 | } 18 | //第一个字符可以是正号或者是负号 19 | int first = 1;//做符号位,1为+,2为- 20 | int index = 0;//防止出现123这种开始就不是符号位的数字 21 | char[] charArray = str.toCharArray(); 22 | if (charArray.length == 1) { 23 | return 0; 24 | } 25 | if (charArray[0] == '-') { 26 | //如果是负号且字符串长度不小于1,将符号位置-1 27 | first = 2; 28 | index++; 29 | } 30 | 31 | if (charArray[0] == '+') { 32 | //如果是符号为正号且字符串长度不小于1,将符号位置+1 33 | index++; 34 | } 35 | 36 | int result = 0; 37 | for (int i = index; i < charArray.length; i++) { 38 | if (charArray[i] < '0' || charArray[i] > '9') { 39 | //如果后面的不在0-9的话,说明不是数字 40 | return 0; 41 | } 42 | result = result * 10 + (int) (charArray[i] - '0');//-‘0’转换为数字 43 | //TODO 有越界的问题 44 | } 45 | 46 | if (first == 2) { 47 | return result * (-1); 48 | } 49 | return result; 50 | } 51 | } -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/coding/interviews/No52_Multiply.java: -------------------------------------------------------------------------------- 1 | package space.mamba.coding.interviews; 2 | 3 | 4 | import org.junit.jupiter.api.Assertions; 5 | 6 | import java.util.Arrays; 7 | 8 | /** 9 | * @author mamba 10 | * @ 2020/7/28 11 | */ 12 | public class No52_Multiply { 13 | 14 | public static void main(String[] args) { 15 | int[]arr1 = {1,2,3}; 16 | int[]arr2 = {1,2,3}; 17 | int[]arr = multiply(arr1,arr2); 18 | Assertions.assertEquals(arr[0],6); 19 | Assertions.assertEquals(arr[1],3); 20 | } 21 | 22 | private static int[] multiply(int[] array1, int[] array2) { 23 | int len1 = array1.length; 24 | int len2 = array2.length; 25 | 26 | if (len1 == len2 && len2 > 1) { 27 | array2[0] = 1; 28 | for (int i = 1; i < len1; i++) { 29 | array2[i] = array2[i - 1] * array1[i - 1]; 30 | } 31 | 32 | double tmp = 1; 33 | for (int i = len1 - 2; i >= 0; i--) { 34 | tmp *= array1[i + 1]; 35 | array2[i] *= tmp; 36 | } 37 | } 38 | 39 | System.out.println(Arrays.toString(array2)); 40 | return array2; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/coding/interviews/No54_isNumber.java: -------------------------------------------------------------------------------- 1 | package space.mamba.coding.interviews; 2 | 3 | /** 4 | * @author mamba 5 | * @ 2020/7/29 6 | */ 7 | public class No54_isNumber { 8 | 9 | public static void main(String[] args) { 10 | 11 | } 12 | 13 | public static boolean isNumber(String s) { 14 | if(s == null || s.length() == 0){ 15 | return false; 16 | } 17 | //标记是否遇到相应情况 18 | boolean numSeen = false; 19 | boolean dotSeen = false; 20 | boolean eSeen = false; 21 | char[] str = s.trim().toCharArray(); 22 | for(int i = 0;i < str.length; i++){ 23 | if(str[i] >= '0' && str[i] <= '9'){ 24 | numSeen = true; 25 | }else if(str[i] == '.'){ 26 | //.之前不能出现.或者e 27 | if(dotSeen || eSeen){ 28 | return false; 29 | } 30 | dotSeen = true; 31 | }else if(str[i] == 'e' || str[i] == 'E'){ 32 | //e之前不能出现e,必须出现数 33 | if(eSeen || !numSeen){ 34 | return false; 35 | } 36 | eSeen = true; 37 | numSeen = false;//重置numSeen,排除123e或者123e+的情况,确保e之后也出现数 38 | }else if(str[i] == '-' || str[i] == '+'){ 39 | //+-出现在0位置或者e/E的后面第一个位置才是合法的 40 | if(i != 0 && str[i-1] != 'e' && str[i-1] != 'E'){ 41 | return false; 42 | } 43 | }else{//其他不合法字符 44 | return false; 45 | } 46 | } 47 | return numSeen; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/coding/interviews/No56_DetectCycle.java: -------------------------------------------------------------------------------- 1 | package space.mamba.coding.interviews; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | 6 | /** 7 | * @author mamba 8 | * @date 2021/2/26 08:18 9 | */ 10 | public class No56_DetectCycle { 11 | 12 | public static void main(String[] args) { 13 | No56_DetectCycle obj = new No56_DetectCycle(); 14 | ListNode head = ListNode.initRing(); 15 | ListNode result = obj.detectCycle(head); 16 | //由于是 环,不能打印 result 17 | System.out.println(result.data); 18 | } 19 | 20 | ListNode detectCycle(ListNode head) { 21 | ListNode pos = head; 22 | Set visited = new HashSet<>(); 23 | while (pos!=null) { 24 | if (visited.contains(pos)) { 25 | return pos; 26 | }else { 27 | visited.add(pos); 28 | } 29 | pos = pos.next; 30 | } 31 | return null; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/coding/interviews/No61PrintBinaryTree_1.java: -------------------------------------------------------------------------------- 1 | package space.mamba.coding.interviews; 2 | 3 | import java.util.ArrayList; 4 | import java.util.LinkedList; 5 | import java.util.List; 6 | import java.util.Queue; 7 | 8 | /** 9 | * @author mamba 10 | * @date 2021/2/19 08:15 11 | *

12 | * 解题思路: 13 | * 题目要求的二叉树的 从上至下 打印(即按层打印),又称为二叉树的 广度优先搜索(BFS)。 14 | * BFS 通常借助 队列 的先入先出特性来实现。 15 | */ 16 | public class No61PrintBinaryTree_1 { 17 | 18 | public static void main(String[] args) { 19 | No61PrintBinaryTree_1 obj = new No61PrintBinaryTree_1(); 20 | TreeNode root = TreeNode.initTreeNode(); 21 | int[] result = obj.levelOrder(root); 22 | for (int i : result) { 23 | System.out.print(i + " "); 24 | } 25 | } 26 | 27 | public int[] levelOrder(TreeNode root) { 28 | if (root == null) { 29 | return new int[0]; 30 | } 31 | Queue queue = new LinkedList<>() {{ 32 | add(root); 33 | }}; 34 | List ans = new ArrayList<>(); 35 | while (!queue.isEmpty()) { 36 | TreeNode treeNode = queue.poll(); 37 | ans.add(treeNode.val); 38 | if (treeNode.left != null) { 39 | queue.add(treeNode.left); 40 | } 41 | if (treeNode.right != null) { 42 | queue.add(treeNode.right); 43 | } 44 | } 45 | int[] res = new int[ans.size()]; 46 | for (int i = 0; i < ans.size(); i++) { 47 | res[i] = ans.get(i); 48 | } 49 | return res; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/coding/interviews/No8_RevertArray.java: -------------------------------------------------------------------------------- 1 | package space.mamba.coding.interviews; 2 | 3 | /** 4 | * @author mamba 5 | * @date 2021/3/3 14:22 6 | *

7 | * 求旋转数组的最小数字 8 | */ 9 | public class No8_RevertArray { 10 | 11 | public static void main(String[] args) { 12 | No8_RevertArray obj = new No8_RevertArray(); 13 | int[] arr = {3, 4, 5, 1,2, 3}; 14 | int result = obj.minArray(arr); 15 | System.out.println(result); 16 | 17 | } 18 | 19 | /** 20 | * 使用二分查找 21 | */ 22 | public int minArray(int[] numbers) { 23 | int low = 0; 24 | int high = numbers.length - 1; 25 | while (low < high) { 26 | // 两个 int 相加可以能溢出 27 | int mid = low + (high - low) / 2; 28 | if (numbers[mid] > numbers[high]) { 29 | low = mid + 1; 30 | } else if (numbers[mid] < numbers[high]) { 31 | high = mid; 32 | } else { 33 | high--; 34 | } 35 | } 36 | return numbers[low]; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/interview/ArrayFindSum.java: -------------------------------------------------------------------------------- 1 | package space.mamba.interview; 2 | 3 | /** 4 | * @author pankui 5 | * @date 2018-12-23 6 | *

 7 |  *
 8 |  *      给出一个排序好的数组和一个数,求数组中连续元素的和等于所给数
 9 |  *
10 |  *      给出一个排序好的数组和一个数,求数组中连续元素的和等于所给数的子数组
11 |  * 
12 | */ 13 | public class ArrayFindSum { 14 | 15 | public static void main(String[] args) { 16 | 17 | 18 | int[] num = {1, 2, 2, 3, 4, 5, 6, 7, 8, 9}; 19 | int sum = 7; 20 | findSum(num, sum); 21 | } 22 | 23 | public static void findSum(int[] num, int sum) { 24 | int left = 0; 25 | int right = 0; 26 | 27 | for (int i = 0; i < num.length; i++) { 28 | int curSum = 0; 29 | left = i; 30 | right = i; 31 | while (curSum < sum) { 32 | curSum += num[right++]; 33 | } 34 | if (curSum == sum) { 35 | for (int j = left; j < right; j++) { 36 | System.out.print(num[j] + " "); 37 | } 38 | System.out.println(); 39 | } 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/leetcode/TwoSum.java: -------------------------------------------------------------------------------- 1 | package space.mamba.leetcode; 2 | 3 | import java.util.HashMap; 4 | import java.util.Map; 5 | 6 | /** 7 | * @author pankui 8 | * @date 09/05/2018 9 | *
10 |  *
11 |  *
12 |  * Given an array of integers, return indices of the two numbers such that they add up to a specific target.
13 |  *
14 |  * You may assume that each input would have exactly one solution, and you may not use the same element twice.
15 |  *
16 |  * Example:
17 |  *
18 |  * Given nums = [2, 7, 11, 15], target = 9,
19 |  *
20 |  * Because nums[0] + nums[1] = 2 + 7 = 9,
21 |  * return [0, 1].
22 |  *
23 |  * test case
24 |  * @see TwoSumTest
25 |  *
26 |  * 
27 | */ 28 | public class TwoSum { 29 | 30 | /** 31 | * test case 32 | * @see space.mamba.leetcode.TwoSumTest 33 | */ 34 | int[] twoSum(int[] nums, int target) { 35 | Map map = new HashMap<>(); 36 | for (int i = 0; i < nums.length; i++) { 37 | int complement = target - nums[i]; 38 | if (map.containsKey(complement)) { 39 | return new int[]{map.get(complement), i}; 40 | } 41 | map.put(nums[i], i); 42 | } 43 | throw new IllegalArgumentException("No two sum solution"); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/leetcode/algorithms/No07_ReverseInteger.java: -------------------------------------------------------------------------------- 1 | package space.mamba.leetcode.algorithms; 2 | 3 | /** 4 | * @author pankui 5 | * @date 2019-02-12 6 | *
 7 |  *      翻转一个long类型数字。例如输入123456L,输出654321L。
 8 |  *
 9 |  *      https://leetcode.com/problems/reverse-integer/
10 |  * 
11 | */ 12 | public class No07_ReverseInteger { 13 | 14 | public static void main(String[] args) { 15 | System.out.println(new No07_ReverseInteger().reverse(12345)); 16 | System.out.println(new No07_ReverseInteger().reverse(67890)); 17 | } 18 | 19 | public int reverse(int x) { 20 | long xlong = 0; 21 | 22 | while (x != 0) { 23 | 24 | xlong = xlong * 10 + x % 10; 25 | 26 | if (xlong > Integer.MAX_VALUE || xlong < Integer.MIN_VALUE) { 27 | return 0; 28 | } 29 | 30 | x = x / 10; 31 | } 32 | 33 | return (int) xlong; 34 | 35 | } 36 | 37 | /** 38 | * 投机取巧,哈哈哈哈 39 | * */ 40 | public int reverse_2(int x) { 41 | try { 42 | if (x < 0) { 43 | StringBuffer stringBuffer = new StringBuffer(String.valueOf(x).substring(1)); 44 | stringBuffer.reverse(); 45 | int i = -Integer.parseInt(stringBuffer.toString()); 46 | return i; 47 | } else { 48 | StringBuffer stringBuffer = new StringBuffer(String.valueOf(x)); 49 | stringBuffer.reverse(); 50 | return Integer.parseInt(stringBuffer.toString()); 51 | } 52 | } catch (Exception e) { 53 | //e.printStackTrace(); 54 | return 0; 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/leetcode/algorithms/No100_Same_Tree.java: -------------------------------------------------------------------------------- 1 | package space.mamba.leetcode.algorithms; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashSet; 5 | import java.util.List; 6 | import java.util.Set; 7 | 8 | /** 9 | * @author mamba 10 | * @date 2020/11/3 08:15 11 | */ 12 | public class No100_Same_Tree { 13 | 14 | public static void main(String[] args) { 15 | 16 | TreeNode p = new TreeNode(); 17 | TreeNode q = new TreeNode(); 18 | boolean result = isSameTree(p.getTestExampleData(), q.getTestExampleData()); 19 | boolean result2 = isSameTree(p.getTestExampleData(), new TreeNode()); 20 | 21 | System.out.println(result); 22 | System.out.println(result2); 23 | 24 | 25 | } 26 | public static boolean isSameTree(TreeNode p, TreeNode q) { 27 | 28 | if (p == null && q == null) { 29 | return true; 30 | } 31 | 32 | if (p == null || q == null) { 33 | return false; 34 | } 35 | 36 | List leftSet = new ArrayList<>(); 37 | while (p.left != null) { 38 | leftSet.add(p.val); 39 | p = p.left; 40 | } 41 | 42 | while (p.right != null) { 43 | leftSet.add(p.val); 44 | p = p.right; 45 | } 46 | 47 | List rightSet = new ArrayList<>(); 48 | while (q.left != null) { 49 | rightSet.add(q.val); 50 | q = q.left; 51 | } 52 | 53 | while (q.right != null) { 54 | rightSet.add(q.val); 55 | q = q.right; 56 | } 57 | 58 | return leftSet.equals(rightSet); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/leetcode/algorithms/No104_Maximum_Depth_of_Binary_Tree.java: -------------------------------------------------------------------------------- 1 | package space.mamba.leetcode.algorithms; 2 | 3 | /** 4 | * @author byte mamba 5 | * @date 2019/12/24 6 | *
 7 |  *
 8 |  *     BFS
 9 |  *     DFS
10 |  *
11 |  *     遍历最后,判断最大的
12 |  *
13 |  *
14 |  *     分而治之
15 |  *     分而治之
16 |  *
17 |  * 
18 | */ 19 | public class No104_Maximum_Depth_of_Binary_Tree { 20 | 21 | public int maxDepth(TreeNode root) { 22 | 23 | 24 | return root == null ? 0 : 1 + Math.max(maxDepth(root.left), maxDepth(root.right)); 25 | } 26 | 27 | public static void main(String[] args) { 28 | No104_Maximum_Depth_of_Binary_Tree obj = new No104_Maximum_Depth_of_Binary_Tree(); 29 | TreeNode treeNode = new TreeNode(); 30 | TreeNode data = treeNode.getTestExampleData(); 31 | System.out.println(data); 32 | int result = obj.maxDepth(data); 33 | System.out.println("max:" + result); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/leetcode/algorithms/No1108_DefangingIPAddress.java: -------------------------------------------------------------------------------- 1 | package space.mamba.leetcode.algorithms; 2 | 3 | /** 4 | * @author byte mamba 5 | * @date 2019/11/24 6 | *
 7 |  *
 8 |  *      https://leetcode.com/problems/defanging-an-ip-address/
 9 |  *      1108. Defanging an IP Address
10 |  * 
11 | */ 12 | public class No1108_DefangingIPAddress { 13 | 14 | public static void main(String[] args) { 15 | 16 | No1108_DefangingIPAddress obj = new No1108_DefangingIPAddress(); 17 | String result = obj.defangIPaddr("1.1.1.1"); 18 | System.out.println(result); 19 | 20 | result = obj.defangIPaddr("255.100.50.0"); 21 | System.out.println(result); 22 | } 23 | 24 | public String defangIPaddr(String address) { 25 | 26 | StringBuilder stringBuilder = new StringBuilder(); 27 | String[] strArray = address.split("\\."); 28 | for (int i = 0; i < strArray.length; i++) { 29 | stringBuilder.append(strArray[i]); 30 | if (i < strArray.length - 1) { 31 | stringBuilder.append("[.]"); 32 | } 33 | } 34 | return stringBuilder.toString(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/leetcode/algorithms/No111_Minimum_Depth_of_Binary_Tree.java: -------------------------------------------------------------------------------- 1 | package space.mamba.leetcode.algorithms; 2 | 3 | import javax.print.DocFlavor; 4 | 5 | /** 6 | * @author byte mamba 7 | * @date 2019/12/24 8 | *
 9 |  *      需要判断没有左子树或者右子树就完成了
10 |  *
11 |  *      BFS
12 |  *
13 |  *      DFS
14 |  *
15 |  *      分而治之
16 |  *
17 |  *
18 |  *      TODO: 如果没有左子树 或者右子树 那么根节点不就是最小的深度了吗?不太理解这里还判断这些
19 |  * 
20 | */ 21 | public class No111_Minimum_Depth_of_Binary_Tree { 22 | 23 | public int minDepth(TreeNode root) { 24 | 25 | if (root == null) { 26 | return 0; 27 | } 28 | 29 | //没有左子树 30 | if (root.left == null) { 31 | return 1 + minDepth(root.right); 32 | } 33 | 34 | //没有右子树 35 | if (root.right == null) { 36 | return 1 + minDepth(root.left); 37 | } 38 | 39 | // 分而治之 40 | int minLeftDepth = minDepth(root.left); 41 | 42 | int minRightDepth = minDepth(root.right); 43 | 44 | return 1 + Math.min(minLeftDepth, minRightDepth); 45 | 46 | } 47 | 48 | public static void main(String[] args) { 49 | No111_Minimum_Depth_of_Binary_Tree obj = new No111_Minimum_Depth_of_Binary_Tree(); 50 | TreeNode treeNode = new TreeNode(); 51 | TreeNode data = treeNode.getTestExampleData(); 52 | 53 | int result = obj.minDepth(data); 54 | System.out.println("min:" + result); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/leetcode/algorithms/No119_Pascal_s_Triangle_I_I.java: -------------------------------------------------------------------------------- 1 | package space.mamba.leetcode.algorithms; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | 6 | /** 7 | * @author byte mamba 8 | * @date 2020/1/6 9 | *
10 |  *      https://leetcode.com/problems/pascals-triangle-ii/
11 |  *
12 |  *     119. Pascal's Triangle II
13 |  *
14 |  *      Given a non-negative index k where k ≤ 33, return the kth index row of the Pascal's triangle.
15 |  *
16 |  * Note that the row index starts from 0.
17 |  *
18 |  *
19 |  *
20 |  * Could you optimize your algorithm to use only O(k) extra space?【重点】 O(n) 空间复杂度
21 |  *
22 |  * 参考 118
23 |  *
24 |  *
25 |  * [C(k,0), C(k,1), ..., C(k, k-1), C(k, k)]
26 |  *
27 |  * C[k,i] = C[k,i-1]*(k-i+1)/i
28 |  *
29 |  * 
30 | */ 31 | public class No119_Pascal_s_Triangle_I_I { 32 | 33 | public static void main(String[] args) { 34 | No119_Pascal_s_Triangle_I_I obj = new No119_Pascal_s_Triangle_I_I(); 35 | // System.out.println(obj.generate(3)); 36 | System.out.println(obj.getRow(3)); 37 | } 38 | public List getRow(int rowIndex) { 39 | Integer[] rowList = new Integer[rowIndex+1]; 40 | rowList[0] = 1; 41 | for(int i=1; i 7 | * 8 | * 盛最多水的容器 9 | * 10 | * https://leetcode-cn.com/problems/container-with-most-water/ 11 | * 12 | * 13 | */ 14 | public class No11MaxArea { 15 | 16 | public static void main(String[] args) { 17 | No11MaxArea obj = new No11MaxArea(); 18 | int[] arr = {1, 8, 6, 2, 5, 4, 8, 3, 7}; 19 | System.out.println(obj.maxArea(arr)); 20 | 21 | } 22 | //双指针 23 | public int maxArea(int[] height) { 24 | if (height.length < 2) { 25 | return 0; 26 | } 27 | int left = 0; 28 | int right = height.length - 1; 29 | int max = 0; 30 | // [1, 8, 6, 2, 5, 4, 8, 3, 7] 31 | //在初始时,左右指针分别指向数组的左右两端,它们可以容纳的水量为 min(1, 7) * 8 = 8min(1,7)∗8=8 32 | //TODO 注意:x轴 相隔是1 个单位, 总共八个单位 33 | while (left < right) { 34 | //取较小的,和相隔单位 获取面积 35 | int currentArea = Math.min(height[left], height[right]) * (right - left); 36 | max = Math.max(currentArea, max); 37 | if (height[left] < height[right]) { 38 | left++; 39 | } else { 40 | right--; 41 | } 42 | } 43 | return max; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/leetcode/algorithms/No136_SingleNumber.java: -------------------------------------------------------------------------------- 1 | package space.mamba.leetcode.algorithms; 2 | 3 | /** 4 | * @author pankui 5 | * @date 2019-03-09 6 | *
 7 |  *      https://leetcode.com/problems/single-number/
 8 |  *
 9 |  *      Given a non-empty array of integers, every element appears twice except for one.
10 |  *      Find that single one.
11 |  *
12 |  * Note:
13 |  *
14 |  *      Your algorithm should have a linear runtime complexity.
15 |  *      Could you implement it without using extra memory?
16 |  *
17 |  *
18 |  *          很好解决,通过异或运算,我们可以把所有出现两次的元素消除 a^a = 0;
19 |  *          最后就只剩下那个出现一次的元素了 0^b = b。
20 |  *
21 |  *          异或运算:如果a、b两个值不相同,则异或结果为1。如果a、b两个值相同,异或结果为0。
22 |  *
23 |  *          result ^= i;
24 |  *           等价下面
25 |  *          result = result ^ i;
26 |  * 
27 | */ 28 | public class No136_SingleNumber { 29 | 30 | public static void main(String[] args) { 31 | No136_SingleNumber obj = new No136_SingleNumber(); 32 | 33 | int[] nums = {2,2,1}; 34 | 35 | //int[] nums = {3, 1, 2, 1, 2}; 36 | 37 | System.out.println(obj.singleNumber(nums)); 38 | } 39 | 40 | public int singleNumber(int[] nums) { 41 | 42 | int result = 0; 43 | for(int i : nums) { 44 | result ^= i; 45 | System.out.println("result="+result); 46 | } 47 | return result; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/leetcode/algorithms/No141_Linked_List_Cycle.java: -------------------------------------------------------------------------------- 1 | package space.mamba.leetcode.algorithms; 2 | 3 | import java.util.HashSet; 4 | import java.util.Set; 5 | 6 | /** 7 | * @author mamba 8 | * @date 2020/10/26 08:19 9 | */ 10 | public class No141_Linked_List_Cycle { 11 | 12 | 13 | public boolean hasCycle(ListNode head) { 14 | 15 | if (head == null || head.next == null || head.next.next == null) { 16 | return false; 17 | } 18 | Set set = new HashSet<>(); 19 | 20 | while(head != null) { 21 | if (set.contains(head)) { 22 | return true; 23 | } 24 | set.add(head); 25 | head = head.next; 26 | } 27 | 28 | return false; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/leetcode/algorithms/No155_MinStack.java: -------------------------------------------------------------------------------- 1 | package space.mamba.leetcode.algorithms; 2 | 3 | import java.util.Stack; 4 | 5 | /** 6 | * @author mamba 7 | * @date 2021/1/28 08:00 8 | * https://leetcode.com/problems/min-stack/ 9 | */ 10 | public class No155_MinStack { 11 | 12 | public static void main(String[] args) { 13 | MinStack minStack = new MinStack(); 14 | minStack.push(-2); 15 | minStack.push(0); 16 | minStack.push(-3); 17 | System.out.println(minStack.getMin()); 18 | minStack.pop(); 19 | System.out.println(minStack.top()); 20 | System.out.println(minStack.getMin()); 21 | } 22 | 23 | } 24 | 25 | class MinStack { 26 | 27 | private Stack stack = new Stack<>(); 28 | 29 | private Stack minStack = new Stack<>(); 30 | 31 | /** initialize your data structure here. */ 32 | public MinStack() { 33 | 34 | } 35 | 36 | public void push(int x) { 37 | stack.push(x); 38 | if (minStack.empty() || minStack.peek() >= x) { 39 | minStack.push(x); 40 | } 41 | } 42 | 43 | public void pop() { 44 | int x = stack.pop(); 45 | if (minStack.peek() == x){ 46 | minStack.pop(); 47 | } 48 | } 49 | 50 | public int top() { 51 | return stack.peek(); 52 | } 53 | 54 | public int getMin() { 55 | return minStack.peek(); 56 | } 57 | } 58 | 59 | /** 60 | * Your MinStack object will be instantiated and called as such: 61 | * MinStack obj = new MinStack(); 62 | * obj.push(x); 63 | * obj.pop(); 64 | * int param_3 = obj.top(); 65 | * int param_4 = obj.getMin(); 66 | */ -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/leetcode/algorithms/No169_Majority_Element.java: -------------------------------------------------------------------------------- 1 | package space.mamba.leetcode.algorithms; 2 | 3 | /** 4 | * @author byte mamba 5 | * @date 2019/12/9 6 | *
 7 |  *
 8 |  *
 9 |  *
10 |  *  因为一定存在。所以只需要判断出现次数最多的
11 |  *
12 |  * 
13 | */ 14 | public class No169_Majority_Element { 15 | 16 | public int majorityElement(int[] nums) { 17 | int count = 0; 18 | int major = nums[0]; 19 | for (int i : nums) { 20 | if (count == 0) { 21 | major = i; 22 | count++; 23 | // 24 | } else if (i == major) { 25 | count++; 26 | } else { 27 | count--; 28 | } 29 | } 30 | return major; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/leetcode/algorithms/No20Valid_Parentheses_Array.java: -------------------------------------------------------------------------------- 1 | package space.mamba.leetcode.algorithms; 2 | 3 | /** 4 | * @author pankui 5 | * @date 2019/11/21 6 | *
 7 |  *   数组的方式判断,这个执行时间比栈快
 8 |  * 
9 | */ 10 | public class No20Valid_Parentheses_Array { 11 | 12 | 13 | public boolean isValid(String s) { 14 | 15 | if (s == null) { 16 | return true; 17 | } 18 | 19 | char[] ch = new char[s.length()]; 20 | 21 | char[] c = s.toCharArray(); 22 | 23 | int j = 0; 24 | boolean flag = false; 25 | 26 | if (c.length % 2 != 0) { 27 | return flag; 28 | } 29 | 30 | for (int i = 0; i < c.length; i++) { 31 | 32 | if (c[i] == '{' || c[i] == '(' || c[i] == '[') { 33 | 34 | ch[j] = c[i]; 35 | j++; 36 | 37 | } else if (c[i] == '}' && (j - 1) >= 0 && ch[j - 1] == '{') { 38 | 39 | j--; 40 | flag = true; 41 | } else if (c[i] == ']' && (j - 1) >= 0 && ch[j - 1] == '[') { 42 | 43 | j--; 44 | flag = true; 45 | 46 | } else if (c[i] == ')' && (j - 1) >= 0 && ch[j - 1] == '(') { 47 | 48 | j--; 49 | flag = true; 50 | } else { 51 | flag = false; 52 | break; 53 | } 54 | } 55 | 56 | 57 | return flag; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/leetcode/algorithms/No225_Implement_Stack_using_Queues.java: -------------------------------------------------------------------------------- 1 | package space.mamba.leetcode.algorithms; 2 | 3 | import java.util.LinkedList; 4 | import java.util.Queue; 5 | 6 | /** 7 | * @author mamba 8 | * @date 2021/1/31 22:21 9 | * https://leetcode.com/problems/implement-stack-using-queues/ 10 | * 11 | * 使用队列实现栈的下列操作: 12 | * 13 | * push(x) — 元素 x 入栈 14 | * pop() — 移除栈顶元素 15 | * top() — 获取栈顶元素 16 | * empty() — 返回栈是否为空 17 | */ 18 | public class No225_Implement_Stack_using_Queues { 19 | public static void main(String[] args) { 20 | MyStack myStack = new MyStack(); 21 | myStack.push(1); 22 | myStack.push(2); 23 | myStack.push(3); 24 | 25 | System.out.println(myStack.pop()); 26 | System.out.println(myStack.pop()); 27 | System.out.println(myStack.pop()); 28 | } 29 | 30 | } 31 | class MyStack { 32 | 33 | Queue queue; 34 | 35 | /** Initialize your data structure here. */ 36 | public MyStack() { 37 | queue = new LinkedList<>(); 38 | } 39 | 40 | /** Push element x onto stack. */ 41 | public void push(int x) { 42 | Queue tempQ = new LinkedList<>(); 43 | tempQ.add(x); 44 | tempQ.addAll(queue); 45 | queue = tempQ; 46 | 47 | } 48 | 49 | /** Removes the element on top of the stack and returns that element. */ 50 | public int pop() { 51 | return queue.poll(); 52 | } 53 | 54 | /** Get the top element. */ 55 | public int top() { 56 | return queue.peek(); 57 | 58 | } 59 | 60 | /** Returns whether the stack is empty. */ 61 | public boolean empty() { 62 | return queue.isEmpty(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/leetcode/algorithms/No22_Generate_Parentheses.java: -------------------------------------------------------------------------------- 1 | package space.mamba.leetcode.algorithms; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | 6 | /** 7 | * @author byte mamba 8 | * @date 2019/12/25 9 | *
10 |  *
11 |  * 
12 | */ 13 | public class No22_Generate_Parentheses { 14 | 15 | public static void main(String[] args) { 16 | 17 | System.out.println(new No22_Generate_Parentheses().generateParenthesis(3)); 18 | 19 | } 20 | 21 | public List generateParenthesis(int n) { 22 | List result = new ArrayList<>(); 23 | generateOnoByOne("", result, n, n); 24 | return result; 25 | } 26 | 27 | private void generateOnoByOne(String subList, List result, int left, int right) { 28 | 29 | if (left == 0 && right == 0) { 30 | result.add(subList); 31 | return; 32 | } 33 | if (left > 0) { 34 | generateOnoByOne(subList + "(", result, left - 1, right); 35 | } 36 | 37 | if (right > left) { 38 | generateOnoByOne(subList + ")", result, left, right - 1); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/leetcode/algorithms/No387_First_Unique_Character_In_a_String.java: -------------------------------------------------------------------------------- 1 | package space.mamba.leetcode.algorithms; 2 | 3 | 4 | /** 5 | * @author pankui 6 | * @date 2019-03-08 7 | *
 8 |  *
 9 |  * 
10 | */ 11 | public class No387_First_Unique_Character_In_a_String { 12 | 13 | /** 14 | * 很简单的解法,因为只包含字母(26),所以可以用int数组作为简单的哈希表。 15 | * */ 16 | public int firstUniqChar(String s) { 17 | int[] charCount = new int[26]; 18 | char[] chars = s.toCharArray(); 19 | for (char c : chars) { 20 | charCount[c - 'a']++; 21 | } 22 | for (int i = 0; i < chars.length; i++) { 23 | if (charCount[chars[i] - 'a'] == 1) { 24 | return i; 25 | } 26 | } 27 | return -1; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/leetcode/algorithms/No50_Pow.java: -------------------------------------------------------------------------------- 1 | package space.mamba.leetcode.algorithms; 2 | 3 | /** 4 | * @author byte mamba 5 | * @date 2019/12/4 6 | *
 7 |  *      50. Pow(x, n)
 8 |  *
 9 |  *      时间复杂度为 O(n),加上题目的限制会超时
10 |  *
11 |  *
12 |  *      本题的难点主要是在边界条件:如果 n < 0,是不是 n = -n, x = 1 / x ,再进行递归就能解决了呢?
13 |  *      如果 n = Intege.MIN_VALUE,n = -n 会出现溢出,怎么办呢?我们可以先将 n / 2 赋值给 t,
14 |  *      再将 t = -n,就不会出现溢出问题。
15 |  * 
16 | */ 17 | public class No50_Pow { 18 | 19 | public static void main(String[] args) { 20 | No50_Pow obj = new No50_Pow(); 21 | double result = obj.myPow(2,4); 22 | System.out.println(result); 23 | 24 | result = obj.myPow(2,-2); 25 | System.out.println(result); 26 | } 27 | 28 | /** 时间复杂度为 O(n),加上题目的限制会超时 29 | 所以这个方法超时,OJ 因超时无法通过 30 | */ 31 | public double myPow2(double x, int n) { 32 | 33 | if (n == 0) { 34 | return 1; 35 | } 36 | 37 | int mark = n; 38 | if (n < 0) { 39 | n = -n; 40 | } 41 | 42 | double temp = 1; 43 | double result = x; 44 | for (int i = 0; i < n; i++) { 45 | result = result * temp; 46 | temp = x; 47 | } 48 | return mark < 0 ? 1 / result : result; 49 | } 50 | 51 | public double power(double x, int n) { 52 | if (n == 0) { 53 | return 1; 54 | } 55 | 56 | double v = power(x, n / 2); 57 | 58 | if (n % 2 == 0) { 59 | return v * v; 60 | } else { 61 | return v * v * x; 62 | } 63 | } 64 | 65 | public double myPow(double x, int n) { 66 | if (n < 0) { 67 | return 1 / power(x, -n); 68 | } else { 69 | return power(x, n); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/leetcode/algorithms/No670_Maximum_Swap.java: -------------------------------------------------------------------------------- 1 | package space.mamba.leetcode.algorithms; 2 | 3 | /** 4 | * @author byte mamba 5 | * @date 2019/12/16 6 | *
 7 |  * Example 1:
 8 |  * Input: 2736
 9 |  * Output: 7236
10 |  *
11 |  * Example 2:
12 |  * Input: 9973
13 |  * Output: 9973
14 |  *
15 |  * https://blog.csdn.net/qq_26410101/article/details/86485441
16 |  *
17 |  * 
18 | */ 19 | public class No670_Maximum_Swap { 20 | 21 | public static void main(String[] args) { 22 | No670_Maximum_Swap obj = new No670_Maximum_Swap(); 23 | System.out.println(obj.maximumSwap(2736)); 24 | 25 | System.out.println(obj.maximumSwap(9973)); 26 | 27 | // 98863 28 | System.out.println(obj.maximumSwap(98368)); 29 | } 30 | 31 | 32 | public int maximumSwap(int num) { 33 | int maxValue = -1, maxIndex = -1; 34 | int leftIndex = -1, rightIndex = -1; 35 | char[] digits = Integer.toString(num).toCharArray(); 36 | 37 | 38 | for (int i = digits.length - 1; i >= 0; i--) { 39 | 40 | int value = Integer.parseInt(String.valueOf(digits[i])); 41 | if (value > maxValue) { 42 | maxIndex = i; 43 | maxValue = value; 44 | continue; 45 | } 46 | 47 | if (value < maxValue) { 48 | leftIndex = i; 49 | rightIndex = maxIndex; 50 | } 51 | } 52 | 53 | if (leftIndex == -1) { 54 | return num; 55 | } 56 | 57 | char temp = digits[rightIndex]; 58 | digits[rightIndex] = digits[leftIndex]; 59 | digits[leftIndex] = temp; 60 | 61 | return Integer.parseInt(new String(digits)); 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/leetcode/algorithms/No69_Sqrt.java: -------------------------------------------------------------------------------- 1 | package space.mamba.leetcode.algorithms; 2 | 3 | import org.junit.jupiter.api.Assertions; 4 | 5 | /** 6 | * @author mamba 7 | * @date 2020/10/25 22:06 8 | * 9 | * https://leetcode.com/problems/sqrtx/submissions/ 10 | */ 11 | public class No69_Sqrt { 12 | 13 | public static void main(String[] args) { 14 | 15 | Assertions.assertEquals(mySqrt(4),2); 16 | Assertions.assertEquals(mySqrt(9),3); 17 | } 18 | 19 | public static int mySqrt(int x) { 20 | 21 | return (int) Math.sqrt(x); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/leetcode/algorithms/No98_Validate_Binary_Search_Tree.java: -------------------------------------------------------------------------------- 1 | package space.mamba.leetcode.algorithms; 2 | 3 | /** 4 | * @author byte mamba 5 | * @date 2019/12/2 6 | *
 7 |  *
 8 |  * 
9 | */ 10 | public class No98_Validate_Binary_Search_Tree { 11 | 12 | public static void main(String[] args) { 13 | 14 | No98_Validate_Binary_Search_Tree obj = new No98_Validate_Binary_Search_Tree(); 15 | TreeNode root = new TreeNode(2); 16 | TreeNode left = new TreeNode(1); 17 | TreeNode right = new TreeNode(3); 18 | 19 | root.left = left; 20 | root.right = right; 21 | boolean result = obj.isValidBST(root); 22 | System.out.println(result); 23 | 24 | 25 | TreeNode root_1 = new TreeNode(5); 26 | TreeNode left_1 = new TreeNode(6); 27 | TreeNode right_1 = new TreeNode(3); 28 | 29 | root_1.left = left_1; 30 | root_1.right = right_1; 31 | result = obj.isValidBST(root_1); 32 | System.out.println(result); 33 | 34 | } 35 | 36 | /** 37 | * Java Solution using Recursion 38 | * 递归 39 | */ 40 | public boolean isValidBST(TreeNode root) { 41 | 42 | return isValid(root, null, null); 43 | } 44 | 45 | private boolean isValid(TreeNode root, Integer min, Integer max) { 46 | if (root == null) { 47 | return true; 48 | } 49 | 50 | if (min != null && root.val <= min) { 51 | return false; 52 | } 53 | if (max != null && root.val >= max) { 54 | return false; 55 | } 56 | 57 | // 左子树都小于根节点,一直递归到 null,右子树都大于根节点,一直递归到null ,都满足就返回TRUE 58 | return isValid(root.left, min, root.val) && isValid(root.right, root.val, max); 59 | } 60 | 61 | 62 | } 63 | 64 | 65 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/leetcode/algorithms/No_232_Implement_Queue_using_Stacks.java: -------------------------------------------------------------------------------- 1 | package space.mamba.leetcode.algorithms; 2 | 3 | import org.junit.jupiter.api.Assertions; 4 | 5 | import java.util.Stack; 6 | 7 | /** 8 | * @author mamba 9 | * @date 2021/2/1 07:50 10 | */ 11 | public class No_232_Implement_Queue_using_Stacks { 12 | 13 | public static void main(String[] args) { 14 | MyQueue myQueue = new MyQueue(); 15 | myQueue.push(1); 16 | myQueue.push(2); 17 | myQueue.push(3); 18 | Assertions.assertEquals(myQueue.pop() , 1); 19 | Assertions.assertEquals(myQueue.pop() , 2); 20 | Assertions.assertEquals(myQueue.pop() , 3); 21 | } 22 | } 23 | 24 | class MyQueue { 25 | 26 | Stack stack; 27 | /** Initialize your data structure here. */ 28 | public MyQueue() { 29 | stack = new Stack<>(); 30 | } 31 | 32 | /** Push element x to the back of queue. */ 33 | public void push(int x) { 34 | Stack tempStack = new Stack<>(); 35 | tempStack.add(x); 36 | tempStack.addAll(stack); 37 | stack = tempStack; 38 | 39 | } 40 | 41 | /** Removes the element from in front of queue and returns that element. */ 42 | public int pop() { 43 | return stack.pop(); 44 | } 45 | 46 | /** Get the front element. */ 47 | public int peek() { 48 | return stack.peek(); 49 | } 50 | 51 | /** Returns whether the queue is empty. */ 52 | public boolean empty() { 53 | return stack.isEmpty(); 54 | } 55 | } -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/leetcode/algorithms/TreeNode.java: -------------------------------------------------------------------------------- 1 | package space.mamba.leetcode.algorithms; 2 | 3 | /** 4 | * @author byte mamba 5 | * @date 2019/12/3 6 | *
 7 |  *
 8 |  * 
9 | */ 10 | public class TreeNode { 11 | 12 | public int val; 13 | public TreeNode left; 14 | public TreeNode right; 15 | 16 | TreeNode(int x) { 17 | val = x; 18 | } 19 | 20 | TreeNode(){} 21 | 22 | @Override 23 | public String toString() { 24 | return "" + val; 25 | } 26 | 27 | public TreeNode getTestExampleData() { 28 | /* 29 | 6 30 | / \ 31 | 2 8 32 | / \ / \ 33 | 0 4 7 9 34 | / \ 35 | 3 5 36 | */ 37 | 38 | TreeNode root = new TreeNode(6); 39 | TreeNode left = new TreeNode(2); 40 | TreeNode right = new TreeNode(8); 41 | 42 | TreeNode left2_left1 = new TreeNode(0); 43 | TreeNode left2_right1 = new TreeNode(4); 44 | TreeNode left2_right1_left = new TreeNode(3); 45 | TreeNode left2_right1_right = new TreeNode(5); 46 | 47 | TreeNode right2_left = new TreeNode(7); 48 | TreeNode right2_right = new TreeNode(9); 49 | 50 | root.left = left; 51 | left.left = left2_left1; 52 | left.right = left2_right1; 53 | left2_right1.left = left2_right1_left; 54 | left2_right1.right = left2_right1_right; 55 | 56 | root.right = right; 57 | right.left = right2_left; 58 | right.right = right2_right; 59 | return root; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/leetcode/database/Duplicate_Emails.sql: -------------------------------------------------------------------------------- 1 | 182. Duplicate Emails 2 | 3 | Write a SQL query to find all duplicate emails in a table named Person. 4 | 5 | +----+---------+ 6 | | Id | Email | 7 | +----+---------+ 8 | | 1 | a@b.com | 9 | | 2 | c@d.com | 10 | | 3 | a@b.com | 11 | +----+---------+ 12 | For example, your query should return the following for the above table: 13 | 14 | +---------+ 15 | | Email | 16 | +---------+ 17 | | a@b.com | 18 | +---------+ 19 | Note: All emails are in lowercase. 20 | 21 | 22 | Mysql 答案: 23 | 24 | select Email 25 | from Person 26 | group by Email 27 | having count(Email) > 1; 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/logic_operation/BitwiseAndExample01.java: -------------------------------------------------------------------------------- 1 | package space.mamba.logic_operation; 2 | 3 | /** 4 | * @author pankui 5 | * @date 2019-04-06 6 | *
 7 |  *
 8 |  *   &按位与的运算
 9 |  *
10 |  *   &按位与的运算规则是将两边的数转换为二进制位,然后运算最终值,
11 |  *   运算规则即(两个为真才为真)1&1=1 , 1&0=0 , 0&1=0 , 0&0=0
12 |  *
13 |  *   3的二进制位是0000 0011 , 5的二进制位是0000 0101 , 那么就是011 & 101,由按位与运算规则得知,001 & 101等于0000 0001,最终值为1
14 |  *
15 |  *   7的二进制位是0000 0111,那就是111 & 101等于101,也就是0000 0101,故值为5
16 |  *
17 |  * 
18 | */ 19 | public class BitwiseAndExample01 { 20 | 21 | public static void main(String[] args) { 22 | //&按位与的运算规则是将两边的数转换为二进制位,然后运算最终值 23 | // int 是八位 011 001 24 | System.out.println(3 & 1); 25 | 26 | System.out.println(3 & 5); 27 | 28 | System.out.println(7 & 5); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/logic_operation/BitwiseOrExample01.java: -------------------------------------------------------------------------------- 1 | package space.mamba.logic_operation; 2 | 3 | /** 4 | * @author pankui 5 | * @date 2019-04-06 6 | *
 7 |  *   Bitwise or  |(按位或)
 8 |  *
 9 |  *   |按位或和&按位与计算方式都是转换二进制再计算,不同的是运算规则(一个为真即为真)1|0 = 1 , 1|1 = 1 , 0|0 = 0 , 0|1 = 1
10 |  *
11 |  * 
12 | */ 13 | public class BitwiseOrExample01 { 14 | 15 | public static void main(String[] args) { 16 | System.out.println(6 | 2); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/logic_operation/InverseOperatorExample01.java: -------------------------------------------------------------------------------- 1 | package space.mamba.logic_operation; 2 | 3 | /** 4 | * @author pankui 5 | * @date 2019-04-06 6 | *
 7 |  *  Inverse operator   取反运算符
 8 |  *
 9 |  *  取反就是1为0,0为1,
10 |  *
11 |  *  5的二进制位是0000 0101,取反后为1111 1010,值为-6
12 |  *
13 |  * 
14 | */ 15 | public class InverseOperatorExample01 { 16 | 17 | public static void main(String[] args) { 18 | System.out.println(~5); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/logic_operation/LeftShiftOperator.java: -------------------------------------------------------------------------------- 1 | package space.mamba.logic_operation; 2 | 3 | /** 4 | * @author pankui 5 | * @date 2019-04-06 6 | *
 7 |  *   Left shift operator 左移运算符
 8 |  * 
9 | */ 10 | public class LeftShiftOperator { 11 | 12 | public static void main(String[] args) { 13 | 14 | /** 15 | * 5<<2的意思为5的二进制位往左挪两位,右边补0,5的二进制位是0000 0101 , 16 | * 就是把有效值101往左挪两位就是0001 0100 , 17 | * 正数左边第一位补0,负数补1,等于乘于2的n次方,十进制位是20 18 | * */ 19 | // 等于乘以2的平方 20 | System.out.println(5 << 2); 21 | 22 | // 等于乘以2的一次方 23 | System.out.println(5 << 1); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/logic_operation/LogicAndExample01.java: -------------------------------------------------------------------------------- 1 | package space.mamba.logic_operation; 2 | 3 | /** 4 | * @author pankui 5 | * @date 2019-04-06 6 | *
 7 |  *  Logic and  &&(逻辑与)
 8 |  * 
9 | */ 10 | public class LogicAndExample01 { 11 | 12 | public static void main(String[] args) { 13 | String str = null; 14 | 15 | if (str != null && (100 / 0 == 0)) { 16 | System.out.println("&&左边一旦为假,右边就不在计算"); 17 | } else { 18 | System.out.println("100 / 0 == 0被计算会抛异常"); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/logic_operation/LogicalOrExample01.java: -------------------------------------------------------------------------------- 1 | package space.mamba.logic_operation; 2 | 3 | /** 4 | * @author pankui 5 | * @date 2019-04-06 6 | *
 7 |  *
 8 |  * 
9 | */ 10 | public class LogicalOrExample01 { 11 | 12 | public static void main(String[] args) { 13 | String str = null; 14 | 15 | if (str != null || (100 / 0 == 0)) { 16 | System.out.println("&&左边一旦为假,右边就不在计算"); 17 | } else { 18 | System.out.println("100 / 0 == 0被计算会抛异常"); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/logic_operation/RightShiftOperator.java: -------------------------------------------------------------------------------- 1 | package space.mamba.logic_operation; 2 | 3 | /** 4 | * @author pankui 5 | * @date 2019-04-06 6 | *
 7 |  *      >>(右移运算符)
 8 |  * 
9 | */ 10 | public class RightShiftOperator { 11 | 12 | public static void main(String[] args) { 13 | 14 | /** 15 | * 凡位运算符都是把值先转换成二进制再进行后续的处理, 16 | * 17 | * 5的二进制位是0000 0101,右移两位就是把101左移后为0000 0001,正数左边第一位补0,负数补1,等于除于2的n次方,结果为1 18 | * */ 19 | // 等于除于2的平方 20 | System.out.println(5 >> 2); 21 | 22 | // 等于除于2的一次方 23 | System.out.println(5 >> 1); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/logic_operation/UnsignedRightShiftOperatorExample01.java: -------------------------------------------------------------------------------- 1 | package space.mamba.logic_operation; 2 | 3 | /** 4 | * @author pankui 5 | * @date 2019-04-06 6 | *
 7 |  *      Unsigned right shift operator
 8 |  *      无符号右移运算符
 9 |  *
10 |  *      无符号右移运算符和右移运算符的主要区别在于负数的计算,因为无符号右移是高位补0,移多少位补多少个0。
11 |  *
12 |  *      15的二进制位是0000 1111 , 右移2位0000 0011,结果为3
13 |  *
14 |  * 
15 | */ 16 | public class UnsignedRightShiftOperatorExample01 { 17 | 18 | public static void main(String[] args) { 19 | 20 | // 无符号右移运算符和右移运算符的主要区别在于负数的计算,因为无符号右移是高位补0,移多少位补多少个0。 21 | // 15的二进制位是0000 1111 , 右移2位0000 0011,结果为3 22 | System.out.println(15 >>> 2); 23 | 24 | 25 | // -6的二进制是6的二进制取反再加1,6的二进制也就是0000 0000 0000 0000 0000 0000 0000 0110, 26 | // 取反后加1为1111 1111 1111 1111 1111 1111 1111 1010, 27 | // 右移三位0001 1111 1111 1111 1111 1111 1111 1111 28 | 29 | System.out.println(-6 >>> 3); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/logic_operation/XOR_Example01.java: -------------------------------------------------------------------------------- 1 | package space.mamba.logic_operation; 2 | 3 | /** 4 | * @author pankui 5 | * @date 2019-04-06 6 | *
 7 |  *  XOR 异或
 8 |  *
 9 |  *  5的二进制位是0000 0101 , 9的二进制位是0000 1001,也就是0101 ^ 1001,结果为1100 , 00001100的十进制位是12
10 |  *
11 |  * 
12 | */ 13 | public class XOR_Example01 { 14 | 15 | public static void main(String[] args) { 16 | System.out.println(5 ^ 9); 17 | } 18 | } 19 | 20 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/string/ReplaceSpace.java: -------------------------------------------------------------------------------- 1 | package space.mamba.string; 2 | 3 | import java.util.regex.Matcher; 4 | import java.util.regex.Pattern; 5 | 6 | /** 7 | * @author pankui 8 | * @date 2018/11/17 9 | *
10 |  *  剑指offer:请实现一个函数,将一个字符串中的每个空格替换成“%20”。
11 |  *  例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy。
12 |  * 
13 | */ 14 | public class ReplaceSpace { 15 | 16 | 17 | public static void main(String[] args) { 18 | 19 | String str = "WeAre Happy. "; 20 | 21 | System.out.println(replace1(str)); 22 | 23 | //第二种实现方式 24 | String[] arr = str.split(" "); 25 | 26 | StringBuilder s2 = new StringBuilder(); 27 | 28 | for (int i = 0; i < str.length(); i++) { 29 | 30 | char b = str.charAt(i); 31 | if (String.valueOf(b).equals(" ")) { 32 | s2.append("%20"); 33 | } else { 34 | s2.append(b); 35 | } 36 | } 37 | System.out.println(s2.toString()); 38 | 39 | 40 | 41 | // 使用正则,其实String 的replaceAll 也是正则 42 | Pattern pattern = Pattern.compile("\\s"); 43 | Matcher matcher = pattern.matcher(str); 44 | StringBuilder stringBuilder = new StringBuilder(); 45 | while (matcher.find()) { 46 | 47 | String s = matcher.replaceAll("%20"); 48 | 49 | System.out.println("s="+s); 50 | stringBuilder.append(s); 51 | } 52 | 53 | System.out.println("结果="+stringBuilder.toString()); 54 | } 55 | 56 | public static String replace1(String str) { 57 | return str.replaceAll("\\s","%20"); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /algorithms-java-example/src/main/java/space.mamba/string/Test001.java: -------------------------------------------------------------------------------- 1 | package java.space.mamba.string; 2 | 3 | /** 4 | * @author pankui 5 | * @date 2021/3/17 6 | *
 7 |  *
 8 |  * 
9 | */ 10 | public class Test001 { 11 | 12 | public static void main(String[] args) { 13 | int i =0; 14 | System.out.println(i++); 15 | 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /algorithms-java-example/src/test/java/space/mamba/coding/interviews/No49_StringToIntegerTest.java: -------------------------------------------------------------------------------- 1 | package space.mamba.coding.interviews; 2 | 3 | import org.junit.jupiter.api.Assertions; 4 | import org.junit.jupiter.api.Test; 5 | 6 | /** 7 | * @author mamba 8 | * @date 2020/9/12 09:59 9 | */ 10 | public class No49_StringToIntegerTest { 11 | 12 | @Test 13 | private void strToInteger() { 14 | No49_StringToInteger obj = new No49_StringToInteger(); 15 | Assertions.assertEquals(obj.strToInteger(null), 0); 16 | Assertions.assertEquals(obj.strToInteger(""), 0); 17 | Assertions.assertEquals(obj.strToInteger(" "), 0); 18 | Assertions.assertEquals(obj.strToInteger(" "), 0); 19 | Assertions.assertEquals(obj.strToInteger("--123321"), 0); 20 | Assertions.assertEquals(obj.strToInteger("++123321"), 0); 21 | Assertions.assertEquals(obj.strToInteger("-123321"), -123321); 22 | Assertions.assertEquals(obj.strToInteger("12345"), 12345); 23 | Assertions.assertEquals(obj.strToInteger("+54321"), 54321); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /algorithms-java-example/src/test/java/space/mamba/leetcode/No387_First_Unique_Character_In_a_StringTest.java: -------------------------------------------------------------------------------- 1 | package space.mamba.leetcode; 2 | 3 | import org.junit.jupiter.api.Assertions; 4 | import org.junit.jupiter.api.Test; 5 | import space.mamba.leetcode.algorithms.No387_First_Unique_Character_In_a_String; 6 | 7 | /** 8 | * @author mamba 9 | * @date 2020/9/12 09:58 10 | */ 11 | public class No387_First_Unique_Character_In_a_StringTest { 12 | 13 | @Test 14 | public void testFirstUniqChar() { 15 | 16 | No387_First_Unique_Character_In_a_String obj = new No387_First_Unique_Character_In_a_String(); 17 | Assertions.assertEquals(0, obj.firstUniqChar("leetcode")); 18 | Assertions.assertEquals(2, obj.firstUniqChar("loveleetcode")); 19 | String str = "asdffdaq"; 20 | 21 | for (int i = 0; i < str.length(); i++) { 22 | char ch = str.charAt(i); 23 | // 如果这个字符第一次出现的位置和最后出现的位置相等,就说明字符串中它只出现了一次 24 | if (str.indexOf(ch) == str.lastIndexOf(ch)) { 25 | System.out.println(ch); 26 | break; 27 | } 28 | } 29 | 30 | System.out.println(obj.firstUniqChar(str)); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /algorithms-java-example/src/test/java/space/mamba/leetcode/TwoSumTest.java: -------------------------------------------------------------------------------- 1 | package space.mamba.leetcode; 2 | 3 | import org.junit.jupiter.api.Assertions; 4 | import org.junit.jupiter.api.Test; 5 | 6 | /** 7 | * @author mamba 8 | * @date 2020/9/12 09:48 9 | */ 10 | public class TwoSumTest { 11 | 12 | @Test 13 | public void testTwoSum() { 14 | int[] nums = {2, 7, 11, 15}; 15 | int target = 9; 16 | int[] a = new TwoSum().twoSum(nums, target); 17 | Assertions.assertArrayEquals(a, new int[]{0, 1}); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /algorithms-python-example/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/algorithms-python-example/__init__.py -------------------------------------------------------------------------------- /algorithms-python-example/basic/BubbleSortDemo.py: -------------------------------------------------------------------------------- 1 | def bubble_sorted(iterable): 2 | new_list = list(iterable) 3 | list_len = len(new_list) 4 | for i in range(list_len - 1): 5 | for j in range(list_len - 1, i, -1): 6 | if new_list[j] < new_list[j - 1]: 7 | new_list[j], new_list[j - 1] = new_list[j - 1], new_list[j] 8 | return new_list 9 | 10 | 11 | testlist = [27, 33, 28, 4, 2, 26, 13, 35, 8, 14] 12 | print('sorted:', bubble_sorted(testlist)) 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /algorithms-python-example/basic/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/algorithms-python-example/basic/__init__.py -------------------------------------------------------------------------------- /images/O/a-sorted-array-of-16-elements.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/O/a-sorted-array-of-16-elements.png -------------------------------------------------------------------------------- /images/O/basic_O.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/O/basic_O.png -------------------------------------------------------------------------------- /images/O/common-formula.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/O/common-formula.png -------------------------------------------------------------------------------- /images/O/general-formula.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/O/general-formula.png -------------------------------------------------------------------------------- /images/O/keep-half.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/O/keep-half.png -------------------------------------------------------------------------------- /images/O/log-formula.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/O/log-formula.png -------------------------------------------------------------------------------- /images/O/repeat-steps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/O/repeat-steps.png -------------------------------------------------------------------------------- /images/O/select-mid-as-pivot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/O/select-mid-as-pivot.png -------------------------------------------------------------------------------- /images/O/separating-the-power.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/O/separating-the-power.png -------------------------------------------------------------------------------- /images/O/simplify-formula.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/O/simplify-formula.png -------------------------------------------------------------------------------- /images/O/till-find-result.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/O/till-find-result.png -------------------------------------------------------------------------------- /images/basic/600px-Greedy_algorithm_36_cents.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/basic/600px-Greedy_algorithm_36_cents.png -------------------------------------------------------------------------------- /images/basic/BFS_DFS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/basic/BFS_DFS.png -------------------------------------------------------------------------------- /images/basic/Bubble_sort_animation.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/basic/Bubble_sort_animation.gif -------------------------------------------------------------------------------- /images/basic/CountMinSketch_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/basic/CountMinSketch_1.jpg -------------------------------------------------------------------------------- /images/basic/CountMinSketch_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/basic/CountMinSketch_2.jpg -------------------------------------------------------------------------------- /images/basic/LFU.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/basic/LFU.jpg -------------------------------------------------------------------------------- /images/basic/SLRU.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/basic/SLRU.jpg -------------------------------------------------------------------------------- /images/basic/Sorting_shaker_sort_anim.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/basic/Sorting_shaker_sort_anim.gif -------------------------------------------------------------------------------- /images/basic/TinyLFU.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/basic/TinyLFU.png -------------------------------------------------------------------------------- /images/basic/W-TinyLFU.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/basic/W-TinyLFU.jpg -------------------------------------------------------------------------------- /images/basic/greedy_algorithm_package_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/basic/greedy_algorithm_package_1.png -------------------------------------------------------------------------------- /images/basic/greedy_algorithm_package_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/basic/greedy_algorithm_package_2.png -------------------------------------------------------------------------------- /images/basic/lru.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/basic/lru.jpg -------------------------------------------------------------------------------- /images/basic/merge_sort.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/basic/merge_sort.png -------------------------------------------------------------------------------- /images/basic/merge_sort_conquer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/basic/merge_sort_conquer.png -------------------------------------------------------------------------------- /images/coding_offer/Multiply.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/coding_offer/Multiply.jpg -------------------------------------------------------------------------------- /images/coding_offer/RotateSmallestNumberOfArrays.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/coding_offer/RotateSmallestNumberOfArrays.jpg -------------------------------------------------------------------------------- /images/coding_offer/no_11_print_number.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/coding_offer/no_11_print_number.png -------------------------------------------------------------------------------- /images/coding_offer/stack_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/coding_offer/stack_1.png -------------------------------------------------------------------------------- /images/coding_offer/stack_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/coding_offer/stack_2.png -------------------------------------------------------------------------------- /images/interview/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/interview/1.png -------------------------------------------------------------------------------- /images/interview/10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/interview/10.png -------------------------------------------------------------------------------- /images/interview/1_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/interview/1_1.png -------------------------------------------------------------------------------- /images/interview/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/interview/3.png -------------------------------------------------------------------------------- /images/interview/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/interview/4.png -------------------------------------------------------------------------------- /images/interview/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/interview/5.png -------------------------------------------------------------------------------- /images/interview/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/interview/6.png -------------------------------------------------------------------------------- /images/interview/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/interview/7.png -------------------------------------------------------------------------------- /images/interview/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/interview/8.png -------------------------------------------------------------------------------- /images/interview/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/interview/9.png -------------------------------------------------------------------------------- /images/recursive/Recursive_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/recursive/Recursive_1.png -------------------------------------------------------------------------------- /images/recursive/Recursive_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/recursive/Recursive_2.png -------------------------------------------------------------------------------- /images/recursive/Recursive_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/recursive/Recursive_4.png -------------------------------------------------------------------------------- /images/recursive/Recursive_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/recursive/Recursive_5.png -------------------------------------------------------------------------------- /images/recursive/Recursive_stack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/recursive/Recursive_stack.png -------------------------------------------------------------------------------- /images/tree/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/1.png -------------------------------------------------------------------------------- /images/tree/10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/10.jpg -------------------------------------------------------------------------------- /images/tree/11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/11.jpg -------------------------------------------------------------------------------- /images/tree/12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/12.jpg -------------------------------------------------------------------------------- /images/tree/13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/13.jpg -------------------------------------------------------------------------------- /images/tree/14.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/14.jpg -------------------------------------------------------------------------------- /images/tree/15.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/15.jpg -------------------------------------------------------------------------------- /images/tree/16.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/16.jpg -------------------------------------------------------------------------------- /images/tree/17.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/17.jpg -------------------------------------------------------------------------------- /images/tree/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/2.jpg -------------------------------------------------------------------------------- /images/tree/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/3.jpg -------------------------------------------------------------------------------- /images/tree/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/4.png -------------------------------------------------------------------------------- /images/tree/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/5.png -------------------------------------------------------------------------------- /images/tree/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/6.png -------------------------------------------------------------------------------- /images/tree/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/7.png -------------------------------------------------------------------------------- /images/tree/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/8.png -------------------------------------------------------------------------------- /images/tree/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/9.png -------------------------------------------------------------------------------- /images/tree/BST.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/BST.jpeg -------------------------------------------------------------------------------- /images/tree/B_tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/B_tree.png -------------------------------------------------------------------------------- /images/tree/Binary_Search_Tree.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/Binary_Search_Tree.jpeg -------------------------------------------------------------------------------- /images/tree/Binary_search_tree_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/Binary_search_tree_1.png -------------------------------------------------------------------------------- /images/tree/Binary_tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/Binary_tree.png -------------------------------------------------------------------------------- /images/tree/b+_11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/b+_11.png -------------------------------------------------------------------------------- /images/tree/balanced_search_tree.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/balanced_search_tree.jpeg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_11.jpg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_12.jpg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_13.jpg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_14.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_14.jpg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_15.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_15.jpg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_16.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_16.jpg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_17.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_17.jpg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_18.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_18.jpg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_19.jpg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_2.jpg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_20.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_20.jpg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_21.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_21.jpg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_22.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_22.jpg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_23.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_23.jpg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_24.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_24.jpg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_25.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_25.jpg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_26.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_26.jpg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_27.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_27.jpg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_28.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_28.jpg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_29.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_29.jpg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_30.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_30.jpg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_31.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_31.jpg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_32.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_32.jpg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_33.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_33.jpg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_34.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_34.jpg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_35.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_35.jpg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_36.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_36.jpg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_37.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_37.jpg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_38.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_38.jpg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_39.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_39.jpg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_40.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_40.jpg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_41.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_41.jpg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_42.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_42.jpg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_43.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_43.jpg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_44.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_44.jpg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_45.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_45.jpg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_46.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_46.jpg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_47.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_47.jpg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_48.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_48.jpg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_49.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_49.jpg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_50.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_50.jpg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_51.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_51.jpg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_52.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_52.jpg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_53.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_53.jpg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_54.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_54.jpg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_55.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_55.jpg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_56.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_56.jpg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_57.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_57.jpg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_58.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_58.jpg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_59.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_59.jpg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_60.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_60.jpg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_61.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_61.jpg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_62.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_62.jpg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_63.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_63.jpg -------------------------------------------------------------------------------- /images/tree/red_block/red_block_tree_64.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block/red_block_tree_64.jpg -------------------------------------------------------------------------------- /images/tree/red_block_left.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block_left.jpg -------------------------------------------------------------------------------- /images/tree/red_block_left_gif.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block_left_gif.gif -------------------------------------------------------------------------------- /images/tree/red_block_right.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block_right.jpg -------------------------------------------------------------------------------- /images/tree/red_block_right_gif.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block_right_gif.gif -------------------------------------------------------------------------------- /images/tree/red_block_tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hi-mamba/algorithms/cf7cf8f02b563bc17a47418368ceeaa6acfb6a42/images/tree/red_block_tree.png -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | space.mamba 8 | algorithms 9 | pom 10 | 1.0-SNAPSHOT 11 | 12 | algorithms-java-example 13 | 14 | 15 | 16 | 17 | 18 | 13 19 | ${java.version} 20 | ${java.version} 21 | 5.6.2 22 | 23 | 24 | 25 | 26 | 27 | org.junit.jupiter 28 | junit-jupiter-api 29 | ${junit.version} 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /几种淘汰算法.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## 几种淘汰算法 4 | 5 | 下面列举下常见的三种FIFO,LRU,LFU(还有一些ARC,MRU感兴趣的可以自行搜索): 6 | 7 | - FIFO:先进先出,在这种淘汰算法中,先进入缓存的会先被淘汰。 8 | 这种可谓是最简单的了,但是会导致我们命中率很低。 9 | 试想一下我们如果有个访问频率很高的数据是所有数据第一个访问的, 10 | 而那些不是很高的是后面再访问的,那这样就会把我们的首个数据但是他的访问频率很高给挤出。 11 | 12 | - LRU:最近最少使用算法。在这种算法中避免了上面的问题, 13 | 每次访问数据都会将其放在我们的队尾,如果需要淘汰数据,就只需要淘汰队首即可。 14 | 但是这个依然有个问题,如果有个数据在1个小时的前59分钟访问了1万次(可见这是个热点数据), 15 | 再后一分钟没有访问这个数据,但是有其他的数据访问,就导致了我们这个热点数据被淘汰。 16 | 17 | - LFU:最近最少频率使用。在这种算法中又对上面进行了优化, 18 | 利用额外的空间记录每个数据的使用频率,然后选出频率最低进行淘汰。 19 | 这样就避免了LRU不能处理时间段的问题。 20 | 21 | -------------------------------------------------------------------------------- /剑指offer/05、从尾到头打印链表.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # 从尾到头打印链表 4 | 5 | ## 解决方案 6 | 7 | 1、先 从头到尾打印链表 入栈里,然后打印栈 8 | 9 | 2、递归打印 10 | 11 | ## 实现 12 | 13 | [P58_PrintListInReversedOrder](/algorithms-java-example/src/main/java/space.mamba/coding/interviews/P58_PrintListInReversedOrder.java) 14 | 15 | -------------------------------------------------------------------------------- /剑指offer/07、用两个栈实现队列.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # 用两个栈实现队列 4 | 5 | 6 | 入栈 1 完成,然后栈1 出栈 入栈 2 完成队列 7 | 8 | ## 例子 9 | 10 | 栈1 11 | 12 | ``` 13 | |1| 14 | |2| 15 | |3| 16 | ``` 17 | 18 | 栈1 出栈 然后结果 入栈2 19 | 20 | 栈2 21 | ``` 22 | |3| 23 | |2| 24 | |1| 25 | ``` 26 | 27 | 28 | ### [例子](/algorithms-java-example/src/main/java/space.mamba/coding/interviews/No7QueueWithTwoStacks.java) -------------------------------------------------------------------------------- /剑指offer/08、求旋转数组的最小数字.md: -------------------------------------------------------------------------------- 1 | 2 | ## [参考](https://www.cnblogs.com/xwdreamer/archive/2012/05/07/2487520.html) 3 | 4 | ## [参考](http://www.cnblogs.com/edisonchou/p/4746561.html) 5 | 6 | 7 | 8 | # 8、求旋转数组的最小数字 9 | 10 | > 一个包含重复元素的升序数组 11 | 12 | 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。 13 | 输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。 14 | 15 | 例如,数组 [3,4,5,1,2] 为 [1,2,3,4,5] 的一个旋转,该数组的最小值为1。   16 | 17 | ### 示例 1: 18 | 19 | ``` 20 | 输入:[3,4,5,1,2] 21 | 输出:1 22 | ``` 23 | 24 | ### 示例 2: 25 | ``` 26 | 输入:[2,2,2,0,1] 27 | 输出:0 28 | ``` 29 | 30 | ## 方法一:暴力解法 31 | 32 | 遍历整个数组找到小值,但是没有利用到排序数组的特点;复杂度o(n) 33 | 34 | 这道题最直观的解法并不难,从头到尾遍历数组一次,我们就能找出最小的元素。 35 | 这种思路的时间复杂度显然是O(n)。但是这个思路没有利用输入的旋转数组的特性, 36 | 肯定达不到面试官的要求。 37 | 38 | ## 方法二:二分法 39 | 40 | 时间复杂度:平均时间复杂度为 O(log n)) 41 | 42 | [No8_RevertArray](/algorithms-java-example/src/main/java/space.mamba/coding/interviews/No8_RevertArray.java) 43 | 44 | 45 | - [例子](/algorithms-java-example/src/main/java/space.mamba/coding/interviews/RotateSmallestNumberOfArrays.java) 46 | 47 | - [例子](/algorithms-java-example/src/main/java/space.mamba/coding/interviews/MinNumberInRotateArray.java) 48 | 49 | -------------------------------------------------------------------------------- /剑指offer/11、数值的整数次方.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # 数值的整数次方 4 | 5 | > 实现函数double Power(double base,int exponent),求base的exponent次方。 6 | 不得使用库函数,同时不需要考虑大数问题。 7 | 8 | 9 | ## 方法一: 10 | 11 | 指数exponent为负,需要把exponent变为正数,然后再对base^(-exponent)取倒数; 12 | 当exponent为负数时,还需考虑base为0的情况;double和0相等的判断。 13 | 14 | 15 | ## 方法二:递归 16 | 17 | 如果我们的目标是求出一个数字的32次方,如果我们已经知道了它的16次方,那么只要在16次方的基础上再平方一次就好了, 18 | 依此类推,我们求32次方只需要做5次乘法。 19 | 20 | 我们可以利用如下公式: 21 | 22 | ![](../images/coding_offer/no_11_print_number.png) 23 | 24 | ```java 25 | 26 | private double powerWithExponent2(double base,int exponent){ 27 | if(exponent == 0){ 28 | return 1; 29 | } 30 | if(exponent == 1){ 31 | return base; 32 | } 33 | double result = powerWithExponent2(base, exponent >> 1); 34 | result *= result; 35 | //等于奇数的话需要再乘一次 36 | if((exponent&0x1) == 1){ 37 | result *= base; 38 | } 39 | return result; 40 | } 41 | ``` 42 | 43 | 我们用右移运算代替除2,用位与运算符代替了求余运算符(%)来判断一个数是奇数还是偶数。 44 | 位运算的效率比乘除法及求余运算的效率要高很多。 45 | 46 | 47 | 48 | ## [数值的整数次方 例子](/algorithms-java-example/src/main/java/space.mamba/coding/interviews/No11_DoublePower.java) 49 | 50 | 51 | ### [递归执行过程详解](../../020、递归执行过程详解.md) 52 | -------------------------------------------------------------------------------- /剑指offer/12、打印1到最大的n位数.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # 打印1到最大的n位数 4 | 5 | > 题目:输入数字n,按顺序打印出从1最大的n位十进制数。比如输入3,则打印出1、2、3一直到最大的3位数即999。 6 | 7 | 8 | ## 不假思索的解法 9 | 10 | 最容易想到的办法是先求出最大的n位数,然后用一个循环从1开始逐个打印: 11 | 12 | ```java 13 | void print1ToMaxOfNDigitsSimple(int n) { 14 | int number = 1; 15 | int i = 0; 16 | //利用while循环计算出比n位十进制多1的数 17 | while (i < n) { 18 | number = number * 10; 19 | i++; 20 | } 21 | 22 | for (j = 1; j < number; j++) { 23 | System.out.println(j); 24 | } 25 | } 26 | ``` 27 | 28 | > 初看之下好像没有问题,但是其并没有考虑大数问题,有可能即使用整型(int)或长整型(long)都会溢出。 29 | 30 | ## 字符串或者数组进行模拟 31 | 32 | > 因为是大数,所以只能用数组或者字符串操作;因为需要判断打印到n个9为止,不需要每次判断, 33 | 只需要在最高位产生进位的时候判断。 34 | 35 | 解决这个问题需要表达一个大数。最常用也是最容易的方法是用字符串或者数组表达大数。该算法的步骤如下: 36 | 37 |   Step1.把字符串中的每一个数字都初始化为'0'; 38 | 39 |   Step2.每一次为字符串表示的数字加1,再打印出来; 40 | 41 | [字符串或者数组进行模拟](/algorithms-java-example/src/main/java/space.mamba/coding/interviews/No12_PrintToMaxOfDigitsSimpke2.java) 42 | -------------------------------------------------------------------------------- /剑指offer/13、O(1)时间删除链表节点.md: -------------------------------------------------------------------------------- 1 | ## [原文](https://blog.csdn.net/chixujohnny/article/details/51240153 ) 2 | 3 | # O(1)时间删除链表节点 4 | 5 | > 题目:给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点。 6 | 7 | 8 | ## 一般思路 9 | 从头开始顺序遍历单链表,遇到要删除的节点跳过去就行了 10 | 11 | 12 | 13 | ## O(1)思路 14 | 因为已经给了要删除节点的指针,可以找到待删除节点的写一个节点的值,复制到待删除节点, 15 | 将该节点的next指针指向next.next就行了,流程如下: 16 | 17 | (1) a->b->c->d->e 要删除的是c节点 18 | 19 | (2) a->b->d->d->e 将待删除节点的下一个节点的值复制到该节点 20 | 21 | (3) a->b->d d->e 将待删除节点的next指向它的next.next 22 | 23 |                             ^ 24 |                     |_____| 25 | 26 | 27 | 28 | ## 要注意的问题 29 | (1)要删除节点是头结点 30 | 31 | (2)要删除节点是为节点(顺序遍历找到尾节点的上一个节点,并删除) 32 | 33 | 34 | 35 | ## [源码](/algorithms-java-example/src/main/java/space.mamba/coding/interviews/No13_DeleteNode.java) 36 | -------------------------------------------------------------------------------- /剑指offer/14、使数组中的奇数位于偶数前面.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # 使数组中的奇数位于偶数前面 4 | 5 | 6 | ## 解题思路: 7 | 其实我想到的第一个思路就是用双指针从两端向中间扫描,处理过程与快排很相似,时间复杂度o(n),这应该是最快的解法了。 8 | 思路简单,就当复习下快排吧 9 | 10 | 书中提到了一点,是将判断部分写成函数,这样能够提升代码的可扩展性,这的确是很好的一个提醒。 11 | 那样处理之后,这一类问题(非负数在前,负数在后;能被3整除的在前,不能的在后;)都只需修改下判断函数即可解决。 12 | 13 | 14 | - [代码](/algorithms-java-example/src/main/java/space.mamba/coding/interviews/No14_ReorderOddEven.java) 15 | -------------------------------------------------------------------------------- /剑指offer/15、找链表中倒数第K个节点.md: -------------------------------------------------------------------------------- 1 | 2 | ## [原文](https://blog.csdn.net/u013132035/article/details/80467023) 3 | 4 | # 找链表中倒数第K个节点 5 | 6 | ## 思路: 7 | 用两个指针,第一个指针先走k-1步,然后两个指针一起走, 8 | 当第一个指针走到尾节点的时候。第二个指针指向的就是倒数第k个节点。 9 | 10 | 11 | - [代码](/algorithms-java-example/src/main/java/space.mamba/coding/interviews/No15_FindList_Last_K_Node.java) 12 | -------------------------------------------------------------------------------- /剑指offer/16、输出反转后的链表.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # 输出反转后的链表 4 | 5 | 解题思路 6 | 设置三个指针,head为当前节点,pre为当前节点的前一个节点,next为当前节点的下一个节点, 7 | 需要pre和next的目的是让当前节点从pre->head->next1->next2变成pre<-head next1->next2的过程中, 8 | 用pre让节点反转所指方向,next节点保存next1节点防止链表断开 9 | 10 | 需要注意的点: 11 | - 1、如果输入的头结点是null,则返回null 12 | - 2、链表断裂的考虑 13 | 14 | 15 | - [代码](/algorithms-java-example/src/main/java/space.mamba/coding/interviews/No16_ReverseList.java) 16 | 17 | -------------------------------------------------------------------------------- /剑指offer/17、合并两个有序链表.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # 合并两个有序链表 4 | 5 | > 题目:已知两个链表head1 和head2 各自有序,请把它们合并成一个链表依然有序 6 | 7 | 使用最原始的办法,定义一个头指针 dummy,遍历两个链表,根据链表节点,进行连接,直到一个链表为空为止, 8 | 再将 dummy 和剩下的一个链接起来。 9 | 10 | - [代码](/algorithms-java-example/src/main/java/space.mamba/coding/interviews/No17_MergeSortListNode.java) 11 | 12 | 类似题目 13 | 14 | - [合并有序数组](../11、leetcode/88、88.%20Merge%20Sorted%20Array.md) 15 | -------------------------------------------------------------------------------- /剑指offer/18、判断二叉树A中是否包含子树B.md: -------------------------------------------------------------------------------- 1 | 2 | ## [原文]() 3 | 4 | # 判断二叉树A中是否包含子树B 5 | 6 | > ps:我们约定空树不是任意一个树的子结构 7 | 8 | ## 思路 9 | 10 | 先从根节点开始判断, 11 | 12 | 1. 如果根节点相同,则从头遍历 13 | 14 | 2. 如果根不同,则从左右两个遍历,任意一个含有B树都可以,如果失败则递归 15 | doesTree1HasTree2函数负责递归两个遍历两个树,直到B树为空则返回true其余都是false 16 | 17 | - [代码](/algorithms-java-example/src/main/java/space.mamba/coding/interviews/No18_HasSubTree.java) 18 | -------------------------------------------------------------------------------- /剑指offer/20、顺时针打印矩阵.md: -------------------------------------------------------------------------------- 1 | 2 | ## [原文](https://blog.csdn.net/yiyiwudian/article/details/46707875) 3 | 4 | # 顺时针打印矩阵(蛇形打印) 5 | 6 | > 之前面试美团就被问到这个问题,面试官说 蛇形打印。。。 7 | 8 | ## 题目:输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。例如:如果输入如下矩阵: 9 | ``` 10 |     1       2       3      4 11 |     5       6       7      8 12 |     9      10     11     12 13 |    13     14     15     16 14 | ``` 15 | 则依次打印出数字1、2、3、4、8、12、16、15、14、13、9、5、6、7、11、10。 16 | 17 | ## 思路: 18 | 19 | - 循环地进行从左到右,从上到下,从右到左,从下到上的打印“年轮”上的元素。 20 | 21 | 22 | ## [代码](/algorithms-java-example/src/main/java/space.mamba/coding/interviews/No19_ClockwisePrintingMatrix.java) 23 | -------------------------------------------------------------------------------- /剑指offer/21、包含min函数的栈.md: -------------------------------------------------------------------------------- 1 | 2 | ## [原文](https://www.jianshu.com/p/5e5dff9becd7) 3 | 4 | # 包含min函数的栈 5 | 6 | ## 题目:定义栈的数据结构,请在该类型中实现一个能够得到栈最小元素的min函数。 7 | 8 | ## 解题思路 9 | 10 | - 1、这道题需要用到两个栈,一个是数据栈,一个是辅助栈 11 | 12 | - 2、每次入栈的时候,辅助栈如果是空的,或者本次入栈的数据不大于栈顶,直接入栈,比如2,1,1(数据栈)和2,1,1(辅助栈); 13 | 否则压入的是当前栈顶的复制值,比如2,3,4(数据栈)和2,2,2(辅助栈),从而保证数据栈里面的最小值永远在辅助栈的栈顶 14 | 15 | - 3、需要注意的是,实例化栈的时候,一定要传入一个泛型参数(本题中的栈存储的只能是int类型的值),否则比较大小的时候会出错(node <= min.peek()) 16 | 17 | - 4、访问栈顶元素用peek方法,而不是top方法 18 | 19 | - [例子代码](/algorithms-java-example/src/main/java/space.mamba/coding/interviews/No21_StackMin.java) 20 | 21 | 22 | -------------------------------------------------------------------------------- /剑指offer/22、判断一个栈是否是另一个栈的弹出序列.md: -------------------------------------------------------------------------------- 1 | 2 | ## [原文](https://www.jianshu.com/p/e39ff6a1b3ee) 3 | 4 | # 判断一个栈是否是另一个栈的弹出序列 5 | 6 | ## 题目: 7 | 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。 8 | 假设压入栈的所有数字均不相等。例如序列1、2、3、4、5是某栈的压栈序列, 9 | 序列4、5、3、2、1是该压栈序列对应的一个弹出序列,但4、3、5、1、2就不可能是该压栈序列的弹出序列。 10 | 11 | ## 思路: 12 | 13 | 首先借助一个辅助栈,把输入的第一个序列中的数字依次压入该辅助栈,并按照第二个序列的顺序依次从该栈中弹出数字。 14 | 15 | 以4、 5、 3、 2 、1为例分析: 16 | 17 | ![](../images/coding_offer/stack_1.png) 18 | 19 | 20 | 再以4、3、5、1、2为例分析: 21 | 22 | ![](../images/coding_offer/stack_2.png) 23 | 24 | 25 | 从上面的两个例子可以找到判断一个序列是不是栈的弹出序列的规律: 26 | 27 | - 如果下一个弹出的数字刚好是栈顶数字,那么直接弹出。 28 | 29 | - 如果下一个弹出的数字不在栈顶,我们把压栈序列中还没有入栈的数字压入辅助栈,直到把下一个需要弹出的数字压入栈顶为止。 30 | 31 | - 如果所有的数字都压入栈了仍然没有找到下一个弹出的数字,那么该序列就不可能是一个弹出序列。 32 | 33 | ## 思路二 34 | 35 | - 步骤1:栈压入序列第一个元素,弹出序列指针指弹出序列的第一个; 36 | 37 | - 步骤2:判断栈顶元素是否等于弹出序列的第一个元素: 38 | 39 | - 步骤2.1:如果不是,压入另一个元素,进行结束判断,未结束则继续执行步骤2; 40 | 41 | - 步骤2.2:如果是,栈弹出一个元素,弹出序列指针向后移动一位,进行结束判断,未结束则继续执行步骤2; 42 | 43 | 结束条件:如果弹出序列指针还没到结尾但已经无元素可压入,则被测序列不是弹出序列。 44 | 如果弹出序列指针以判断完最后一个元素,则被测序列是弹出序列。 45 | 46 | 47 | - [代码实现](/algorithms-java-example/src/main/java/space.mamba/coding/interviews/No22_IsPopOrder.java) 48 | -------------------------------------------------------------------------------- /剑指offer/23、1.层序遍历二叉树.md: -------------------------------------------------------------------------------- 1 | ## [原文](https://www.jianshu.com/p/e39ff6a1b3ee) 2 | 3 | # 层序遍历二叉树(从上到下打印二叉树) 4 | 5 | > 这道题实质是考查树的层次遍历(广度优先遍历)算法: 6 | 7 | ## 题目要求: 8 | 从上到下打印二叉树的每个节点,同一层的节点按照从左到右的顺序打印。 9 | 10 | ## 解题思路: 11 | 这道题就是二叉树的层序遍历。使用一个队列,进行广度优先遍历即可。 12 | 13 | > 扩展:如何广度优先遍历一个有向图?这同样也可以基于队列实现。 14 | 树是图的一种特殊退化形式,从上到下按层遍历二叉树,从本质上来说就是广度优先遍历二叉树。 15 | 16 | 17 | - [代码实现](/algorithms-java-example/src/main/java/space.mamba/coding/interviews/No23_PrintTreeFromTopToBottom.java) 18 | -------------------------------------------------------------------------------- /剑指offer/23、2.分行从上到下打印二叉树.md: -------------------------------------------------------------------------------- 1 | ## [原文](https://www.jianshu.com/p/bca35632cc76) 2 | 3 | # 分行从上到下打印二叉树 4 | 5 | ## 面试题32.2:分行从上到下打印二叉树 6 | 7 | ## 题目要求: 8 | 从上到下按层打印二叉树,同一层的节点按从左到右的顺序打印 ,每一层打印一行。 9 | 10 | ## 解题思路: 11 | 同样是层序遍历,与上一题不同的是,此处要记录每层的节点个数, 12 | 在每层打印结束后多打印一个回车符。 13 | 14 | 15 | - [代码实现](/algorithms-java-example/src/main/java/space.mamba/coding/interviews/No23_printTreeInLine.java) 16 | -------------------------------------------------------------------------------- /剑指offer/24、后序遍历二叉搜索树.md: -------------------------------------------------------------------------------- 1 | 2 | ## [原文](https://www.jianshu.com/p/49aaf6e0491d) 3 | 4 | # 后序遍历二叉搜索树 5 | 6 | > 二叉搜索树的性质(左子树小于根节点,右子树大于根节点) 7 | 8 | ## 题目要求: 9 | 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果,假设输入数组的任意两个数都互不相同。 10 | 11 | ## 解题思路: 12 | 二叉搜索树的中序遍历是有序的,而此题是后序遍历。 13 | 后序遍历可以很容易找到根节点,然后根据二叉搜索树的性质(左子树小于根节点,右子树大于根节点), 14 | 可以将序列分为根节点的左子树部分与右子树部分,而后递归判断两个子树。 15 | 16 | -------------------------------------------------------------------------------- /剑指offer/25、二叉树中和为某值的路径.md: -------------------------------------------------------------------------------- 1 | 2 | ## [原文](https://www.jianshu.com/p/6c1d5cd26020) 3 | 4 | # 二叉树中和为某值的路径 5 | 6 | ## 题目要求: 7 | 8 | 输入一棵二叉树和一个整数,打印出二叉树中节点值的和为输入整数的所有路径。从树的根节点开始往下一直到叶节点所经过的节点形成一条路径。 9 | 10 | ## 解题思路: 11 | 12 | 需要得到所有从根节点到叶节点的路径,判断和是否为给定值。自己写一个小的二叉树,通过模拟上述过程,发现获取所有路径的过程与前序遍历类似。 13 | 因此,可以对给定二叉树进行前序遍历。当被访问节点时叶节点时,判断路径和是否为给定值。此外,为了记录路径上的节点,需要一个数组。 14 | 15 | 16 | - [代码实现](/algorithms-java-example/src/main/java/space.mamba/coding/interviews/No25_FindBinaryTreePath.java) 17 | -------------------------------------------------------------------------------- /剑指offer/26、复杂链表的复制.md: -------------------------------------------------------------------------------- 1 | 2 | ## [原文](https://www.jianshu.com/p/e6eea3a0aa43) 3 | 4 | # 复杂链表的复制 5 | 6 | ## 题目要求: 7 | 8 | 在复杂链表中,每个节点除了有一个next指针指向下一个节点,还有一个random指针指向链表中的任意节点或null,请完成一个能够复制复杂链表的函数。 9 | 10 | ## 解题思路: 11 | 此题定义了一种新的数据结构,复杂链表。与传统链表的区别是多了一个random指针。本题的关键点也就在如何高效地完成random指针的复制。 12 | 13 | -------------------------------------------------------------------------------- /剑指offer/31、连续子数组的最大和.md: -------------------------------------------------------------------------------- 1 | 2 | # 连续子数组的最大和 3 | 4 | ## 方法一:暴力枚举子数组 5 | 思路 6 | - 一个长度为n的数组,共有n(n+1)/2个子数组,计算出所有子数组的和, 7 | 最快需要O(n^2)的时间复杂度,虽然完成了计算,但是时间复杂度 O(n^2) 8 | 9 | ## 方法二:找规律 10 | 思路 11 | - 记录两个数,最大的子数组和+累加子数组和 12 | 遍历数组,随时更新最大的子数组和 13 | 一旦累加数为负数,直接放弃,将累加子数组和设置为0 14 | 15 | ## 方法三:[动态规划](../00、基础知识/17、动态规划.md) 16 | 思路 17 | 18 | - 动态规划: 19 | - 状态转移方程:dp[i] = max(dp[i-1] + nums[i], nums[i]),其中dp[i]表示以索引i为结束点基准的子数组的最大值。 20 | - 初始状态:dp[0]= nums[0]。 21 | 22 | 23 | ## 例子题目 24 | 输入一个整型数组,数组里有正数也有负数。数组中一个或连续的多个整数组成一个子数组。求所有子数组的和的最大值。要求时间复杂度为O(n)。 25 | 26 | ## 例子说明: 27 | 28 | 例如输入的数组为{1, -2, 3, 10, -4, 7, 2, -5}, 29 | 最大的子数组为{3, 10, -4, 7, 2}。 30 | 因此输出为该子数组的和18 31 | 32 | 33 | [实现例子](/algorithms-java-example/src/main/java/space.mamba/coding/interviews/No31_FindGreatestSumOfSubArray.java) 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /剑指offer/32、从1到整数n中1出现的次数.md: -------------------------------------------------------------------------------- 1 | ##### [原文](https://blog.csdn.net/Koala_Tree/java/article/details/79524603) 2 | 3 | ##### [参考](https://blog.csdn.net/yi_Afly/article/details/52012593) 4 | 5 | # 从1到整数n中1出现的次数 6 | 7 | 8 | ## 解决思路 9 | 10 | - 常规思路(暴力解决),一个数一个数的计数 11 | 12 | 累加 1 到 n 中每个整数 1 出现的次数。我们可以每次通过对 10 求余数判断整数的个位数字是不是 1。 13 | 如果这个数字大于 10,除以 10 之后再判断个位数字是不是 1 。 14 | 15 | > 直接遍历这些整数,转化为字符串,统计每个中1出现的次数。没有考虑时间效率。 16 | 17 | - 寻找数学规律 18 | 19 | 这里的 X∈[1,9],因为 X=0 不符合下列规律,需要单独计算。 20 | 21 | 首先要知道以下的规律: 22 | ``` 23 | 这种解法寻求数字的规律,时间复杂度低; 24 | 首先要知道以下的规律: 25 | 26 | 27 | 以21354为例,寻找1出现的次数: 28 | 29 | 个位:从1至21350中包含了2135个10,因此1出现了2135次,21351,21352,21353,21354其中21351包含了一个1,故个位出现1的次数为:2135*10(1-1) + 1 = 2136次; 30 | 31 | 公式:( 2135+1)* 10^(1-1) = 2136; 32 | 33 | 十位:从1到21300中包含了213个100,因此1出现了213 * 10^(2-1) = 2130次,剩下的数字是21301到21354,它们的十位数字是5 > 1;因此它会包含10个1;故总数为2130 + 10 = 2140次; 34 | 35 | 公式:(213 + 1)* 10^(2-1) = 2140次; 36 | 37 | 百位:从1到21000中包含了21个1000,因此1出现了21 * 10^(3-1) = 2100次,剩下的数字是21001到21354,它们的百位数字是3 > 1;因此它会包含100个1;故总数为2100 + 100 = 2200次; 38 | 39 | 公式:(21 + 1)* 10^(3-1) = 2200次; 40 | 41 | 千位:从1到20000中包含了2个10000,因此1出现了2 * 10^(4-1) = 2000次,剩下的数字是20001到21354,它们的千位数字是1 = 1;情况稍微复杂些,354 + 1 = 355;故1的总数为2000 + 355 = 2355次; 42 | 43 | 公式:2 * 10^(4-1) + 354 + 1 = 2355次; 44 | 45 | 万位:万位是2 > 1,没有更高位;因此1出现的次数是1 * 10^(5-1) = 10000次; 46 | 47 | 公式:(0 + 1)*10^(5-1) = 10000次; 48 | 49 | 故总共为:2136+2140+2200+2355+10000=18831次; 50 | 51 | 故总结: 52 | 53 | 1、取第 i 位左边的数字(高位),乘以 10 ^(i−1) ,得到基础值 a 。 54 | 2、取第 i 位数字,计算修正值:  55 | 1、如果大于 X,则结果为 a+ 10 ^(i−1) 。 56 | 2、如果小于 X,则结果为 a 。 57 | 3、如果等 X,则取第 i 位右边(低位)数字,设为 b ,最后结果为 a+b+1 。 58 | 59 | ``` 60 | 61 | [实践例子](/algorithms-java-example/src/main/java/space.mamba/coding/interviews/No32_CountNumber.java) 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /剑指offer/33、把数组中的数排成一个最小的数.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # 把数组中的数排成一个最小的数 4 | 5 | 6 | ## 题目: 7 | 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个。 8 | 9 | ## 例子 10 | 例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323。 11 | 12 | ## 思路 13 | 14 | 思路一 15 |   不好的方法:求出所有全排列(类似字符串的排列 ),将数字拼起来,最后求出所有的最小值。这效率太低,且没有考虑到大数问题。 16 | 17 | 思路二: 18 | 找规律排序,要对3,32 ,321 排序,不能直接比较32,3的大小,应该比较323,332的大小, 19 | 即,3,32的大小应该有323,332的大小来确定。因此3比32大,3应该在32后面,32和321比较时,32321>32132, 20 | 因此32>321,32在321后面,3,32,321由小到大排序为,321,32,3,组成的最小数为:321323 21 | 22 | - 好的方法:观察规律,自行定义一种排序规则。 23 | 24 |   对于数字m和n,可以拼接成mn和nm,如果mn list, Comparator c)方法进行排序。 30 | Comparator中重写compare()方法来规定比较规则。 31 | 32 | ## 实践 33 | 34 | [自行定义一种排序规则](/algorithms-java-example/src/main/java/space.mamba/coding/interviews/No33_ArrayConvertSmallestNumber.java) 35 | -------------------------------------------------------------------------------- /剑指offer/34、求第N个丑数.md.md: -------------------------------------------------------------------------------- 1 | ##### [原文](https://segmentfault.com/a/1190000015720743) 2 | 3 | # 求第N个丑数 4 | 5 | ## 题目描述 6 |  把只包含因子2、3和5的数称作丑数(Ugly Number)。 7 | 例如6、8都是丑数,但14不是,因为它包含因子7。 8 | 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。 9 | 10 | > 8 被 2 和 4 整除,但是 4 又被 2 整除【因子包含 2】 11 | 12 | ## 丑数的定义: 13 | 14 | 所谓丑数,就是不能被2,3,5以外的其他素数整除的数。1,2,3,4,5,6,8,9,10,12,15是最前面的11个丑数。(1不是素数) 15 | 16 | ## 基本思路 17 | 18 | ### 暴力解法: 19 | 20 | 如果一个数是丑数,那么这个数,如果能被2整除,就一直除以2,如果能被3整除就一直除以3,如果能被5整除,就一直除以5,最后的结果一定是1。 21 | 按照这种思路,从数字1开始判断直到第N个丑数出现即可。 22 | 23 | ### 动态规划: 24 | > 动态规划思想。后面的丑数一定是由前面的丑数乘以2、3或5得到 25 | 26 | 这种暴力解法存在大量的重复计算,例如:现在分析12是不是丑数,12/2=6,而6我们已经知道是丑数了, 27 | 已经不需要向下计算了。因此我们可以记忆化:将丑数记录下来。  28 | 29 | 这个题目有重叠子问题,考虑使用动态规划。我们不妨假设DP[n]表示第n个丑数,这个丑数就等于前面几个丑数*2或者*3或者*5的最小值, 30 | 并且丑数的位置只会向后移,我们不妨假设三个i j k分别为*2 *3 *5的丑数位置。由此我们可以写出 状态转移方程: 31 | 32 | dp[n] = min{dp[i]*2,dp[j]*3,dp[k]*5} 33 | 34 | ##### 举个栗子 35 | 现在已知6个丑数 1 2 3 4 5 6, 求第7个丑数。 36 | 37 | 可以翻译成:假设dp[i]表示第i个丑数的数值,已知丑数的个数为count=6, 38 | 且前6个丑数 dp[1]=1;dp[2]=2;dp[3]=3;dp[4]=4;dp[5]=5;dp[6]=6; 求dp[7]。 39 | 40 | 则dp[7]可能有三种情况: 41 | ``` 42 | 从i=1开始按顺序求v = dp[i]*2,当v>dp[6],可以停止,则第4个丑数乘2得到的8可能是第7个丑数。 43 | 从i=1开始按顺序求v = dp[i]*3,当v>dp[6],可以停止,则第3个丑数乘3得到的9可能是第7个丑数。 44 | 从i=1开始按顺序求v = dp[i]*5,当v>dp[6],可以停止,则第3个丑数乘5得到的10可能是第7个丑数。 45 | 取三种情况的最小值,得到8,就是第7个丑数,即dp[7] = 8。 46 | ``` 47 | 依此类推,可以求得第8个丑数。 48 | 49 | 注意,这里有个小优化,按顺序搜索的时候`并不需要每次都从1开始`,只需要从上次搜索的结束点继续搜索就行了。 50 | 51 | 例如求dp[8],同样有三种情况: 52 | ``` 53 | 从i=4开始按顺序求v = dp[i]*2,当v>dp[7],可以停止,则第5个丑数乘2得到的10可能是第8个丑数。 54 | 从i=3开始按顺序求v = dp[i]*3,当v>dp[7],可以停止,则第3个丑数乘3得到的9可能是第8个丑数。 55 | 从i=2开始按顺序求v = dp[i]*5,当v>dp[7],可以停止,则第2个丑数乘5得到的10可能是第8个丑数。 56 | 取三种情况的最小值,得到10,即dp[8] = 9。 57 | ``` 58 | 59 | ### 实践例子 60 | 61 | [No34_UglyNumber](/algorithms-java-example/src/main/java/space.mamba/coding/interviews/No34_UglyNumber.java) 62 | -------------------------------------------------------------------------------- /剑指offer/35、第一个出现一次的字符.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # 第一个出现一次的字符 4 | 5 | ## 题目描述 6 | 在一个字符串(0<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置, 如果没有则返回 -1. 7 | 8 | ## 解题思路 9 | 10 | 先在hash表中统计各字母出现次数,第二次扫描直接访问hash表获得次数。也可以用数组代替hash表。 11 | 12 | 13 | ## 实践例子 14 | 15 | [No35_FirstFindOnceChar](/algorithms-java-example/src/main/java/space.mamba/coding/interviews/No35_FirstFindOnceChar.java) 16 | -------------------------------------------------------------------------------- /剑指offer/36、数组中逆序对的个数.md: -------------------------------------------------------------------------------- 1 | 2 | ##### [参考](https://juejin.im/post/5b6cfb746fb9a04fae213694) 3 | 4 | #### [参考](https://www.jianshu.com/p/c7f98f5cc918) 5 | 6 | # 数组中逆序对的个数 7 | 8 | ## 题目 9 | 在数组中的两个数字如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。 10 | 输入一个数组,求出这个数组中的逆序对的总数。 11 | 12 | ## 举例分析 13 |   例如在数组{7, 5, 6, 4 }中, 一共存在5 个逆序对,分别是(7, 6)、(7,5),(7, 4)、(6, 4)和(5, 4)。 14 | 15 | ## 解题思路 16 | 17 | ### 第一种::暴力解法 18 | 19 |   顺序扫描整个数组。每扫描到一个数字的时候,逐个比较该数字和它后面的数字的大小。 20 | 如果后面的数字比它小,则这两个数字就组成了一个逆序对。假设数组中含有n 个数字。 21 | 由于每个数字都要和O(n)个数字作比较, 因此这个算法的时间复杂度是O(n^2)。 22 | 23 | ### 第二种:分治思想,采用归并排序的思路来处理 24 | 25 | > 归并排序 26 | 27 | 上述思路在进行比较后,并没有将相关信息留下,其实在比较之后可以进行局部的排序,从而降低比较的次数,降低时间复杂度。 28 | 可通过如下步骤求逆序对个数:先把数组逐步分隔成长度为1的子数组,统计出子数组内部的逆序对个数, 29 | 然后再将相邻两个子数组合并成一个有序数组并统计数组之间的逆序对数目,直至合并成一个大的数组。 30 | 其实,这是二路归并的步骤,只不过在归并的同事要多进行一步统计。因此时间复杂度o(nlogn),空间复杂度o(n), 31 | 如果使用原地归并排序,可以将空间复杂度降为o(1)。 32 | 33 | 本文使用经典二路归并排序实现。以{7,5,6,4}为例,过程如下: 34 | ``` 35 | 36 | [7 5 6 4] 37 | / \ 分:将长度为4的数组分成长度为2的数组 38 | [7 5] [6 4] 39 | / \ / \ 分:将长度为2的数组分成长度为1的数组 40 | [7] [5] [6] [4] 41 | \ / \ / 和:1->2,并记录子数组内的逆序对 42 | [5 7] [4 6] 43 | \ / 和:2->4,并记录子数组内的逆序对 44 | [4 5 6 7] 45 | ``` 46 | 47 | [No36_InversePairsCore](/algorithms-java-example/src/main/java/space.mamba/coding/interviews/No36_InversePairsCore.java) 48 | -------------------------------------------------------------------------------- /剑指offer/37、两个链表的第一个公共节点.md: -------------------------------------------------------------------------------- 1 | 2 | ##### [原文](https://www.jianshu.com/p/bad5c698f1fd) 3 | 4 | # 两个链表的第一个公共节点 5 | 6 | 题目描述:输入两个链表,找出它们的第一个公共节点。 7 | 8 | ## 解法 1: 遍历+哈希表记录 9 | 比较容易想到的思路: 10 | - 开辟哈希表 map。key 是节点,value 是 boolean,代表节点是否出现过 11 | - 对 list1 进行遍历,设置 map[节点]=true 12 | - 对 list2 进行遍历,如果节点在 map 中出现过,那么说明这是两个链表的公共节点,返回 13 | 14 | 时间复杂度是O(N),空间复杂度是O(N) 15 | 16 | ## 解法 2: 快慢指针 17 | 18 | 我们使用两个指针 node1,node2 分别指向两个链表 headA,headB 的头结点,然后同时分别逐结点遍历, 19 | 当 node1 到达链表 headA 的末尾时,重新定位到链表 headB 的头结点;当 node2 到达链表 headB 的末尾时, 20 | 重新定位到链表 headA 的头结点。 21 | 22 | 这样,当它们相遇时,所指向的结点就是第一个公共结点。 23 | 24 | 时间复杂度是O(N),空间复杂度是O(1)。 25 | 26 | 27 | ## 实践 28 | 29 | [No37_IntersectionNode](/algorithms-java-example/src/main/java/space.mamba/coding/interviews/No37_IntersectionNode.java) 30 | 31 | -------------------------------------------------------------------------------- /剑指offer/38、字符串的排列.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | # 字符串的排列 5 | 6 | 输入一个字符串,打印出该字符串中字符的所有排列。 7 | 8 |   9 | 你可以以任意顺序返回这个字符串数组,但里面不能有重复元素。 10 | 11 | 12 | ## 示例: 13 | ``` 14 | 输入:s = "abc" 15 | 输出:["abc","acb","bac","bca","cab","cba"] 16 | ``` -------------------------------------------------------------------------------- /剑指offer/38、数字在排序数组中出现的次数.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # 数字在排序数组中出现的次数 4 | 5 | ## 题目: 6 | 统计一个数字在排序数组中出现的次数。例如输入排序数组{1,2,3,3,3,3,4,5}和数字3, 7 | 由于3在这个数组中出现了4次,因此输出4。 8 | 9 | ## 解题思路 10 | 11 | > 看见有序,第一个想到二分查找。二分找到k的值,然后从这个位置向前向后找。 12 | ### 暴力求解 13 | 暴力,简单粗暴,但是并不可取 14 | 15 | ### 直接运用二分查找 16 | 17 | 既然输入的数组是排序的,那么我们很自然地就能想到用二分查找算法。 18 | 在题目给出的例子中,我们可以先用二分查找算法找到一个3。 19 | 由于3可能出现多次,因此我们找到的3的左右两边可能都有3,于是我们在找到的3的左右两边顺序扫描,分别找出第一个3和最后一个3。 20 | 因为要查找的数字在长度为n的数组中有可能出现O(n)次,所以顺序扫描的时间复杂度是O(n)。 21 | 因此这种算法的效率和直接从头到尾顺序扫描整个数组统计3出现的次数的方法是一样的。 22 | 23 | ### 改进运用二分查找 24 | > 还是二分查找的思想,先找到第一个k和最后一个k的位置相减 25 | 26 |  接下来我们思考如何更好地利用二分查找算法。假设我们是统计数字k在排序数组中出现的次数。 27 | 在前面的算法中时间主要消耗在如何确定重复出现的数字的第一个k和最后一个k的位置上,`有没有可能用二分查找算法直接找到第一个k及最后一个k呢`? 28 | 29 | 我们先分析如何用二分查找算法在数组中找到第一个k。二分查找算法总是先拿数组中间的数字和k作比较。 30 | - 如果中间的数字比k大,那么k只有可能出现在数组的前半段,下一轮我们只在数组的前半段查找就可以了。 31 | - 如果中间的数字比k小,那么k只有可能出现在数组的后半段,下一轮我们只在数组的后半段查找就可以了。 32 | - 如果中间的数字和k相等呢?我们先判断这个数字是不是第一个k。如果位于中间数字的前面一个数字不是k,此时中间的数字刚好就是第一个k。 33 | - 如果中间数字的前面一个数字也是k,也就是说第一个k肯定在数组的前半段,下一轮我们仍然需要在数组的前半段查找。 34 | 35 | ## 实践 36 | 37 | [No38_GetSortArrayNumCount](/algorithms-java-example/src/main/java/space.mamba/coding/interviews/No38_GetSortArrayNumCount.java) 38 | -------------------------------------------------------------------------------- /剑指offer/39、二叉树的深度.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # 二叉树的深度 4 | 5 | ## 题目描述 6 | 输入一棵二叉树,求该树的深度。 7 | > 从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的长度为树的深度。 8 | 9 | ## 思路 10 | 此题的递归思想比较简单,直接用递归将根节点的深度转换为求左右子孩子的深度的较大值+1, 11 | 根节点的深度等于max(左孩子的深度,右孩子的深度) 12 | 13 | 如果不使用递归,可以通过层序遍历(广度优先遍历)解决。 14 | 15 | ## 实践 16 | 17 | [No39_DepthInBTree](/algorithms-java-example/src/main/java/space.mamba/coding/interviews/No39_DepthInBTree.java) 18 | -------------------------------------------------------------------------------- /剑指offer/40、数组中只出现一次的两个数,而其他数都出现两次.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # 数组中只出现一次的两个数,而其他数都出现两次 4 | 5 | 一个整型数组里除了两个数字之外,其他的数字都出现了两次。 6 | 请写程序找出这两个只出现一次的数字。`要求时间复杂度是O(n),空间复杂度是O(1)`。 7 | 8 | ## 思路: 9 | 10 | - 大家首先想到的是`顺序扫描法`【暴力的双重FOR 循环】,但是这种方法的时间复杂度是O(n^2)。 11 | - 大家又会考虑`用哈希表`的方法,但是空间复杂度不是O(1)。 12 | 13 | 应该怎么做才能即满足时间复杂度是O(n)又满足空间复杂度是O(1)的要求呢? 14 | > 两个相同的数字异或等于0. 15 | 16 | 我们可以想一想“异或”运算的一个性质,我们直接举例说明。 17 | 18 | 举例:{2,4,3,6,3,2,5,5} 19 | 20 | 这个数组中只出现一次的两个数分别是4和6。怎么找到这个两个数字呢? 21 | 22 | 我们先不看找到俩个的情况,先看这样一个问题,如何在一个数组中找到一个只出现一次的数字呢?比如数组:{4,5,5},唯一一个只出现一次的数字是4。 23 | 24 | 我们知道异或的一个性质是:`任何一个数字异或它自己都等于0`。也就是说,如果我们从头到尾依次异或数组中的每一个数字, 25 | 那么最终的结果刚好是那个只出现一次的数字。比如数组{4,5,5}, 26 | 我们先用数组中的第一个元素4(二进制形式:0100)和数组中的第二个元素5(二进制形式:0101)进行异或操作,0100和0101异或得到0001, 27 | 用这个得到的元素与数组中的三个元素5(二进制形式:0101)进行异或操作,0001和0101异或得到0100,正好是结果数字4。 28 | 这是因为数组中相同的元素异或是为0的,因此就只剩下那个不成对的孤苦伶仃元素。 29 | 30 | 现在好了,我们已经知道了如何找到一个数组中找到一个只出现一次的数字,那么我们如何在一个数组中找到两个只出现一次的数字呢? 31 | 如果,我们可以将原始数组分成两个子数组,使得每个子数组包含一个只出现一次的数字,而其他数字都成对出现。 32 | 这样,我们就可以用上述方法找到那个孤苦伶仃的元素。 33 | 34 | 我们还是从头到尾一次异或数组中的每一个数字,那么最终得到的结果就是两个只出现一次的数组的异或结果。 35 | 因为其他数字都出现了两次,在异或中全部抵消了。由于两个数字肯定不一样,那么异或的结果肯定不为0, 36 | 也就是说这个结果数组的二进制表示至少有一个位为1。我们在结果数组中找到第一个为1的位的位置,记为第n位。 37 | 现在我们以第n位是不是1为标准把元数组中的数字分成两个子数组,第一个子数组中每个数字的第n位都是1,而第二个子数组中每个数字的第n位都是0。 38 | 39 | 举例:{2,4,3,6,3,2,5,5} 40 | 41 | 我们依次对数组中的每个数字做异或运行之后,得到的结果用二进制表示是0010。异或得到结果中的倒数第二位是1, 42 | 于是我们根据数字的倒数第二位是不是1分为两个子数组。第一个子数组{2,3,6,3,2}中所有数字的倒数第二位都是1, 43 | 而第二个子数组{4,5,5}中所有数字的倒数第二位都是0。接下来只要分别两个子数组求异或, 44 | 就能找到第一个子数组中只出现一次的数字是6,而第二个子数组中只出现一次的数字是4。 45 | 46 | 47 | ## 实践 48 | 49 | [No40_FindNumsAppearOnce](/algorithms-java-example/src/main/java/space.mamba/coding/interviews/No40_FindNumsAppearOnce.java) 50 | -------------------------------------------------------------------------------- /剑指offer/41、和为s的连续正数序列.md: -------------------------------------------------------------------------------- 1 | 2 | ##### [什么是滑动窗口,以及如何用滑动窗口解这道题(C++/Java/Python)](https://leetcode-cn.com/problems/he-wei-sde-lian-xu-zheng-shu-xu-lie-lcof/solution/shi-yao-shi-hua-dong-chuang-kou-yi-ji-ru-he-yong-h/) 3 | 4 | # 和为s的连续正数序列 5 | 6 | ## 题目描述 7 | 输入一个正整数s,打印出所有和为s的连续正整数序列(至少包含两个数字)。 8 | 9 | 例如输入15,所以打印出3个连续序列(1,2,3,4,5)(4,5,6)(7,8) 10 | 11 | ### 方法一:暴力求解 12 | 13 | 用两个数字begin和end分别表示序列的最大值和最小值, 14 | 15 | 首先将begin初始化为1,end初始化为2. 16 | 17 | 如果从begin到end的和大于s,我们就从序列中去掉较小的值(即增大begin), 18 | 19 | 相反,只需要增大end。 20 | 21 | 终止条件为:一直增加begin到(1+sum)/2并且end小于sum为止 22 | 23 | 时间复杂度仍然是O(n^2) 24 | 25 | ### 方法二: 滑动窗口法 26 | 27 | ## 实践 28 | 29 | [No41_FindContinuousSequences](/algorithms-java-example/src/main/java/space.mamba/coding/interviews/No41_FindContinuousSequences.java) 30 | -------------------------------------------------------------------------------- /剑指offer/42、翻转字符串.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # 翻转字符串 4 | 5 | ## 1、题目描述 6 | 例如,“student. a am I”。正确的输出应该是“I am a student.”。 7 | 8 | ## 2、解题思路 9 | 10 | ### 思路一 11 | 暴力空格拆分 12 | 13 | ### 思路二 14 | 15 | 【先反转整个数组,然后反转每个单词】 16 | 17 | 算法:句子翻转 + 单词翻转 18 | 19 | 第一步:翻转整个句子; 20 | 21 | 第二步:翻转每个单词。 22 | 23 | 注意:句子和单词的边界条件处理。 24 | 25 | 26 | ## 实践 27 | 28 | [No42_ReverseSentence](/algorithms-java-example/src/main/java/space.mamba/coding/interviews/No42_ReverseSentence.java) 29 | -------------------------------------------------------------------------------- /剑指offer/43、n个骰子的点数及出现的概率.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # n个骰子的点数及出现的概率 4 | 5 | ## 题目: 6 | 把n个骰子扔在地上,所有骰子朝上的一面的点数之和为s.输入n,打印出s的所有可能的值出现的概率。 7 | 8 | ## 思路标 9 | 10 | 算法:递归、动态规划 -------------------------------------------------------------------------------- /剑指offer/45、圆圈中最后剩下的数.md: -------------------------------------------------------------------------------- 1 | 2 | ##### [原文1](https://blog.csdn.net/DERRANTCM/article/details/46798717) 3 | 4 | # 圆圈中最后剩下的数(约瑟夫环问题) 5 | 6 | ## 题目 7 | 8 | 0, 1, … , n-1 这n个数字排成一个圈圈,从数字0开始每次从圆圏里删除第m个数字。 9 | 求出这个圈圈里剩下的最后一个数字 10 | 11 | ## 解题思路 12 | ### 第一种:经典的解法, 用环形链表模拟圆圈。 13 |   创建一个总共有n 个结点的环形链表,然后每次在这个链表中删除第m 个结点。 14 | 15 | 缺点:要模拟整个游戏过程,时间复杂度高达O(nm),当n,m非常大(例如上百万,上千万)的时候,几乎是没有办法在短时间内出结果的 16 | 17 | ### 约瑟夫环——公式法(递推公式) 18 | 19 | 递推公式: 20 | ``` 21 | f(N,M)=(f(N−1,M)+M)%Nf(N,M)=(f(N-1,M)+M)\%N 22 | 23 | f(N,M)=(f(N−1,M)+M)%N 24 | ``` 25 | 26 | 27 | 28 | 29 | 30 | 31 | ## 实践 32 | 33 | [No45_LastRemaining](/algorithms-java-example/src/main/java/space.mamba/coding/interviews/No45_LastRemaining.java) 34 | 35 | -------------------------------------------------------------------------------- /剑指offer/46、1+2+3+…+n的和.md: -------------------------------------------------------------------------------- 1 | ##### 2 | 3 | # 1+2+3+…+n的和 4 | 5 | ## 题目描述 6 | 求1+2+3+...+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。 7 | 8 | 那么显然这道题目难度提升了一个台阶,如果没做过这个类型的题目,可能会心中一揪,两眼一把黑。 9 | 10 | > 累加不能用循环的话,那就试试递归 11 | 12 | ## 解题思路 13 | 14 | 计算方法主要有三种:平均计算、迭代、递归。 15 | 16 | 这里可以通过递归的方式进行计算,但是很疑问的地方在于如何结束递归。 17 | 这里可以有多种的方式,基本方向是采用逻辑与或的方式来计算,与的时候通过n>0来短路, 18 | 这样在n=0的时候不需要计算递归的值,或的时候通过n==0来短路,在n=0的时候可以短路逻辑或运算。 19 | 20 | ## 实践 21 | 22 | [No46_SumSolution](/algorithms-java-example/src/main/java/space.mamba/coding/interviews/No46_SumSolution.java) 23 | -------------------------------------------------------------------------------- /剑指offer/47、不用加减乘除做加法.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # 不用加减乘除做加法 4 | 5 | 写一个函数,求两个整数之和,要求在函数体内不得使用 “+”、“-”、“*”、“/” 四则运算符号。 6 | 7 | ### 提示: 8 | 9 | a, b 均可能是负数或 0 10 | 结果不会溢出 32 位整数 11 | 12 | ## 解题思路 13 | 1、加法其实质为各位相加结果(不考虑进位)+ 进位值 14 | 15 | 2、各位相加结果(不考虑进位)等价于 加数二进制异或结果 16 | 17 | 进位值等价于加数按位与并向左移动一位 18 | 19 | 3、第一步和第二部反复迭代,最终没有进位,那么各位相加结果(不考虑进位)则是最终结果 20 | 21 | ## 实践 22 | 23 | [No47_Add](/algorithms-java-example/src/main/java/space.mamba/coding/interviews/No47_Add.java) 24 | 25 | 26 | -------------------------------------------------------------------------------- /剑指offer/48、不能被继承的类.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # 不能被继承的类 4 | 5 | 题目:用C++设计一个不能被继承的类。 6 | 7 | 该题因为Java有final关键字`表示一个类型不能被继承`,所以该题不能使用Java实现。 8 | 9 | 10 | ## 方法一:因为Java有final关键字`表示一个类型不能被继承 11 | 12 | ```java 13 | public final class FinalDemo { 14 | } 15 | ``` 16 | 17 | 18 | ## 方法二:声明构造方法为私有(private)的, 而且也声明一个静态方法(static method)来返回一个类对象。 19 | 20 | ```java 21 | public class jiekou { 22 | 23 | private jiekou(){ 24 | System.out.println("Private Default Constructor"); 25 | } 26 | public static jiekou getInstance(){ 27 | return new jiekou(); 28 | } 29 | } 30 | ``` 31 | 32 | -------------------------------------------------------------------------------- /剑指offer/49、字符串转换为整数.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # 字符串转换为整数 4 | 5 | ## 题目描述 6 | 7 | 将一个字符串转换成一个整数,要求不能使用字符串转换整数的库函数。 8 | 9 | > 如果是合法的数值表达则返回该数字,否则返回0 10 | 11 | 样例输入 12 | ``` 13 | 1a33 14 | 15 | -2147483648 16 | ``` 17 | 样例输出 18 | ``` 19 | 0 20 | 21 | -2147483648 22 | ``` 23 | 24 | ## 解题思路 25 | 26 | - 若输入有效,则首字符应该是在["+","-"]或者"0"~"9"中 27 | 28 | - 注意数值不要越界 29 | 30 | ## 实践 31 | 32 | [No49_StringToInteger](/algorithms-java-example/src/main/java/space.mamba/coding/interviews/No49_StringToInteger.java) 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /剑指offer/50、树中两个节点的最低公共祖先.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # 树中两个节点的最低公共祖先 4 | 5 | -------------------------------------------------------------------------------- /剑指offer/51、找出重复的数.md: -------------------------------------------------------------------------------- 1 | ##### [数组中重复的数字](https://www.cnblogs.com/AndyJee/p/4693099.html) 2 | 3 | # 找出重复的数 4 | 5 | ## 题目: 6 | 在一个长度为n的数组里的所有数字都在0到n-1的范围内。 7 | 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。 8 | 请找出数组中任意一个重复的数字。 9 | 10 | 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是重复的数字2或者3。 11 | 12 | ## 思路 13 | 14 | ### 1、排序 15 | 16 | 将数组排序,然后扫描排序后的数组即可。 17 | 18 | 时间复杂度:O(nlogn),空间复杂度:O(1) 19 | 20 | ### 2、哈希表 21 | 22 | 从头到尾扫描数组,每扫描到一个数字,判断该数字是否在哈希表中,如果该哈希表还没有这个数字, 23 | 那么加入哈希表,如果已经存在,则返回该数字; 24 | 25 | 时间复杂度:O(n),空间复杂度:O(n) 26 | 27 | ### 3、交换 28 | 29 | 0~n-1正常的排序应该是A[i]=i;因此可以通过交换的方式,将它们都各自放回属于自己的位置; 30 | 31 | 从头到尾扫描数组A,当扫描到下标为i的数字m时,首先比较这个数字m是不是等于i, 32 | 33 | 如果是,则继续扫描下一个数字; 34 | 35 | 如果不是,则判断它和A[m]是否相等,如果是,则找到了第一个重复的数字(在下标为i和m的位置都出现了m); 36 | 如果不是,则把A[i]和A[m]交换,即把m放回属于它的位置; 37 | 38 | 重复上述过程,直至找到一个重复的数字; 39 | 40 | 时间复杂度:O(n),空间复杂度:O(1) 41 | 42 | (将每个数字放到属于自己的位置最多交换两次) 43 | 44 | ### 4.用两层for循环 45 | 46 | 47 | 48 | ## 实践例子 49 | 50 | [No51_DuplicateNum](/algorithms-java-example/src/main/java/space.mamba/coding/interviews/No51_DuplicateNum.java) 51 | 52 | -------------------------------------------------------------------------------- /剑指offer/52、构建-乘积数组.md: -------------------------------------------------------------------------------- 1 | ##### [原文](https://blog.nowcoder.net/n/86b0194acf644f209e74093f892f42c6) 2 | 3 | 4 | 5 | 6 | 7 | # 构建乘积数组 8 | 9 | ## 题目: 10 | 给定一个数组A[0,1,...,n-1],请构建一个数组B[0,1,...,n-1],其中B中的元素B[i]=A[0]*A[1]*...*A[i-1]*A[i+1]*...*A[n-1]。 11 | 不能使用除法。 12 | 13 | ![](../images/coding_offer/Multiply.jpg) 14 | 15 | ## 思路: 16 | 17 | 我们发现,这题如果不让用除法,那就不能用最简单的O(n)来做。但是能否换种思路呢? 18 | 我们发现规律,连乘积是从中间某个位置断开的,如果我们从断开位置可以保存左右的状态,那么就没问题了。 19 | 怎么保持状态呢?在这个题目中只能用乘法。乘法要求公因子越来越多才有机会保存状态。 20 | 21 | ### 方法1: 22 | 23 | 两重循环,在遍历数组A的时候,A[i]赋值为1,计算B[i],时间复杂度:O(n^2) 24 | 25 | ### 方法2: 26 | 27 | 构建前向乘积数组C[i]=A[0]*A[1]*...*A[i-1],即C[i]=C[i-1]*A[i-1]; 28 | 29 | 构建后向乘积数组D[i]=A[n-1]*A[n-2]*...A[n-i+1],即D[i]=D[i+1]*A[i+1]; 30 | 31 | 通过C[i],D[i]来求B[i]:B[i]=C[i]*D[i] 32 | 33 | 时间复杂度:O(n) 34 | 35 | 36 | ## 实践例子 37 | 38 | [No52_Multiply](/algorithms-java-example/src/main/java/space.mamba/coding/interviews/No52_Multiply.java) 39 | 40 | 41 | -------------------------------------------------------------------------------- /剑指offer/53、正则表达式匹配.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # 正则表达式匹配 4 | 5 | ## 题目描述 6 | 请实现一个函数用来匹配包括.和*的正则表达式。模式中的字符.表示任意一个字符,而*表示它前面的字符可以出现任意次(包含0次)。 7 | 在本题中,匹配是指字符串的所有字符匹配整个模式。 8 | 例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但是与"aa.a"和"ab*a"均不匹配。 9 | 10 | 输入字符串为str,模式为pattern 11 | 12 | 13 | ## 思路 14 | 15 | ### 解法一 16 | 动态规划的思路。只要模式字符串当前为“.”,一定匹配,如果是当前不匹配,就需要看下一个字符串是否为“”来判断。 17 | 18 | ### 解法二 19 | 20 | 这题主要还是难在要考虑 * 的问题 如果模式匹配字符的下一个字符是 * : 如果pttern当前字符和str的当前字符匹配,:有以下三种可能情况 21 | 22 | pttern当前字符能匹配 str 中的 0 个字符:match(str, pattern+2) 23 | pttern当前字符能匹配 str 中的 1 个字符:match(str+1, pattern+2) 24 | pttern当前字符能匹配 str 中的 多个字符:match(str+1, pattern) 25 | 对于 . 的情况比较简单,. 和一个字符匹配 match(str+1, pattern+1) 要注意时刻判断当前要比较的字符的下标是否会数组越界 26 | 27 | 28 | --- 29 | 30 | 首先,对于*来说,它无法单独存在,只能跟在.或者字母之后。所以,我们可以把.*或者a*这样的组合看做是单个的组合字符。 31 | 定义:由.或者字母与*组成的组合字符,称之为通配符。 32 | 33 | 从第0项开头开始依次进行字符匹配,有几种情况?(暂不考虑到字符串结尾) 34 | 35 | p[0]是通配符 36 | 1.1 p[0] == '.'或者p[0] == s[0] 37 | 这说明第0项是可以匹配的。当然,也可以选择不将s[0]和p[0]进行匹配,例如: 38 | 字符串s = "a", p = "a*a",s[0]的a需要匹配p[2]的a,而不是p[0]的a*。 39 | 如果s[0]和p[0]匹配上了,那么接下来就让s[1]和p[0]匹配;反之则让s[0]和p[2]匹配。二者都能化成较小子集的问题,符合动态规划的需求。 40 | 1.2 否则,s[0]和p[0]匹配不上,那么就让s[0]和p[2]进行匹配。 41 | 42 | p[0]是字母 43 | 如果s[0] == p[0],匹配成功,接下来匹配s[1]和p[1]。 44 | 反之,匹配失败,返回false; 45 | 46 | p[0]是. 47 | 匹配成功,接下来配s[1]和p[1]。 48 | 49 | 总而言之,核心的思想是把大的问题转化为小一点的问题,递推得出最后的答案。 50 | 51 | 52 | ## 实践例子 53 | 54 | [No53_Pattern](/algorithms-java-example/src/main/java/space.mamba/coding/interviews/No53_Pattern.java) 55 | 56 | -------------------------------------------------------------------------------- /剑指offer/54、表示数值的字符串.md: -------------------------------------------------------------------------------- 1 | 2 | # 表示数值的字符串 3 | 4 | 请实现一个函数用来判断字符串是否表示数值(包括整数和小数)。 5 | 6 | 例如,字符串"+100"、"5e2"、"-123"、"3.1416"、"0123"都表示数值, 7 | 但"12e"、"1a3.14"、"1.2.3"、"+-5"、"-1E-16"及"12e+5.4"都不是。 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /剑指offer/55、字符流中第一个不重复的字符.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # 字符流中第一个不重复的字符 4 | 5 | ## 题目描述 6 | 7 | 请实现一个函数用来找出字符流中第一个只出现一次的字符。 8 | 例如,当从字符流中只读出前两个字符”go”时,第一个只出现一次的字符是”g”。 9 | 当从该字符流中读出前六个字符“google”时,第一个只出现一次的字符是”l”。 10 | 如果当前字符流没有存在出现一次的字符,返回#字符。 11 | 12 | -------------------------------------------------------------------------------- /剑指offer/56、链表中环的入口节点.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | # 链表中环的入口节点 5 | 6 | 给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。 7 | 8 | 为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 9 | 如果 pos 是 -1,则在该链表中没有环。注意,pos 仅仅是用于标识环的情况,并不会作为参数传递到函数中。 10 | 11 | 说明:不允许修改给定的链表。 12 | 13 | ## 进阶: 14 | 15 | 你是否可以使用 O(1) 空间解决此题? 16 |   17 | 18 | ### 示例 1: 19 | 20 | > 3->2->0->-4->2 21 | 22 | ``` 23 | 输入:head = [3,2,0,-4], pos = 1 24 | 输出:返回索引为 1 的链表节点 25 | 解释:链表中有一个环,其尾部连接到第二个节点。 26 | ``` 27 | 28 | ### 示例 2: 29 | 30 | > 1->2->1 31 | ``` 32 | 输入:head = [1,2], pos = 0 33 | 输出:返回索引为 0 的链表节点 34 | 解释:链表中有一个环,其尾部连接到第一个节点。 35 | ``` 36 | 示例 3: 37 | ``` 38 | 1->1 39 | 输入:head = [1], pos = -1 40 | 输出:返回 null 41 | 解释:链表中没有环。 42 | ``` 43 | 44 | ### 提示: 45 | ``` 46 | 链表中节点的数目范围在范围 [0, 104] 内 47 | -105 <= Node.val <= 105 48 | pos 的值为 -1 或者链表中的一个有效索引 49 | ``` 50 | 51 | ## 解决方案 52 | 53 | [No56_DetectCycle](/algorithms-java-example/src/main/java/space.mamba/coding/interviews/No56_DetectCycle.java) -------------------------------------------------------------------------------- /剑指offer/58、二叉树的下一个节点.md: -------------------------------------------------------------------------------- 1 | 2 | [原文](https://github.com/lwy2016/Leetcode/blob/master/SwordOffer/57.%E4%BA%8C%E5%8F%89%E6%A0%91%E7%9A%84%E4%B8%8B%E4%B8%80%E4%B8%AA%E8%8A%82%E7%82%B9.md) 3 | 4 | [原文](https://blog.nowcoder.net/n/788a8ff4beaa4f9cb118381e68b8ef7d) 5 | 6 | # 二叉树的下一个节点 7 | 8 | ## 题目描述 9 | 给定一个二叉树和其中的一个结点,请找出`中序遍历顺序`的`下一个结点`并且返回。 10 | 注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。 11 | 12 | ## 思路 13 | 分析二叉树的下一个节点,一共有以下情况: 14 | 15 | - 二叉树为空,则返回空; 16 | 17 | - 如果有右子树,则找右子树的最左节点 18 | 19 | - 没右子树,则找第一个当前节点是父节点左孩子的节点 如果节点是它父节点的左子节点, 20 | 那么它的下一个节点就是它的父节点 如果该节点既没有右子树, 21 | 且是父节点的右子节点,那么要找到该大块子树的根节点的父节点 22 | 23 | > 中序遍历(LDR)是二叉树遍历的一种,也叫做中根遍历、中序周游。在二叉树中,先左后根再右。巧记:左根右。 24 | 25 | ## 不去遍历,寻找下一节点的特性 26 | 27 | 根据中序遍历的规则,下一节点要么是左子树,要那么是父节点 28 | 29 | ``` 30 | A 31 | / \ 32 | B C 33 | / \ / \ 34 | D E F G 35 | / \ 36 | H I 37 | ``` 38 | 仔细观察,可以把中序下一结点归为几种类型: 39 | 40 | 有右子树,下一结点是右子树中的最左结点,例如 B,下一结点是 H 41 | 42 | 无右子树,且结点是该结点父结点的左子树,则下一结点是该结点的父结点,例如 H,下一结点是 E 43 | 44 | 无右子树,且结点是该结点父结点的右子树,则我们一直沿着父结点追朔, 45 | 直到找到某个结点是其父结点的左子树,如果存在这样的结点,那么这个结点的父结点就是我们要找的下一结点。 46 | 例如 I,下一结点是 A;例如 G,并没有符合情况的结点,所以 G 没有下一结点 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /剑指offer/60、按之字形顺序打印二叉树.md: -------------------------------------------------------------------------------- 1 | 2 | [剑指 Offer 32 - III. 从上到下打印二叉树 III](https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-iii-lcof) 3 | 4 | # 按之字形顺序打印二叉树 5 | 6 | 请实现一个函数按照之字形顺序打印二叉树,即第一行按照从左到右的顺序打印,第二层按照从右到左的顺序打印, 7 | 第三行再按照从左到右的顺序打印,其他行以此类推。 8 | 9 | 10 | ## 例如: 11 | 给定二叉树: [3,9,20,null,null,15,7], 12 | ``` 13 | 3 14 | / \ 15 | 9 20 16 | / \ 17 | 15 7 18 | ``` 19 | 返回其层次遍历结果: 20 | ``` 21 | [ 22 | [3], 23 | [20,9], 24 | [15,7] 25 | ] 26 | ``` 27 | 28 | [No60PrintBinaryTree](/algorithms-java-example/src/main/java/space.mamba/coding/interviews/No60PrintBinaryTree.java) -------------------------------------------------------------------------------- /剑指offer/61、I-从上到下打印二叉树.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | # 剑指 Offer 32 - I. 从上到下打印二叉树 5 | 6 | 7 | 从上到下打印出二叉树的每个节点,同一层的节点按照从左到右的顺序打印。 8 | 9 |   10 | 11 | 例如: 12 | 13 | 给定二叉树: [3,9,20,null,null,15,7], 14 | ``` 15 | 3 16 | / \ 17 | 9 20 18 | / \ 19 | 15 7 20 | ``` 21 | 返回: 22 | 23 | [3,9,20,15,7] 24 |   25 | 26 | 提示: 27 | 28 | 节点总数 <= 1000 29 | 30 | ## 思路 31 | 32 | 按`层次`输出二叉树 33 | 34 | 访问根节点,并将根节点入队。 35 | 36 | 当队列不空的时候,重复以下操作。 37 | ``` 38 | 弹出一个元素。作为当前的根节点。 39 | 如果根节点有左孩子,访问左孩子,并将左孩子入队。 40 | 如果根节点有右孩子,访问右孩子,并将右孩子入队。 41 | ``` 42 | 43 | 44 | [No61PrintBinaryTree_1](/algorithms-java-example/src/main/java/space.mamba/coding/interviews/No61PrintBinaryTree_1.java) -------------------------------------------------------------------------------- /剑指offer/61、II-把二叉树打印成多行.md: -------------------------------------------------------------------------------- 1 | ##### [原文](https://leetcode-cn.com/problems/cong-shang-dao-xia-da-yin-er-cha-shu-ii-lcof/solution/mian-shi-ti-32-ii-cong-shang-dao-xia-da-yin-er-c-5/) 2 | 3 | # 把二叉树打印成多行 4 | 5 | ## 题目描述 6 | 7 | 从上到下按层打印二叉树,同一层结点从左至右输出。每一层输出一行。 8 | 9 | 例如: 10 | ``` 11 | 给定二叉树: [3,9,20,null,null,15,7], 12 | 13 | 3 14 | / \ 15 | 9 20 16 | / \ 17 | 15 7 18 | 返回其层次遍历结果: 19 | 20 | [ 21 | [3], 22 | [9,20], 23 | [15,7] 24 | ] 25 | ``` 26 | 27 | 按层打印: 题目要求的二叉树的 从上至下 打印(即按层打印),又称为二叉树的 `广度优先搜索`(BFS)。 28 | BFS 通常借助 队列 的先入先出特性来实现。 29 | 30 | ## 思路 31 | 32 | 按`层次`输出二叉树 33 | 34 | 访问根节点,并将根节点入队。 35 | 36 | 当队列不空的时候,重复以下操作。 37 | ``` 38 | 39 | 当前层打印循环: 循环次数为当前层节点数(即队列 queue 长度) 40 | 41 | 弹出一个元素。作为当前的根节点。 42 | 如果根节点有左孩子,访问左孩子,并将左孩子入队。 43 | 如果根节点有右孩子,访问右孩子,并将右孩子入队。 44 | ``` 45 | 46 | 47 | [No61PrintBinaryTree_2](/algorithms-java-example/src/main/java/space.mamba/coding/interviews/No61PrintBinaryTree_2.java) -------------------------------------------------------------------------------- /剑指offer/62、序列化二叉树.md: -------------------------------------------------------------------------------- 1 | [](https://leetcode-cn.com/problems/serialize-and-deserialize-binary-tree/solution/er-cha-shu-de-xu-lie-hua-yu-fan-xu-lie-hua-by-le-2/) 2 | 3 | # 序列化二叉树 4 | 5 | ## 方法一:深度优先搜索 6 | 7 | ### 思路和算法 8 | 9 | 二叉树的序列化本质上是对其值进行编码,更重要的是对其结构进行编码。 10 | 可以遍历树来完成上述任务。众所周知,我们一般有两个策略:广度优先搜索和深度优先搜索。 11 | 12 | 广度优先搜索可以按照层次的顺序从上到下遍历所有的节点 13 | 14 | 深度优先搜索可以从一个根开始,一直延伸到某个叶,然后回到根,到达另一个分支。 15 | 根据根节点、左节点和右节点之间的相对顺序,可以进一步将深度优先搜索策略区分为: 16 | - 先序遍历 17 | - 中序遍历 18 | - 后序遍历 19 | 20 | 我们从根节点 1 开始,序列化字符串是 1,。然后我们跳到根节点 2 的左子树,序列化字符串变成 1,2,。 21 | 现在从节点 2 开始,我们访问它的左节点 3(1,2,3,None,None,)和右节点 4 22 | 23 | (1,2,3,None,None,4,None,None)。None,None, 是用来标记缺少左、右子节点, 24 | 这就是我们在序列化期间保存树结构的方式。 25 | 最后,我们回到根节点 1 并访问它的右子树,它恰好是叶节点 5。 26 | 最后,序列化字符串是 1,2,3,None,None,4,None,None,5,None,None,。 27 | 28 | 即我们可以先序遍历这颗二叉树,遇到空子树的时候序列化成 None,否则继续递归序列化。 29 | 那么我们如何反序列化呢?首先我们需要根据 , 把原先的序列分割开来得到先序遍历的元素列表,然后从左向右遍历这个序列: 30 | 31 | 如果当前的元素为 None,则当前为空树 32 | 否则先解析这棵树的左子树,再解析它的右子树 33 | 34 | ## 复杂度分析 35 | 36 | - 时间复杂度:在序列化和反序列化函数中,我们只访问每个节点一次,因此时间复杂度为 O(n)O(n),其中 nn 是节点数,即树的大小。 37 | 38 | - 空间复杂度:在序列化和反序列化函数中,我们递归会使用栈空间,故渐进空间复杂度为 O(n)O(n)。 39 | 40 | 41 | 42 | [No62_SerializeBinaryTree](/algorithms-java-example/src/main/java/space.mamba/coding/interviews/No62_SerializeBinaryTree.java) 43 | -------------------------------------------------------------------------------- /剑指offer/63、二叉搜索树的第k大节点.md: -------------------------------------------------------------------------------- 1 | 2 | [剑指 Offer 54. 二叉搜索树的第k大节点](https://leetcode-cn.com/problems/er-cha-sou-suo-shu-de-di-kda-jie-dian-lcof) 3 | 4 | # 二叉搜索树的第k大节点 5 | 6 | 二叉查找树(英语:Binary Search Tree),也称为 二叉搜索树、 7 | 有序二叉树(Ordered Binary Tree)或排序二叉树(Sorted Binary Tree), 8 | 是指一棵空树或者具有下列性质的二叉树: 9 | 10 | - 若任意节点的左子树不空,则左子树上所有节点的值均小于它的根节点的值; 11 | - 若任意节点的右子树不空,则右子树上所有节点的值均大于它的根节点的值 12 | 13 | 14 | 给定一棵二叉搜索树,请找出其中第k大的节点。 15 | 16 | 17 | ## 示例 1: 18 | 19 | 输入: root = [3,1,4,null,2], k = 1 20 | ``` 21 | 3 22 | / \ 23 | 1 4 24 | \ 25 |   2 26 | ``` 27 | 输出: 4 28 | 29 | ## 示例 2: 30 | 31 | 输入: root = [5,3,6,2,4,null,null,1], k = 3 32 | ``` 33 | 5 34 | / \ 35 | 3 6 36 | / \ 37 | 2 4 38 | / 39 | 1 40 | ``` 41 | 输出: 4 42 | 43 | ## 解题思路: 44 | 45 | > 本文解法基于此性质:二叉搜索树的中序遍历为 递增序列 46 | 47 | 根据以上性质,易得二叉搜索树的 中序遍历倒序 为 递减序列 。 48 | 49 | 因此,求 “二叉搜索树第 k 大的节点” 可转化为求 “此树的中序遍历倒序的第 k 个节点”。 50 | 51 | [No63BinarySearchTreeKNode](/algorithms-java-example/src/main/java/space.mamba/coding/interviews/No63BinarySearchTreeKNode.java) 52 | -------------------------------------------------------------------------------- /剑指offer/64、数据流中的中位数.md: -------------------------------------------------------------------------------- 1 | 2 | [剑指 Offer 41. 数据流中的中位数](https://leetcode-cn.com/problems/shu-ju-liu-zhong-de-zhong-wei-shu-lcof) 3 | 4 | # 数据流中的中位数 5 | 6 | 如何得到一个数据流中的中位数?如果从数据流中读出奇数个数值, 7 | 那么中位数就是所有数值排序之后位于中间的数值。 8 | 如果从数据流中读出偶数个数值,那么中位数就是所有数值排序之后中间两个数的平均值。 9 | 10 | ## 例如, 11 | 12 | [2,3,4]的中位数是 3 13 | 14 | [2,3] 的中位数是 (2 + 3) / 2 = 2.5 15 | 16 | 设计一个支持以下两种操作的数据结构: 17 | ``` 18 | void addNum(int num) - 从数据流中添加一个整数到数据结构中。 19 | double findMedian() - 返回目前所有元素的中位数。 20 | ``` 21 | 22 | ### 示例 1: 23 | 24 | 输入: 25 | ``` 26 | ["MedianFinder","addNum","addNum","findMedian","addNum","findMedian"] 27 | [[],[1],[2],[],[3],[]] 28 | 输出:[null,null,null,1.50000,null,2.00000] 29 | ``` 30 | 31 | ### 示例 2: 32 | 33 | 输入: 34 | ``` 35 | ["MedianFinder","addNum","findMedian","addNum","findMedian"] 36 | [[],[2],[],[3],[]] 37 | 输出:[null,null,2.00000,null,2.50000] 38 | ``` 39 | 40 | ## 限制: 41 | 42 | 最多会对addNum、findMedian 进行50000次调用。 43 | 44 | -------------------------------------------------------------------------------- /常见算法题目/0002、最小堆.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # 最小堆 -------------------------------------------------------------------------------- /常见算法题目/0003、Top-N算法的实现.md: -------------------------------------------------------------------------------- 1 | 2 | ## [原文1](https://blog.csdn.net/nupt123456789/article/details/12980431) 3 | 4 | 5 | # Top-N算法的实现 6 | 7 | 8 | 在搜索引擎中,如Lucene,搜索的结果是最相似 的前N条,那么如何从一个无序的数组中得到前N个最大(或最小)的值呢? 9 | 以下是我写的一个Top-N的演示程序。主要用到的数据结构是TreeSet,TreeSet会自动化实现插入排序, 10 | 前提是该类要实现Comparable接口。 11 | 12 | 13 | - [例子](/algorithms-java-example/src/main/java/space.mamba/coding/interviews/TopNDemo.java) 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /常见算法题目/0010、N皇后问题.md: -------------------------------------------------------------------------------- 1 | 2 | ## [漫画:什么是八皇后问题?](https://juejin.im/post/5accdb236fb9a028bb195562) 3 | 4 | ## [八皇后问题](https://zh.wikipedia.org/zh-hans/%E5%85%AB%E7%9A%87%E5%90%8E%E9%97%AE%E9%A2%98) 5 | 6 | ## [八皇后问题](https://www.zhihu.com/question/28543312/answer/41291172) 7 | 8 | # N皇后问题 9 | 10 | > 比如:8皇后的解怎么输出?我会告诉你,我们只要求输出解的个数, 11 | 其实,我们想要的是n皇后,对于任意一个n的值, 12 | 我们要求输出解的个数。n=1,输出1; n=2, 输出0; ...; n=8,输出92; ... -------------------------------------------------------------------------------- /常见算法题目/0032、经典算法-背包问题.md: -------------------------------------------------------------------------------- 1 | 2 | ## [原文](https://blog.csdn.net/lanyu_01/article/details/79815801) 3 | 4 | # 经典算法—背包问题 5 | 6 | ## 问题描述: 7 | 8 | 一个背包的总容量为V,现在有N类物品,第i类物品的重量为weight[i],价值为value[i] 9 | 那么往该背包里装东西,怎样装才能使得最终包内物品的总价值最大。这里装物品主要由三种装法: 10 | 11 | - 1、0-1背包:每类物品最多只能装一次 12 | 13 | - 2、多重背包:每类物品都有个数限制,第i类物品最多可以装num[i]次 14 | 15 | - 3、完全背包:每类物品可以无限次装进包内 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /常见算法题目/0060、 有两个int型的整数:x,y;不使用"if","? :","switch"等判断语句!找出a、b中最大的数!.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # 有两个int型的整数:x,y;不使用"if","? :","switch"等判断语句!找出a、b中最大的数! 4 | 5 | 6 | ## [代码实现](/algorithms-java-example/src/main/java/space.mamba/coding/interviews/MaxNumExample01.java) 7 | -------------------------------------------------------------------------------- /常见算法题目/0110、给你1到100万的连续整数,我从中取出一个数然后打乱数组,你给我求出被取出的是什么数.md: -------------------------------------------------------------------------------- 1 | ## [原文](https://www.jianshu.com/p/be015178b2a3) 2 | 3 | # 给你1到100万的连续整数,我从中取出一个数然后打乱数组,你给我求出被取出的是什么数。 4 | 5 | - 解决办法 6 | 7 | 用等差数列求和公式求出1到100万的和,然后再一一减去数组中的数字,就可以求出被取出的数了。 8 | 9 | 10 | 1. 求数组里面的和 11 | 2. 取一个数 12 | 3、和 减去数组中的值 13 | 14 | -------------------------------------------------------------------------------- /常见算法题目/0111、有两个int类型的数a和b,你能写出几种交换它们值的办法?越多越好.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # 有两个int类型的数a和b,你能写出几种交换它们值的办法?越多越好 4 | 5 | > 中间变量、异或、用两数和加减运算(这里可能会发生整形溢出) -------------------------------------------------------------------------------- /框架算法/06、选举算法.md: -------------------------------------------------------------------------------- 1 | 2 | ## [原文]() 3 | 4 | # 选举算法 --------------------------------------------------------------------------------