├── .gitattributes ├── .gitignore ├── 0001.two-sum ├── two-sum.go └── two-sum_test.go ├── 0002.add-two-numbers ├── add-two-numbers.go └── add-two-numbers_test.go ├── 0003.无重复字符的最长子串 ├── longest-substring-without-repeating-characters.go └── longest-substring-without-repeating-characters_test.go ├── 0005.longest-palindromic-substring ├── longest-palindromic-substring.go └── longest-palindromic-substring_test.go ├── 0010.regular-expression-matching └── regular-expression-matching.go ├── 0011.container-with-most-water ├── container-with-most-water.go └── container-with-most-water_test.go ├── 0015.3sum ├── 3sum.go └── 3sum_test.go ├── 0017.letter-combinations-of-a-phone-number ├── letter-combinations-of-a-phone-number.go └── letter-combinations-of-a-phone-number_test.go ├── 0018.4sum ├── 4sum.go └── 4sum_test.go ├── 0019.remove-nth-node-from-end-of-list ├── remove-nth-node-from-end-of-list.go └── remove-nth-node-from-end-of-list_test.go ├── 0020.valid-parentheses ├── valid-parentheses.go └── valid-parentheses_test.go ├── 0021.merge-two-sorted-lists ├── solution.go └── solution_test.go ├── 0022.generate-parentheses ├── generate-parentheses.go └── generate-parentheses_test.go ├── 0023.merge-k-sorted-lists ├── merge-k-sorted-lists.go └── merge-k-sorted-lists_test.go ├── 0025.reverse-nodes-in-k-group ├── reverse-nodes-in-k-group.go └── reverse-nodes-in-k-group_test.go ├── 0027.remove-element ├── remove-element.go └── remove-element_test.go ├── 0028.implement-strstr └── implement-strstr.go ├── 0031.next-permutation ├── next-permutation.go └── next-permutation_test.go ├── 0032.longest-valid-parentheses ├── longest-valid-parentheses.go └── longest-valid-parentheses_test.go ├── 0033.search-in-rotated-sorted-array ├── search-in-rotated-sorted-array.go └── search-in-rotated-sorted-array_test.go ├── 0034.find-first-and-last-position-of-element-in-sorted-array ├── find-first-and-last-position-of-element-in-sorted-array.go └── find-first-and-last-position-of-element-in-sorted-array_test.go ├── 0039.combination-sum ├── combination-sum.go └── combination-sum_test.go ├── 0042.trapping-rain-water ├── trapping-rain-water.go └── trapping-rain-water_test.go ├── 0046.permutations ├── main.go └── main_test.go ├── 0048.rotate-image └── rotate-image.go ├── 0049.group-anagrams ├── group-anagrams.go └── group-anagrams_test.go ├── 0053.maximum-subarray ├── maximum-subarray.go └── maximum-subarray_test.go ├── 0054.spiral-matrix └── spiral-matrix.go ├── 0055.jump-game ├── jump-game.go └── jump-game_test.go ├── 0056.merge-intervals ├── merge-intervals.go └── merge-intervals_test.go ├── 0062.unique-paths └── unique-paths.go ├── 0063.unique-paths-ii ├── unique-paths-ii.go └── unique-paths-ii_test.go ├── 0064.minimum-path-sum ├── minimum-path-sum.go └── minimum-path-sum_test.go ├── 0069.sqrtx └── main.go ├── 0070.climbing-stairs └── climbing-stairs.go ├── 0072.edit-distance ├── edit-distance.go └── edit-distance_test.go ├── 0075.sort-colors └── sort-colors.go ├── 0076.minimum-window-substring ├── minimum-window-substring.go └── minimum-window-substring_test.go ├── 0077.combinations └── combinations.go ├── 0078.subsets ├── subsets.go └── subsets_test.go ├── 0079.word-search ├── word-search.go └── word-search_test.go ├── 0082.remove-duplicates-from-sorted-list-ii ├── remove-duplicates-from-sorted-list-ii.go └── remove-duplicates-from-sorted-list-ii_test.go ├── 0084.largest-rectangle-in-histogram ├── largest-rectangle-in-histogram.go └── largest-rectangle-in-histogram_test.go ├── 0088.merge-sorted-array └── merge-sorted-array.go ├── 0092.reverse-linked-list-ii └── reverse-linked-list-ii.go ├── 0094.binary-tree-inorder-traversal ├── binary-tree-inorder-traversal.go └── binary-tree-inorder-traversal_test.go ├── 0095.unique-binary-search-trees-ii ├── unique-binary-search-trees-ii.go └── unique-binary-search-trees-ii_test.go ├── 0096.unique-binary-search-trees ├── unique-binary-search-trees.go └── unique-binary-search-trees_test.go ├── 0098.validate-binary-search-tree ├── validate-binary-search-tree.go └── validate-binary-search-tree_test.go ├── 0101.symmetric-tree └── symmetric-tree.go ├── 0102.binary-tree-level-order-traversal ├── binary-tree-level-order-traversal.go └── binary-tree-level-order-traversal_test.go ├── 0103.binary-tree-zigzag-level-order-traversal └── binary-tree-zigzag-level-order-traversal.go ├── 0104.maximum-depth-of-binary-tree └── maximum-depth-of-binary-tree.go ├── 0105.construct-binary-tree-from-preorder-and-inorder-traversal ├── construct-binary-tree-from-preorder-and-inorder-traversal.go └── construct-binary-tree-from-preorder-and-inorder-traversal_test.go ├── 0106.construct-binary-tree-from-inorder-and-postorder-traversal ├── construct-binary-tree-from-inorder-and-postorder-traversal.go └── construct-binary-tree-from-inorder-and-postorder-traversal_test.go ├── 0107.binary-tree-level-order-traversal-ii └── binary-tree-level-order-traversal-ii.go ├── 0108.convert-sorted-array-to-binary-search-tree └── convert-sorted-array-to-binary-search-tree.go ├── 0110.balanced-binary-tree └── balanced-binary-tree.go ├── 0111.minimum-depth-of-binary-tree ├── main.go └── main_test.go ├── 0112.path-sum ├── path-sum.go └── path-sum_test.go ├── 0113.path-sum-ii ├── path-sum-ii.go └── path-sum-ii_test.go ├── 0114.flatten-binary-tree-to-linked-list └── flatten-binary-tree-to-linked-list.go ├── 0116.populating-next-right-pointers-in-each-node └── populating-next-right-pointers-in-each-node.go ├── 0117.populating-next-right-pointers-in-each-node-ii └── populating-next-right-pointers-in-each-node-ii.go ├── 0121.best-time-to-buy-and-sell-stock ├── best-time-to-buy-and-sell-stock.go └── best-time-to-buy-and-sell-stock_test.go ├── 0122.best-time-to-buy-and-sell-stock-ii └── best-time-to-buy-and-sell-stock-ii.go ├── 0123.best-time-to-buy-and-sell-stock-iii ├── best-time-to-buy-and-sell-stock-iii.go └── best-time-to-buy-and-sell-stock-iii_test.go ├── 0128.longest-consecutive-sequencelongest ├── longest-consecutive-sequence.go └── longest-consecutive-sequence_test.go ├── 0136.single-number ├── single-number.go └── single-number_test.go ├── 0139.word-break ├── word-break.go └── word-break_test.go ├── 0141.linked-list-cycle └── linked-list-cycle.go ├── 0142.linked-list-cycle-ii ├── linked-list-cycle-ii.go └── linked-list-cycle-ii_test.go ├── 0144.binary-tree-preorder-traversal └── binary-tree-preorder-traversal.go ├── 0145.binary-tree-postorder-traversal └── binary-tree-postorder-traversal.go ├── 0146. LRU 缓存 ├── lru-cache.go ├── lru-copy.go ├── lru-self.go └── lru-self_test.go ├── 0148.sort-list ├── sort-list.go └── sort-list_test.go ├── 0151.reverse-words-in-a-string ├── reverse-words-in-a-string.go └── reverse-words-in-a-string_test.go ├── 0152.maximum-product-subarray └── maximum-product-subarray.go ├── 0155.min-stack └── min-stack.go ├── 0160.intersection-of-two-linked-lists ├── intersection-of-two-linked-lists.go └── intersection-of-two-linked-lists_test.go ├── 0169.majority-element └── majority-element.go ├── 0188.best-time-to-buy-and-sell-stock-iv ├── best-time-to-buy-and-sell-stock-iv.go └── best-time-to-buy-and-sell-stock-iv_test.go ├── 0198.house-robber ├── house-robber.go └── house-robber_test.go ├── 0199.binary-tree-right-side-view └── binary-tree-right-side-view.go ├── 0200.number-of-islands ├── number-of-islands.go └── number-of-islands_test.go ├── 0206. 反转链表 ├── reverse-linked-list.go └── reverse-linked-list_test.go ├── 0207.course-schedule ├── course-schedule.go └── course-schedule_test.go ├── 0213.house-robber-ii ├── house-robber-ii.go └── house-robber-ii_test.go ├── 0215.kth-largest-element-in-an-array ├── kth-largest-element-in-an-array.go └── kth-largest-element-in-an-array_test.go ├── 0221.maximal-square ├── maximal-square.go └── maximal-square_test.go ├── 0222.count-complete-tree-nodes └── count-complete-tree-nodes.go ├── 0226.invert-binary-tree └── invert-binary-tree.go ├── 0230.kth-smallest-element-in-a-bst ├── kth-smallest-element-in-a-bst.go └── kth-smallest-element-in-a-bst_test.go ├── 0234.palindrome-linked-list ├── palindrome-linked-list.go └── palindrome-linked-list_test.go ├── 0235.lowest-common-ancestor-of-a-binary-search-tree └── lowest-common-ancestor-of-a-binary-search-tree.go ├── 0236.lowest-common-ancestor-of-a-binary-tree ├── lowest-common-ancestor-of-a-binary-tree.go └── lowest-common-ancestor-of-a-binary-tree_test.go ├── 0238.product-of-array-except-self ├── product-of-array-except-self.go └── product-of-array-except-self_test.go ├── 0240.search-a-2d-matrix-ii └── search-a-2d-matrix-ii.go ├── 0257.binary-tree-paths └── binary-tree-paths.go ├── 0279.perfect-squares ├── perfect-squares.go └── perfect-squares_test.go ├── 0283.move-zeroes ├── move-zeroes.go └── move-zeroes_test.go ├── 0287.find-the-duplicate-number ├── find-the-duplicate-number.go └── find-the-duplicate-number_test.go ├── 0297.serialize-and-deserialize-binary-tree ├── serialize-and-deserialize-binary-tree.go └── serialize-and-deserialize-binary-tree_test.go ├── 0300.longest-increasing-subsequence └── longest-increasing-subsequence.go ├── 0301.remove-invalid-parentheses ├── remove-invalid-parentheses.go └── remove-invalid-parentheses_test.go ├── 0309.best-time-to-buy-and-sell-stock-with-cooldown ├── best-time-to-buy-and-sell-stock-with-cooldown.go └── best-time-to-buy-and-sell-stock-with-cooldown_test.go ├── 0322.coin-change └── main.go ├── 0337.house-robber-iii ├── house-robber-iii.go └── house-robber-iii_test.go ├── 0338.counting-bits └── counting-bits.go ├── 0341.flatten-nested-list-iterator └── flatten-nested-list-iterator.go ├── 0343.integer-break └── integer-break.go ├── 0347.top-k-frequent-elements ├── top-k-frequent-elements.go └── top-k-frequent-elements_test.go ├── 0394.decode-string ├── decode-string.go └── decode-string_test.go ├── 0404.sum-of-left-leaves └── sum-of-left-leaves.go ├── 0406.queue-reconstruction-by-height ├── queue-reconstruction-by-height.go └── queue-reconstruction-by-height_test.go ├── 0415.add-strings ├── add-strings.go └── add-strings_test.go ├── 0416.partition-equal-subset-sum ├── partition-equal-subset-sum.go └── partition-equal-subset-sum_test.go ├── 0429.n-ary-tree-level-order-traversal └── n-ary-tree-level-order-traversal.go ├── 0437.path-sum-iii └── path-sum-iii.go ├── 0438.find-all-anagrams-in-a-string ├── find-all-anagrams-in-a-string.go └── find-all-anagrams-in-a-string_test.go ├── 0448.find-all-numbers-disappeared-in-an-array ├── find-all-numbers-disappeared-in-an-array.go └── find-all-numbers-disappeared-in-an-array_test.go ├── 0450.delete-node-in-a-bst └── delete-node-in-a-bst.go ├── 0459.repeated-substring-pattern ├── repeated-substring-pattern.go └── repeated-substring-pattern_test.go ├── 0461.hamming-distance └── hamming-distance.go ├── 0494.target-sum ├── target-sum.go └── target-sum_test.go ├── 0501.find-mode-in-binary-search-tree ├── find-mode-in-binary-search-tree.go └── find-mode-in-binary-search-tree_test.go ├── 0509.fibonacci-number └── fibonacci-number.go ├── 0513.find-bottom-left-tree-value └── find-bottom-left-tree-value.go ├── 0515.find-largest-value-in-each-tree-row └── find-largest-value-in-each-tree-row.go ├── 0516.longest-palindromic-subsequence └── longest-palindromic-subsequence.go ├── 0518.coin-change-2 ├── coin-change-2.go └── coin-change-2_test.go ├── 0530.minimum-absolute-difference-in-bst └── minimum-absolute-difference-in-bst.go ├── 0538.convert-bst-to-greater-tree └── convert-bst-to-greater-tree.go ├── 0541.reverse-string-ii └── reverse-string-ii.go ├── 0543.diameter-of-binary-tree └── diameter-of-binary-tree.go ├── 0559.maximum-depth-of-n-ary-tree └── maximum-depth-of-n-ary-tree.go ├── 0560.subarray-sum-equals-k ├── subarray-sum-equals-k.go └── subarray-sum-equals-k_test.go ├── 0567.permutation-in-string ├── permutation-in-string.go └── permutation-in-string_test.go ├── 0581.shortest-unsorted-continuous-subarray ├── shortest-unsorted-continuous-subarray.go └── shortest-unsorted-continuous-subarray_test.go ├── 0617.merge-two-binary-trees └── merge-two-binary-trees.go ├── 0637.average-of-levels-in-binary-tree └── average-of-levels-in-binary-tree.go ├── 0647.palindromic-substrings ├── palindromic-substrings.go └── palindromic-substrings_test.go ├── 0652.find-duplicate-subtrees ├── find-duplicate-subtrees.go └── find-duplicate-subtrees_test.go ├── 0654.maximum-binary-tree └── maximum-binary-tree.go ├── 0669.trim-a-binary-search-tree └── trim-a-binary-search-tree.go ├── 0674.longest-continuous-increasing-subsequence ├── longest-continuous-increasing-subsequence.go └── longest-continuous-increasing-subsequence_test.go ├── 0695.max-area-of-island └── max-area-of-island.go ├── 0700.search-in-a-binary-search-tree └── search-in-a-binary-search-tree.go ├── 0701.insert-into-a-binary-search-tree └── insert-into-a-binary-search-tree.go ├── 0704.binary-search └── binary-search.go ├── 0714.best-time-to-buy-and-sell-stock-with-transaction-fee └── best-time-to-buy-and-sell-stock-with-transaction-fee.go ├── 0739.daily-temperatures ├── daily-temperatures.go └── daily-temperatures_test.go ├── 0743.network-delay-time ├── network-delay-time.go └── network-delay-time_test.go ├── 0746.min-cost-climbing-stairs └── min-cost-climbing-stairs.go ├── 0752.open-the-lock └── main.go ├── 0876.middle-of-the-linked-list ├── middle-of-the-linked-list.go └── middle-of-the-linked-list_test.go ├── 1038.binary-search-tree-to-greater-sum-tree └── binary-search-tree-to-greater-sum-tree.go ├── 1049.last-stone-weight-ii └── last-stone-weight-ii.go ├── 1254.number-of-closed-islands └── number-of-closed-islands.go ├── 1373.maximum-sum-bst-in-binary-tree └── maximum-sum-bst-in-binary-tree.go ├── 1905.count-sub-islands └── count-sub-islands.go ├── 399.evaluate-division ├── evaluate-division.go └── evaluate-division_test.go ├── LICENSE ├── README.md ├── bfs ├── bfs-note.md └── bfs.md ├── big-num-operation ├── README.md ├── big_num_add.go ├── big_num_div.go ├── big_num_mult.go └── big_num_sub.go ├── binary-operation └── lowbit.go ├── binary-sort ├── README.md ├── search_range.go └── sqrt.go ├── character-match ├── brute_force.go └── kmp.go ├── data-structure ├── README.md ├── double_linklist.go ├── single_linklist.go └── stack.go ├── dfs ├── dfs-note.md ├── n_queens.go └── permutations.go ├── double-pointer ├── README.md ├── get_char.go └── max_sub_seq.go ├── go.mod ├── go.sum ├── listnode.md ├── max-num-less-n └── get_num.go ├── offer-question ├── offer03.shu-zu-zhong-zhong-fu-de-shu-zi-lcof │ ├── shu-zu-zhong-zhong-fu-de-shu-zi-lcof.go │ └── shu-zu-zhong-zhong-fu-de-shu-zi-lcof_test.go ├── offer04.er-wei-shu-zu-zhong-de-cha-zhao-lcof │ └── er-wei-shu-zu-zhong-de-cha-zhao-lcof.go ├── offer05.ti-huan-kong-ge-lcof │ └── ti-huan-kong-ge-lcof.go ├── offer06.cong-wei-dao-tou-da-yin-lian-biao-lcof │ └── cong-wei-dao-tou-da-yin-lian-biao-lcof.go ├── offer07.zhong-jian-er-cha-shu-lcof │ └── zhong-jian-er-cha-shu-lcof.go ├── offer09.yong-liang-ge-zhan-shi-xian-dui-lie-lcof │ └── yong-liang-ge-zhan-shi-xian-dui-lie-lcof.go ├── offer10.qing-wa-tiao-tai-jie-wen-ti-lcof │ └── qing-wa-tiao-tai-jie-wen-ti-lcof.go ├── offer12.ju-zhen-zhong-de-lu-jing-lcof │ └── ju-zhen-zhong-de-lu-jing-lcof.go ├── offer14.jian-sheng-zi-ii-lcof │ └── jian-sheng-zi-ii-lcof.go ├── offer14.jian-sheng-zi-lcof │ ├── jian-sheng-zi-lcof.go │ └── jian-sheng-zi-lcof_test.go ├── offer15.er-jin-zhi-zhong-1de-ge-shu-lcof │ └── er-jin-zhi-zhong-1de-ge-shu-lcof.go ├── offer21.diao-zheng-shu-zu-shun-xu-shi-qi-shu-wei-yu-ou-shu-qian-mian-lcof │ ├── diao-zheng-shu-zu-shun-xu-shi-qi-shu-wei-yu-ou-shu-qian-mian-lcof.go │ └── diao-zheng-shu-zu-shun-xu-shi-qi-shu-wei-yu-ou-shu-qian-mian-lcof_test.go ├── offer29.shun-shi-zhen-da-yin-ju-zhen-lcof │ ├── shun-shi-zhen-da-yin-ju-zhen-lcof.go │ └── shun-shi-zhen-da-yin-ju-zhen-lcof_test.go └── offer58.zuo-xuan-zhuan-zi-fu-chuan-lcof │ └── zuo-xuan-zhuan-zi-fu-chuan-lcof.go ├── queue └── queue.go ├── sectionMerge.go ├── sort ├── bubble_sort.go ├── insert_sort.go ├── merge_sort.go ├── quick_sort.go └── quick_sort_test.go ├── sum └── prefixSum.go ├── test ├── main.go └── main_test.go ├── tree.md └── util ├── TreeNode.go └── listNode.go /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .LICENSE 2 | .idea/ -------------------------------------------------------------------------------- /0001.two-sum/two-sum.go: -------------------------------------------------------------------------------- 1 | package _001_two_sum 2 | 3 | func twoSum(nums []int, target int) []int { 4 | for left := 0; left < len(nums); left++ { 5 | right := len(nums) - 1 6 | for right > left { 7 | if nums[right] == target-nums[left] { 8 | return []int{left, right} 9 | } 10 | right-- 11 | } 12 | } 13 | return nil 14 | } 15 | -------------------------------------------------------------------------------- /0001.two-sum/two-sum_test.go: -------------------------------------------------------------------------------- 1 | package _001_two_sum 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_twoSum(t *testing.T) { 9 | type args struct { 10 | nums []int 11 | target int 12 | } 13 | tests := []struct { 14 | name string 15 | args args 16 | want []int 17 | }{ 18 | { 19 | "test1", 20 | args{ 21 | []int{2, 7, 11, 15}, 22 | 9, 23 | }, 24 | []int{0, 1}, 25 | }, 26 | } 27 | for _, tt := range tests { 28 | t.Run(tt.name, func(t *testing.T) { 29 | if got := twoSum(tt.args.nums, tt.args.target); !reflect.DeepEqual(got, tt.want) { 30 | t.Errorf("twoSum() = %v, want %v", got, tt.want) 31 | } 32 | }) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /0002.add-two-numbers/add-two-numbers.go: -------------------------------------------------------------------------------- 1 | package _002_add_two_numbers 2 | 3 | import ( 4 | "github.com/yigenshutiao/Golang-algorithm-template/util" 5 | ) 6 | 7 | type ListNode = util.ListNode 8 | 9 | func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode { 10 | 11 | // 记住要起一个新链表即可 12 | dummy := new(ListNode) 13 | pre := dummy 14 | 15 | var s, v int 16 | // 两个节点有一个不为空即可,每次拿到当前值和是否进位 17 | for l1 != nil || l2 != nil { 18 | v1, v2 := 0, 0 19 | if l1 != nil { 20 | v1 = l1.Val 21 | l1 = l1.Next 22 | } 23 | if l2 != nil { 24 | v2 = l2.Val 25 | l2 = l2.Next 26 | } 27 | sum := v1 + v2 + s 28 | s, v = sum/10, sum%10 29 | 30 | cur := &ListNode{Val: v} 31 | dummy.Next = cur 32 | dummy = dummy.Next 33 | } 34 | 35 | if s > 0 { 36 | cur := &ListNode{Val: s} 37 | dummy.Next = cur 38 | } 39 | 40 | return pre.Next 41 | } 42 | -------------------------------------------------------------------------------- /0002.add-two-numbers/add-two-numbers_test.go: -------------------------------------------------------------------------------- 1 | package _002_add_two_numbers 2 | 3 | import ( 4 | "github.com/yigenshutiao/Golang-algorithm-template/util" 5 | "reflect" 6 | "testing" 7 | ) 8 | 9 | func Test_addTwoNumbers(t *testing.T) { 10 | type args struct { 11 | l1 *ListNode 12 | l2 *ListNode 13 | } 14 | tests := []struct { 15 | name string 16 | args args 17 | want *ListNode 18 | }{ 19 | { 20 | "test 1", 21 | args{ 22 | util.Ints2List([]int{9, 9, 9, 9, 9, 9, 9}), 23 | util.Ints2List([]int{9, 9, 9, 9}), 24 | }, 25 | util.Ints2List([]int{8, 9, 9, 9, 0, 0, 0, 1}), 26 | }, 27 | } 28 | for _, tt := range tests { 29 | t.Run(tt.name, func(t *testing.T) { 30 | if got := addTwoNumbers(tt.args.l1, tt.args.l2); !reflect.DeepEqual(got, tt.want) { 31 | t.Errorf("addTwoNumbers() = %v, want %v", got, tt.want) 32 | } 33 | }) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /0003.无重复字符的最长子串/longest-substring-without-repeating-characters.go: -------------------------------------------------------------------------------- 1 | package _003_longest_substring_without_repeating_characters 2 | 3 | // 输入: s = "abcabcbb" 4 | // 输出: 3 5 | 6 | // 滑动窗口的题,先加元素,再动坐标 7 | func lengthOfLongestSubstring(s string) int { 8 | left, right := 0, 0 9 | var res int 10 | 11 | info := make(map[byte]int) 12 | 13 | for left < len(s) { 14 | // 节点right 往右走,一直走到有重复字符串 15 | for right < len(s) && info[s[right]] < 1 { 16 | info[s[right]]++ 17 | right++ 18 | } 19 | 20 | if right-left > res { 21 | res = right - left 22 | } 23 | 24 | info[s[left]]-- 25 | left++ 26 | } 27 | 28 | return res 29 | } 30 | -------------------------------------------------------------------------------- /0003.无重复字符的最长子串/longest-substring-without-repeating-characters_test.go: -------------------------------------------------------------------------------- 1 | package _003_longest_substring_without_repeating_characters 2 | 3 | import "testing" 4 | 5 | func Test_lengthOfLongestSubstring(t *testing.T) { 6 | type args struct { 7 | s string 8 | } 9 | tests := []struct { 10 | name string 11 | args args 12 | want int 13 | }{ 14 | { 15 | "test 1", 16 | args{ 17 | "dvdf", 18 | }, 19 | 3, 20 | }, 21 | } 22 | for _, tt := range tests { 23 | t.Run(tt.name, func(t *testing.T) { 24 | if got := lengthOfLongestSubstring(tt.args.s); got != tt.want { 25 | t.Errorf("lengthOfLongestSubstring() = %v, want %v", got, tt.want) 26 | } 27 | }) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /0005.longest-palindromic-substring/longest-palindromic-substring.go: -------------------------------------------------------------------------------- 1 | package _005_longest_palindromic_substring 2 | 3 | func longestPalindrome(s string) string { 4 | var res string 5 | 6 | dp := make([][]bool, len(s)) 7 | for i := 0; i < len(s); i++ { 8 | dp[i] = make([]bool, len(s)) 9 | } 10 | 11 | // 从下往上,从左往右 12 | for i := len(s) - 1; i >= 0; i-- { 13 | for j := i; j < len(s); j++ { 14 | if s[i] == s[j] { 15 | if j-i <= 1 { 16 | dp[i][j] = true 17 | if j-i+1 > len(res) { 18 | res = s[i : j+1] 19 | } 20 | } else { 21 | if dp[i+1][j-1] == true { 22 | dp[i][j] = true 23 | if j-i+1 > len(res) { 24 | res = s[i : j+1] 25 | } 26 | } 27 | } 28 | } 29 | } 30 | } 31 | 32 | return res 33 | } 34 | -------------------------------------------------------------------------------- /0005.longest-palindromic-substring/longest-palindromic-substring_test.go: -------------------------------------------------------------------------------- 1 | package _005_longest_palindromic_substring 2 | 3 | import "testing" 4 | 5 | func Test_longestPalindrome(t *testing.T) { 6 | type args struct { 7 | s string 8 | } 9 | tests := []struct { 10 | name string 11 | args args 12 | want string 13 | }{ 14 | { 15 | "test 1", 16 | args{ 17 | "babad", 18 | }, 19 | "aba", 20 | }, 21 | } 22 | for _, tt := range tests { 23 | t.Run(tt.name, func(t *testing.T) { 24 | if got := longestPalindrome(tt.args.s); got != tt.want { 25 | t.Errorf("longestPalindrome() = %v, want %v", got, tt.want) 26 | } 27 | }) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /0010.regular-expression-matching/regular-expression-matching.go: -------------------------------------------------------------------------------- 1 | package _010_regular_expression_matching 2 | 3 | func isMatch(s string, p string) bool { 4 | n := len(s) 5 | m := len(p) 6 | s = " " + s 7 | p = " " + p 8 | f := make([][]bool, n+1) 9 | for i := 0; i <= n; i++ { 10 | f[i] = make([]bool, m+1) 11 | } 12 | f[0][0] = true 13 | // 为了表达式中包含 f[0][0] 的时候计算正确,f[0][0] 置为 true, f[0][0] 无实际意义 14 | 15 | for i := 0; i <= n; i++ { 16 | for j := 1; j <= m; j++ { 17 | if j+1 < m && p[j+1] == '*' { 18 | continue // 如果 p 中的下一个字符是 *,不计算,放到和 * 一起计算 19 | } 20 | if i > 0 && p[j] != '*' { 21 | f[i][j] = f[i-1][j-1] && (s[i] == p[j] || p[j] == '.') 22 | } else if p[j] == '*' { 23 | f[i][j] = (f[i][j-2]) || ((i > 0 && f[i-1][j]) && (s[i] == p[j-1] || p[j-1] == '.')) 24 | } 25 | } 26 | } 27 | return f[n][m] 28 | } 29 | -------------------------------------------------------------------------------- /0011.container-with-most-water/container-with-most-water.go: -------------------------------------------------------------------------------- 1 | package _011_container_with_most_water 2 | 3 | // 暴力双重循环 4 | func maxArea2(height []int) int { 5 | res := 0 6 | for i := 0; i < len(height); i++ { 7 | for j := i + 1; j < len(height); j++ { 8 | res = max(res, (j-i)*min(height[i], height[j])) 9 | } 10 | } 11 | 12 | return res 13 | } 14 | 15 | // double pointer 16 | func maxArea(height []int) int { 17 | l, r := 0, len(height)-1 18 | res := 0 19 | for l < r { 20 | res = max((r-l)*min(height[l], height[r]), res) 21 | // ** 移动短板,试图换取更长的高度 ** 22 | if height[l] < height[r] { 23 | l++ 24 | } else { 25 | r-- 26 | } 27 | } 28 | 29 | return res 30 | } 31 | 32 | func max(a, b int) int { 33 | if a > b { 34 | return a 35 | } 36 | return b 37 | } 38 | 39 | func min(a, b int) int { 40 | if a < b { 41 | return a 42 | } 43 | return b 44 | } 45 | -------------------------------------------------------------------------------- /0011.container-with-most-water/container-with-most-water_test.go: -------------------------------------------------------------------------------- 1 | package _011_container_with_most_water 2 | 3 | import "testing" 4 | 5 | func Test_maxArea(t *testing.T) { 6 | type args struct { 7 | height []int 8 | } 9 | tests := []struct { 10 | name string 11 | args args 12 | want int 13 | }{ 14 | { 15 | "test1", 16 | args{ 17 | []int{1, 8, 6, 2, 5, 4, 8, 3, 7}, 18 | }, 19 | 49, 20 | }, 21 | } 22 | for _, tt := range tests { 23 | t.Run(tt.name, func(t *testing.T) { 24 | if got := maxArea(tt.args.height); got != tt.want { 25 | t.Errorf("maxArea() = %v, want %v", got, tt.want) 26 | } 27 | }) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /0015.3sum/3sum.go: -------------------------------------------------------------------------------- 1 | package _015_3sum 2 | 3 | import "sort" 4 | 5 | func threeSum(nums []int) [][]int { 6 | res := [][]int{} 7 | 8 | sort.Ints(nums) 9 | for i := 0; i < len(nums)-2; i++ { 10 | target := nums[i] 11 | // 开头大于0,后面没得玩了,直接返回 12 | if target > 0 { 13 | break 14 | } 15 | 16 | // 这里是防止重复的优化,且只保留第一次的结果, 注意第一个条件 17 | if i > 0 && nums[i] == nums[i-1] { 18 | continue 19 | } 20 | 21 | // 提前定义坐标很重要 22 | left, right := i+1, len(nums)-1 23 | for left < right { 24 | if nums[left]+nums[right]+target == 0 { 25 | res = append(res, []int{nums[i], nums[left], nums[right]}) 26 | // 注意标定变量 27 | n1, n2 := nums[left], nums[right] 28 | // 排除相同的数字 29 | for left < right && nums[left] == n1 { 30 | left++ 31 | } 32 | for left < right && nums[right] == n2 { 33 | right-- 34 | } 35 | } else if nums[left]+nums[right]+target > 0 { 36 | right-- 37 | } else if nums[left]+nums[right]+target < 0 { 38 | left++ 39 | } 40 | } 41 | } 42 | 43 | return res 44 | } 45 | -------------------------------------------------------------------------------- /0015.3sum/3sum_test.go: -------------------------------------------------------------------------------- 1 | package _015_3sum 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_threeSum(t *testing.T) { 9 | type args struct { 10 | nums []int 11 | } 12 | tests := []struct { 13 | name string 14 | args args 15 | want [][]int 16 | }{ 17 | { 18 | "test 1", 19 | args{ 20 | []int{-1, 0, 1, 2, -1, -4}, 21 | }, 22 | [][]int{{-1, -1, 2}, {-1, 0, 1}}, 23 | }, 24 | } 25 | for _, tt := range tests { 26 | t.Run(tt.name, func(t *testing.T) { 27 | if got := threeSum(tt.args.nums); !reflect.DeepEqual(got, tt.want) { 28 | t.Errorf("threeSum() = %v, want %v", got, tt.want) 29 | } 30 | }) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /0017.letter-combinations-of-a-phone-number/letter-combinations-of-a-phone-number.go: -------------------------------------------------------------------------------- 1 | package _017_letter_combinations_of_a_phone_number 2 | 3 | func letterCombinations(digits string) []string { 4 | var res []string 5 | if digits == "" { 6 | return res 7 | } 8 | 9 | digMap := map[byte]string{ 10 | '2': "abc", 11 | '3': "def", 12 | '4': "ghi", 13 | '5': "jkl", 14 | '6': "mno", 15 | '7': "pqrs", 16 | '8': "tuv", 17 | '9': "wxyz", 18 | } 19 | 20 | var dfs func(curIdx int, cur string, res *[]string) 21 | dfs = func(curIdx int, cur string, res *[]string) { 22 | if curIdx == len(digits) { 23 | *res = append(*res, cur) 24 | return 25 | } 26 | 27 | s := digits[curIdx] 28 | for _, v := range digMap[s] { 29 | cur = cur + string(v) 30 | dfs(curIdx+1, cur, res) 31 | cur = cur[:len(cur)-1] 32 | } 33 | } 34 | dfs(0, "", &res) 35 | 36 | return res 37 | } 38 | -------------------------------------------------------------------------------- /0017.letter-combinations-of-a-phone-number/letter-combinations-of-a-phone-number_test.go: -------------------------------------------------------------------------------- 1 | package _017_letter_combinations_of_a_phone_number 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_letterCombinations(t *testing.T) { 9 | type args struct { 10 | digits string 11 | } 12 | tests := []struct { 13 | name string 14 | args args 15 | want []string 16 | }{ 17 | { 18 | "test1", 19 | args{ 20 | "23", 21 | }, 22 | []string{"ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"}, 23 | }, 24 | } 25 | for _, tt := range tests { 26 | t.Run(tt.name, func(t *testing.T) { 27 | if got := letterCombinations(tt.args.digits); !reflect.DeepEqual(got, tt.want) { 28 | t.Errorf("letterCombinations() = %v, want %v", got, tt.want) 29 | } 30 | }) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /0018.4sum/4sum.go: -------------------------------------------------------------------------------- 1 | package _018_4sum 2 | 3 | import "sort" 4 | 5 | func fourSum(nums []int, target int) [][]int { 6 | if len(nums) < 4 { 7 | return nil 8 | } 9 | res := [][]int{} 10 | 11 | sort.Ints(nums) 12 | 13 | for i := 0; i < len(nums)-3; i++ { 14 | // 这里要注意一下...不要写成 i+1 15 | if i > 0 && nums[i] == nums[i-1] { 16 | continue 17 | } 18 | 19 | for j := i + 1; j < len(nums)-2; j++ { 20 | left, right := j+1, len(nums)-1 21 | if j > i+1 && nums[j] == nums[j-1] { 22 | continue 23 | } 24 | for left < right { 25 | // 重新定义坐标, n1, n2要写在compare 循环里面,不然不会更新... 26 | if nums[i]+nums[j]+nums[left]+nums[right] == target { 27 | res = append(res, []int{nums[i], nums[j], nums[left], nums[right]}) 28 | n1, n2 := nums[left], nums[right] 29 | for left < right && n1 == nums[left] { 30 | left++ 31 | } 32 | for left < right && n2 == nums[right] { 33 | right-- 34 | } 35 | } else if nums[i]+nums[j]+nums[left]+nums[right] < target { 36 | left++ 37 | } else if nums[i]+nums[j]+nums[left]+nums[right] > target { 38 | right-- 39 | } 40 | } 41 | } 42 | } 43 | 44 | return res 45 | } 46 | -------------------------------------------------------------------------------- /0018.4sum/4sum_test.go: -------------------------------------------------------------------------------- 1 | package _018_4sum 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_fourSum(t *testing.T) { 9 | type args struct { 10 | nums []int 11 | target int 12 | } 13 | tests := []struct { 14 | name string 15 | args args 16 | want [][]int 17 | }{ 18 | { 19 | "test 1", 20 | args{ 21 | nums: []int{-2, -1, -1, 1, 1, 2, 2}, 22 | target: 0, 23 | }, 24 | [][]int{{-2, -1, 1, 2}, {-1, -1, 1, 1}}, 25 | }, 26 | } 27 | for _, tt := range tests { 28 | t.Run(tt.name, func(t *testing.T) { 29 | if got := fourSum(tt.args.nums, tt.args.target); !reflect.DeepEqual(got, tt.want) { 30 | t.Errorf("fourSum() = %v, want %v", got, tt.want) 31 | } 32 | }) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /0019.remove-nth-node-from-end-of-list/remove-nth-node-from-end-of-list.go: -------------------------------------------------------------------------------- 1 | package _019_remove_nth_node_from_end_of_list 2 | 3 | type ListNode struct { 4 | Val int 5 | Next *ListNode 6 | } 7 | 8 | func removeNthFromEnd(head *ListNode, n int) *ListNode { 9 | pre := &ListNode{0, head} 10 | slow, fast := pre, pre 11 | // 一共5个节点,n = 3,n+1=4,再走1步就能找到n的前置节点,这是走n+1步的原因 12 | // 1. 快指针走n+1步 13 | for i := 0; i <= n; i++ { 14 | fast = fast.Next 15 | } 16 | // 2. 快慢指针同时走,让慢指针走到n节点的pre 17 | for fast != nil { 18 | slow = slow.Next 19 | fast = fast.Next 20 | } 21 | // 3. 开始删除 22 | slow.Next = slow.Next.Next 23 | 24 | return pre.Next 25 | } 26 | -------------------------------------------------------------------------------- /0019.remove-nth-node-from-end-of-list/remove-nth-node-from-end-of-list_test.go: -------------------------------------------------------------------------------- 1 | package _019_remove_nth_node_from_end_of_list 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_removeNthFromEnd(t *testing.T) { 9 | type args struct { 10 | head *ListNode 11 | n int 12 | } 13 | tests := []struct { 14 | name string 15 | args args 16 | want *ListNode 17 | }{ 18 | { 19 | "test 1", 20 | args{ 21 | head: &ListNode{1, nil}, 22 | n: 1, 23 | }, 24 | nil, 25 | }, 26 | } 27 | for _, tt := range tests { 28 | t.Run(tt.name, func(t *testing.T) { 29 | if got := removeNthFromEnd(tt.args.head, tt.args.n); !reflect.DeepEqual(got, tt.want) { 30 | t.Errorf("removeNthFromEnd() = %v, want %v", got, tt.want) 31 | } 32 | }) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /0020.valid-parentheses/valid-parentheses.go: -------------------------------------------------------------------------------- 1 | package _020_valid_parentheses 2 | 3 | func isValid(s string) bool { 4 | var stack []rune 5 | parenth := map[rune]rune{ 6 | '(': ')', 7 | '{': '}', 8 | '[': ']', 9 | } 10 | for _, v := range s { 11 | if _, ok := parenth[v]; ok { 12 | // 如果是左序列,入栈 13 | stack = append(stack, v) 14 | } else { 15 | // 如果开始stack里面没有左序列 16 | if len(stack) < 1 { 17 | return false 18 | } 19 | // 如果是右序列,和栈顶元素匹配,匹配则继续,不匹配则假 20 | top := stack[len(stack)-1] 21 | stack = stack[:len(stack)-1] 22 | if v != parenth[top] { 23 | return false 24 | } 25 | } 26 | } 27 | // 栈长度为0,true 28 | if len(stack) == 0 { 29 | return true 30 | } 31 | 32 | return false 33 | } 34 | -------------------------------------------------------------------------------- /0020.valid-parentheses/valid-parentheses_test.go: -------------------------------------------------------------------------------- 1 | package _020_valid_parentheses 2 | 3 | import "testing" 4 | 5 | func Test_isValids(t *testing.T) { 6 | type args struct { 7 | s string 8 | } 9 | tests := []struct { 10 | name string 11 | args args 12 | want bool 13 | }{ 14 | { 15 | "test 1", 16 | args{ 17 | "()", 18 | }, 19 | true, 20 | }, 21 | } 22 | for _, tt := range tests { 23 | t.Run(tt.name, func(t *testing.T) { 24 | if got := isValid(tt.args.s); got != tt.want { 25 | t.Errorf("isValids() = %v, want %v", got, tt.want) 26 | } 27 | }) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /0021.merge-two-sorted-lists/solution.go: -------------------------------------------------------------------------------- 1 | package _021_merge_two_sorted_lists 2 | 3 | type ListNode struct { 4 | Val int 5 | Next *ListNode 6 | } 7 | 8 | func mergeTwoLists(list1 *ListNode, list2 *ListNode) *ListNode { 9 | dummy := new(ListNode) 10 | head := dummy 11 | 12 | for list1 != nil && list2 != nil { 13 | if list1.Val < list2.Val { 14 | head.Next = list1 15 | list1 = list1.Next 16 | } else { 17 | head.Next = list2 18 | list2 = list2.Next 19 | } 20 | 21 | head = head.Next 22 | } 23 | 24 | if list1 != nil { 25 | head.Next = list1 26 | } 27 | if list2 != nil { 28 | head.Next = list2 29 | } 30 | 31 | return dummy.Next 32 | } 33 | -------------------------------------------------------------------------------- /0022.generate-parentheses/generate-parentheses.go: -------------------------------------------------------------------------------- 1 | package _022_generate_parentheses 2 | 3 | func generateParenthesis(n int) []string { 4 | res := []string{} 5 | 6 | if n == 0 { 7 | return res 8 | } 9 | 10 | var dfs func(cur string, left, right int) 11 | dfs = func(cur string, left, right int) { 12 | if left == 0 && right == 0 { 13 | res = append(res, cur) 14 | return 15 | } 16 | 17 | if left > right { 18 | return 19 | } 20 | 21 | if left > 0 { 22 | dfs(cur+"(", left-1, right) 23 | } 24 | 25 | if right > 0 { 26 | dfs(cur+")", left, right-1) 27 | } 28 | } 29 | 30 | dfs("", n, n) 31 | 32 | return res 33 | } 34 | -------------------------------------------------------------------------------- /0022.generate-parentheses/generate-parentheses_test.go: -------------------------------------------------------------------------------- 1 | package _022_generate_parentheses 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_generateParenthesis(t *testing.T) { 9 | type args struct { 10 | n int 11 | } 12 | tests := []struct { 13 | name string 14 | args args 15 | want []string 16 | }{ 17 | { 18 | "test 1", 19 | args{ 20 | 2, 21 | }, 22 | []string{"(())", "()()"}, 23 | }, 24 | } 25 | for _, tt := range tests { 26 | t.Run(tt.name, func(t *testing.T) { 27 | if got := generateParenthesi(tt.args.n); !reflect.DeepEqual(got, tt.want) { 28 | t.Errorf("generateParenthesis() = %v, want %v", got, tt.want) 29 | } 30 | }) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /0023.merge-k-sorted-lists/merge-k-sorted-lists.go: -------------------------------------------------------------------------------- 1 | package _023_merge_k_sorted_lists 2 | 3 | type ListNode struct { 4 | Val int 5 | Next *ListNode 6 | } 7 | 8 | func mergeKLists(lists []*ListNode) *ListNode { 9 | if len(lists) == 0 { 10 | return nil 11 | } 12 | 13 | if len(lists) == 1 { 14 | return lists[0] 15 | } 16 | 17 | left := lists[:len(lists)/2] 18 | right := lists[len(lists)/2:] 19 | 20 | return mergeTwoList(mergeKLists(left), mergeKLists(right)) 21 | } 22 | 23 | func mergeTwoList(head1, head2 *ListNode) *ListNode { 24 | if head1 == nil && head2 == nil { 25 | return nil 26 | } 27 | 28 | dummy := new(ListNode) 29 | pre := dummy 30 | for head1 != nil && head2 != nil { 31 | if head1.Val < head2.Val { 32 | dummy.Next = head1 33 | head1 = head1.Next 34 | } else { 35 | dummy.Next = head2 36 | head2 = head2.Next 37 | } 38 | dummy = dummy.Next 39 | } 40 | 41 | if head1 != nil { 42 | dummy.Next = head1 43 | } else { 44 | dummy.Next = head2 45 | } 46 | 47 | return pre.Next 48 | } 49 | -------------------------------------------------------------------------------- /0025.reverse-nodes-in-k-group/reverse-nodes-in-k-group.go: -------------------------------------------------------------------------------- 1 | package _025_reverse_nodes_in_k_group 2 | 3 | import "github.com/yigenshutiao/Golang-algorithm-template/util" 4 | 5 | type ListNode = util.ListNode 6 | 7 | func reverseKGroup(head *ListNode, k int) *ListNode { 8 | var dummy = &ListNode{Next: head} 9 | var pre, tail = dummy, head 10 | for tail != nil { 11 | 12 | for i := 0; i < k-1; i++ { 13 | tail = tail.Next 14 | if tail == nil { 15 | return dummy.Next //2)直接退出 16 | } 17 | } //1)完成p、h、t的定位 18 | 19 | tail.Next, tail = nil, tail.Next 20 | nh := reverse(head) 21 | pre.Next, head.Next, head, pre = nh, tail, tail, head 22 | } 23 | return dummy.Next 24 | } 25 | 26 | func reverse(head *ListNode) *ListNode { //1)只用返回新头,因为输入的头就是新尾 27 | var pre *ListNode 28 | for head != nil { 29 | head.Next, pre, head = pre, head, head.Next 30 | } 31 | return pre 32 | } 33 | -------------------------------------------------------------------------------- /0025.reverse-nodes-in-k-group/reverse-nodes-in-k-group_test.go: -------------------------------------------------------------------------------- 1 | package _025_reverse_nodes_in_k_group 2 | 3 | import ( 4 | "fmt" 5 | "github.com/stretchr/testify/assert" 6 | "github.com/yigenshutiao/Golang-algorithm-template/util" 7 | "testing" 8 | ) 9 | 10 | // tcs is testcase slice 11 | var tcs = []struct { 12 | head []int 13 | k int 14 | ans []int 15 | }{ 16 | { 17 | []int{1, 2, 3, 4, 5}, 18 | 3, 19 | []int{3, 2, 1, 4, 5}, 20 | }, 21 | 22 | //{ 23 | // []int{1, 2, 3, 4, 5}, 24 | // 2, 25 | // []int{2, 1, 4, 3, 5}, 26 | //}, 27 | 28 | // 可以有多个 testcase 29 | } 30 | 31 | func Test_reverseKGroup(t *testing.T) { 32 | ast := assert.New(t) 33 | 34 | for _, tc := range tcs { 35 | fmt.Printf("~~%v~~\n", tc) 36 | head := util.Ints2List(tc.head) 37 | ans := util.Ints2List(tc.ans) 38 | ast.Equal(ans, reverseKGroup(head, tc.k), "输入:%v", tc) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /0027.remove-element/remove-element.go: -------------------------------------------------------------------------------- 1 | package _027_remove_element 2 | 3 | func removeElement(nums []int, val int) int { 4 | for i := 0; i < len(nums); i++ { 5 | if nums[i] == val { 6 | for j := i + 1; j < len(nums); j++ { 7 | if nums[j] != val { 8 | nums[i], nums[j] = nums[j], nums[i] 9 | break 10 | } 11 | } 12 | } 13 | } 14 | 15 | res := 0 16 | for i := 0; i < len(nums); i++ { 17 | if nums[i] != val { 18 | res += 1 19 | } 20 | } 21 | return res 22 | } 23 | 24 | func removeElements(nums []int, val int) int { 25 | j := 0 26 | for i := 0; i < len(nums); i++ { 27 | if nums[i] != val { 28 | nums[j] = nums[i] 29 | j++ 30 | } 31 | } 32 | return j 33 | } 34 | -------------------------------------------------------------------------------- /0027.remove-element/remove-element_test.go: -------------------------------------------------------------------------------- 1 | package _027_remove_element 2 | 3 | import "testing" 4 | 5 | func Test_removeElements(t *testing.T) { 6 | type args struct { 7 | nums []int 8 | val int 9 | } 10 | tests := []struct { 11 | name string 12 | args args 13 | want int 14 | }{ 15 | { 16 | "test1", 17 | args{ 18 | []int{0, 1, 2, 2, 3, 0, 4, 2}, 19 | 2, 20 | }, 21 | 5, 22 | }, 23 | } 24 | for _, tt := range tests { 25 | t.Run(tt.name, func(t *testing.T) { 26 | if got := removeElements(tt.args.nums, tt.args.val); got != tt.want { 27 | t.Errorf("removeElements() = %v, want %v", got, tt.want) 28 | } 29 | }) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /0028.implement-strstr/implement-strstr.go: -------------------------------------------------------------------------------- 1 | package _028_implement_strstr 2 | 3 | func strStr(haystack string, needle string) int { 4 | for i := 0; i <= len(haystack)-len(needle); i++ { 5 | if haystack[i:i+len(needle)] == needle { 6 | return i 7 | } 8 | } 9 | return -1 10 | } 11 | -------------------------------------------------------------------------------- /0031.next-permutation/next-permutation_test.go: -------------------------------------------------------------------------------- 1 | package _031_next_permutation 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_nextPermutation1(t *testing.T) { 9 | type args struct { 10 | nums []int 11 | } 12 | tests := []struct { 13 | name string 14 | args args 15 | want []int 16 | }{ 17 | { 18 | "test 1", 19 | args{ 20 | []int{1, 2, 3, 8, 5, 7, 6, 4}, 21 | }, 22 | []int{1, 2, 3, 8, 6, 4, 5, 7}, 23 | }, 24 | } 25 | for _, tt := range tests { 26 | t.Run(tt.name, func(t *testing.T) { 27 | if got := nextPermutation(tt.args.nums); !reflect.DeepEqual(got, tt.want) { 28 | t.Errorf("nextPermutation() = %v, want %v", got, tt.want) 29 | } 30 | }) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /0032.longest-valid-parentheses/longest-valid-parentheses.go: -------------------------------------------------------------------------------- 1 | package _032_longest_valid_parentheses 2 | 3 | func longestValidParentheses(s string) int { 4 | var res int 5 | dp := make([]int, len(s)) 6 | for i := 1; i < len(s); i++ { 7 | if s[i] == ')' { 8 | if s[i-1] == '(' { 9 | if i-2 >= 0 { 10 | dp[i] = 2 + dp[i-2] 11 | } else { 12 | dp[i] = 2 13 | } 14 | } else if i-dp[i-1]-1 >= 0 && s[i-dp[i-1]-1] == '(' { 15 | // 这里只需要看s[i-dp[i-1]-2] 是否存在即可 16 | if (i - dp[i-1] - 2) >= 0 { 17 | dp[i] = dp[i-1] + 2 + dp[i-2-dp[i-1]] 18 | } else { 19 | dp[i] = dp[i-1] + 2 20 | } 21 | } 22 | } 23 | res = max(res, dp[i]) 24 | } 25 | return res 26 | } 27 | 28 | func max(a, b int) int { 29 | if a > b { 30 | return a 31 | } 32 | return b 33 | } 34 | -------------------------------------------------------------------------------- /0032.longest-valid-parentheses/longest-valid-parentheses_test.go: -------------------------------------------------------------------------------- 1 | package _032_longest_valid_parentheses 2 | 3 | import "testing" 4 | 5 | func Test_longestValidParentheses(t *testing.T) { 6 | type args struct { 7 | s string 8 | } 9 | tests := []struct { 10 | name string 11 | args args 12 | want int 13 | }{ 14 | { 15 | "test 1", 16 | args{ 17 | ")(()())", 18 | }, 19 | 6, 20 | }, 21 | } 22 | for _, tt := range tests { 23 | t.Run(tt.name, func(t *testing.T) { 24 | if got := longestValidParentheses(tt.args.s); got != tt.want { 25 | t.Errorf("longestValidParentheses() = %v, want %v", got, tt.want) 26 | } 27 | }) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /0033.search-in-rotated-sorted-array/search-in-rotated-sorted-array.go: -------------------------------------------------------------------------------- 1 | package _033_search_in_rotated_sorted_array 2 | 3 | // 局部二分法:将数组一分为二,其中一定有一个是有序的,另一个可能是有序,也能是部分有序。 4 | // 此时有序部分用二分法查找。无序部分再一分为二,其中一个一定有序,另一个可能有序,可能无序。就这样循环. 5 | 6 | // 所以这里再朴素二分的基础上,增加了寻找 有序子序列模块,要先找子序列,然后再查找 7 | // search有点没搞懂什么时候用 <= ,什么时候用< 8 | func search(nums []int, target int) int { 9 | l, r := 0, len(nums)-1 10 | for l <= r { 11 | mid := (l + r) >> 1 12 | if target == nums[mid] { 13 | return mid 14 | } 15 | if nums[0] <= nums[mid] { 16 | // 左半部分有序 17 | if target >= nums[0] && target < nums[mid] { 18 | // 想办法先移动右坐标 19 | r = mid - 1 20 | } else { 21 | l = mid + 1 22 | } 23 | } else { 24 | // 右半部分有序 25 | if target <= nums[len(nums)-1] && target > nums[mid] { 26 | // 想办法移动左坐标 27 | l = mid + 1 28 | } else { 29 | r = mid - 1 30 | } 31 | } 32 | } 33 | 34 | return -1 35 | } 36 | -------------------------------------------------------------------------------- /0033.search-in-rotated-sorted-array/search-in-rotated-sorted-array_test.go: -------------------------------------------------------------------------------- 1 | package _033_search_in_rotated_sorted_array 2 | 3 | import "testing" 4 | 5 | func Test_search(t *testing.T) { 6 | type args struct { 7 | nums []int 8 | target int 9 | } 10 | tests := []struct { 11 | name string 12 | args args 13 | want int 14 | }{ 15 | { 16 | "name2", 17 | args{ 18 | []int{4, 5, 6, 7, 0, 1, 2}, 19 | 0, 20 | }, 21 | 4, 22 | }, 23 | 24 | { 25 | "test 1", 26 | args{ 27 | []int{3, 1}, 28 | 1, 29 | }, 30 | 1, 31 | }, 32 | } 33 | for _, tt := range tests { 34 | t.Run(tt.name, func(t *testing.T) { 35 | if got := search(tt.args.nums, tt.args.target); got != tt.want { 36 | t.Errorf("search() = %v, want %v", got, tt.want) 37 | } 38 | }) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /0034.find-first-and-last-position-of-element-in-sorted-array/find-first-and-last-position-of-element-in-sorted-array_test.go: -------------------------------------------------------------------------------- 1 | package _034_find_first_and_last_position_of_element_in_sorted_array 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_searchRange(t *testing.T) { 9 | type args struct { 10 | nums []int 11 | target int 12 | } 13 | tests := []struct { 14 | name string 15 | args args 16 | want []int 17 | }{ 18 | { 19 | "test 1", 20 | args{ 21 | []int{5, 7, 7, 8, 8, 10}, 22 | 8, 23 | }, 24 | []int{3, 4}, 25 | }, 26 | { 27 | "test 2", 28 | args{ 29 | []int{5, 7, 7, 8, 8}, 30 | 8, 31 | }, 32 | []int{3, 4}, 33 | }, 34 | } 35 | for _, tt := range tests { 36 | t.Run(tt.name, func(t *testing.T) { 37 | if got := searchRange(tt.args.nums, tt.args.target); !reflect.DeepEqual(got, tt.want) { 38 | t.Errorf("searchRange() = %v, want %v", got, tt.want) 39 | } 40 | }) 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /0039.combination-sum/combination-sum.go: -------------------------------------------------------------------------------- 1 | package _039_combination_sum 2 | 3 | func combinationSum(candidates []int, target int) [][]int { 4 | var res [][]int 5 | 6 | var dfs func(cur []int, target int, idx int) 7 | 8 | dfs = func(cur []int, target int, idx int) { 9 | if target == 0 { 10 | tmp := make([]int, len(cur)) 11 | copy(tmp, cur) 12 | res = append(res, tmp) 13 | return 14 | } 15 | 16 | if target < 0 { 17 | return 18 | } 19 | 20 | // 当前处理函数 21 | for i := idx; i < len(candidates); i++ { 22 | cur = append(cur, candidates[i]) 23 | // 只需要一个横坐标即可,不需要传入纵坐标 24 | dfs(cur, target-candidates[i], i) 25 | cur = cur[:len(cur)-1] 26 | } 27 | } 28 | 29 | dfs([]int{}, target, 0) 30 | 31 | return res 32 | } 33 | -------------------------------------------------------------------------------- /0039.combination-sum/combination-sum_test.go: -------------------------------------------------------------------------------- 1 | package _039_combination_sum 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_combinationSum(t *testing.T) { 9 | type args struct { 10 | candidates []int 11 | target int 12 | } 13 | tests := []struct { 14 | name string 15 | args args 16 | want [][]int 17 | }{ 18 | { 19 | "test 1", 20 | args{ 21 | []int{2, 3, 6, 7}, 22 | 7, 23 | }, 24 | [][]int{ 25 | {2, 2, 3}, 26 | {7}, 27 | }, 28 | }, 29 | } 30 | for _, tt := range tests { 31 | t.Run(tt.name, func(t *testing.T) { 32 | if got := combinationSum(tt.args.candidates, tt.args.target); !reflect.DeepEqual(got, tt.want) { 33 | t.Errorf("combinationSum() = %v, want %v", got, tt.want) 34 | } 35 | }) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /0042.trapping-rain-water/trapping-rain-water.go: -------------------------------------------------------------------------------- 1 | package _042_trapping_rain_water 2 | 3 | func min(a, b int) int { 4 | if a < b { 5 | return a 6 | } 7 | return b 8 | } 9 | 10 | // trapDP 接雨水dp解法 11 | func trap(height []int) int { 12 | var res int 13 | 14 | maxLeft := make([]int, len(height)) 15 | maxRigt := make([]int, len(height)) 16 | 17 | maxLeft[0] = height[0] 18 | // 当前值左边界的最大值 为当前值和dp[i-1]的比较 19 | for i := 1; i < len(height); i++ { 20 | maxLeft[i] = max(height[i], maxLeft[i-1]) 21 | } 22 | 23 | // 当前值右边界的最大值,是当前值和dp[i+1]的比较 24 | maxRigt[len(height)-1] = height[len(height)-1] 25 | for i := len(height) - 2; i >= 0; i-- { 26 | maxRigt[i] = max(height[i], maxRigt[i+1]) 27 | } 28 | 29 | for i := 1; i < len(height); i++ { 30 | high := min(maxRigt[i], maxLeft[i]) 31 | sum := high - height[i] 32 | 33 | if sum > 0 { 34 | res += sum 35 | } 36 | } 37 | 38 | return res 39 | } 40 | 41 | func max(a, b int) int { 42 | if a > b { 43 | return a 44 | } 45 | return b 46 | } 47 | -------------------------------------------------------------------------------- /0042.trapping-rain-water/trapping-rain-water_test.go: -------------------------------------------------------------------------------- 1 | package _042_trapping_rain_water 2 | 3 | import "testing" 4 | 5 | func Test_traps(t *testing.T) { 6 | type args struct { 7 | height []int 8 | } 9 | tests := []struct { 10 | name string 11 | args args 12 | want int 13 | }{ 14 | { 15 | "test 1", 16 | args{ 17 | []int{4, 2, 0, 3, 2, 5}, 18 | }, 19 | 9, 20 | }, 21 | } 22 | for _, tt := range tests { 23 | t.Run(tt.name, func(t *testing.T) { 24 | if got := trapDP(tt.args.height); got != tt.want { 25 | t.Errorf("traps() = %v, want %v", got, tt.want) 26 | } 27 | }) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /0046.permutations/main_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_permute(t *testing.T) { 9 | type args struct { 10 | nums []int 11 | } 12 | tests := []struct { 13 | name string 14 | args args 15 | want [][]int 16 | }{ 17 | { 18 | "case1", 19 | args{ 20 | []int{1, 2, 3}, 21 | }, 22 | [][]int{{1, 2, 3}, {1, 3, 2}, {2, 1, 3}, {2, 3, 1}, {3, 1, 2}, {3, 2, 1}}, 23 | }, 24 | } 25 | for _, tt := range tests { 26 | t.Run(tt.name, func(t *testing.T) { 27 | if got := permute(tt.args.nums); !reflect.DeepEqual(got, tt.want) { 28 | t.Errorf("permute() = %v, want %v", got, tt.want) 29 | } 30 | }) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /0048.rotate-image/rotate-image.go: -------------------------------------------------------------------------------- 1 | package _048_rotate_image 2 | 3 | // rotate,解法比较特殊,先沿着135度对角线旋转,然后再reverse即可 4 | func rotate(matrix [][]int) { 5 | // 沿着135度对角线旋转数组 6 | for i := 0; i < len(matrix); i++ { 7 | for j := i; j < len(matrix); j++ { 8 | matrix[i][j], matrix[j][i] = matrix[j][i], matrix[i][j] 9 | } 10 | } 11 | 12 | // 然后对于每一行的元素进行reverse 13 | for _, nums := range matrix { 14 | reverse(nums) 15 | } 16 | } 17 | 18 | func reverse(nums []int) { 19 | for i := 0; i < len(nums)/2; i++ { 20 | nums[i], nums[len(nums)-1-i] = nums[len(nums)-1-i], nums[i] 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /0049.group-anagrams/group-anagrams.go: -------------------------------------------------------------------------------- 1 | package _049_group_anagrams 2 | 3 | func groupAnagrams(strs []string) [][]string { 4 | var res [][]string 5 | // 需要一个极其难记住的数据结构... 6 | wordCnt := map[[26]int][]string{} 7 | for _, s := range strs { 8 | cnt := [26]int{} 9 | for _, v := range s { 10 | cnt[v-'a']++ 11 | } 12 | wordCnt[cnt] = append(wordCnt[cnt], s) 13 | } 14 | 15 | for _, words := range wordCnt { 16 | res = append(res, words) 17 | } 18 | 19 | return res 20 | } 21 | -------------------------------------------------------------------------------- /0049.group-anagrams/group-anagrams_test.go: -------------------------------------------------------------------------------- 1 | package _049_group_anagrams 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_groupAnagrams(t *testing.T) { 9 | type args struct { 10 | strs []string 11 | } 12 | tests := []struct { 13 | name string 14 | args args 15 | want [][]string 16 | }{ 17 | { 18 | "test 1", 19 | args{ 20 | []string{"eat", "tea", "tan", "ate", "nat", "bat"}, 21 | }, 22 | [][]string{ 23 | {"bat"}, 24 | {"nat", "tan"}, 25 | {"ate", "eat", "tea"}, 26 | }, 27 | }, 28 | } 29 | for _, tt := range tests { 30 | t.Run(tt.name, func(t *testing.T) { 31 | if got := groupAnagrams(tt.args.strs); !reflect.DeepEqual(got, tt.want) { 32 | t.Errorf("groupAnagrams() = %v, want %v", got, tt.want) 33 | } 34 | }) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /0053.maximum-subarray/maximum-subarray.go: -------------------------------------------------------------------------------- 1 | package _053_maximum_subarray 2 | 3 | func maxSubArray(nums []int) int { 4 | dp := make([]int, len(nums)) 5 | for i := range nums { 6 | dp[i] = -999999999 7 | } 8 | dp[0] = nums[0] 9 | 10 | // dp[i] 以nums[i] 为下标的最大子字符串的和 11 | // 对于每个数字来说,只有两种选择:只要当前的数字,当前数字+上次最大的值 12 | // 初始化dp[0]为nums[0] 13 | for i := 1; i < len(nums); i++ { 14 | dp[i] = max(nums[i], nums[i]+dp[i-1]) 15 | } 16 | 17 | res := -9999999 18 | // 没办法找到最大值,需要再遍历一次 19 | for _, v := range dp { 20 | if v > res { 21 | res = v 22 | } 23 | } 24 | 25 | return res 26 | } 27 | 28 | func max(a, b int) int { 29 | if a > b { 30 | return a 31 | } 32 | return b 33 | } 34 | -------------------------------------------------------------------------------- /0053.maximum-subarray/maximum-subarray_test.go: -------------------------------------------------------------------------------- 1 | package _053_maximum_subarray 2 | 3 | import "testing" 4 | 5 | func Test_maxSubArray(t *testing.T) { 6 | type args struct { 7 | nums []int 8 | } 9 | tests := []struct { 10 | name string 11 | args args 12 | want int 13 | }{ 14 | { 15 | "test 1", 16 | args{ 17 | []int{-2, 1, -3, 4, -1, 2, 1, -5, 4}, 18 | }, 19 | 6, 20 | }, 21 | } 22 | for _, tt := range tests { 23 | t.Run(tt.name, func(t *testing.T) { 24 | if got := maxSubArray(tt.args.nums); got != tt.want { 25 | t.Errorf("maxSubArray() = %v, want %v", got, tt.want) 26 | } 27 | }) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /0054.spiral-matrix/spiral-matrix.go: -------------------------------------------------------------------------------- 1 | package _054_spiral_matrix 2 | 3 | func spiralOrder(matrix [][]int) []int { 4 | var result []int 5 | if len(matrix) == 0 { 6 | return result 7 | } 8 | left, right, up, down := 0, len(matrix[0])-1, 0, len(matrix)-1 9 | 10 | // x, y表示行和列,如x=2,y=1,则 arr[2][1]=10(第3行第2列) 11 | var x, y int 12 | for left <= right && up <= down { 13 | 14 | for y = left; y <= right && avoid(left, right, up, down); y++ { 15 | result = append(result, matrix[x][y]) 16 | } 17 | y-- 18 | up++ 19 | for x = up; x <= down && avoid(left, right, up, down); x++ { 20 | result = append(result, matrix[x][y]) 21 | } 22 | x-- 23 | right-- 24 | for y = right; y >= left && avoid(left, right, up, down); y-- { 25 | result = append(result, matrix[x][y]) 26 | } 27 | y++ 28 | down-- 29 | for x = down; x >= up && avoid(left, right, up, down); x-- { 30 | result = append(result, matrix[x][y]) 31 | } 32 | x++ 33 | left++ 34 | } 35 | return result 36 | } 37 | 38 | func avoid(left, right, up, down int) bool { 39 | return up <= down && left <= right 40 | } 41 | -------------------------------------------------------------------------------- /0055.jump-game/jump-game.go: -------------------------------------------------------------------------------- 1 | package _055_jump_game 2 | 3 | func canJump(nums []int) bool { 4 | dp := make([]bool, len(nums)) 5 | 6 | dp[0] = true 7 | 8 | for i := 1; i < len(nums); i++ { 9 | for j := 0; j < i; j++ { 10 | if dp[j] == true && nums[j] >= i-j { 11 | dp[i] = true 12 | break 13 | } 14 | } 15 | } 16 | 17 | return dp[len(nums)-1] 18 | } 19 | 20 | func canJumps(nums []int) bool { 21 | k := 0 22 | 23 | for i := 0; i < len(nums); i++ { 24 | if i > k { 25 | return false 26 | } 27 | 28 | // i + num[i]:已经跳的位置(i), 还能跳多远(num[i]), 和为最远能到达的距离 29 | k = max(k, i+nums[i]) 30 | } 31 | 32 | return true 33 | } 34 | 35 | func max(a, b int) int { 36 | if a > b { 37 | return a 38 | } 39 | return b 40 | } 41 | -------------------------------------------------------------------------------- /0055.jump-game/jump-game_test.go: -------------------------------------------------------------------------------- 1 | package _055_jump_game 2 | 3 | import "testing" 4 | 5 | func Test_canJump(t *testing.T) { 6 | type args struct { 7 | nums []int 8 | } 9 | tests := []struct { 10 | name string 11 | args args 12 | want bool 13 | }{ 14 | { 15 | "test 1", 16 | args{ 17 | []int{2, 3, 1, 1, 4}, 18 | }, 19 | true, 20 | }, 21 | } 22 | for _, tt := range tests { 23 | t.Run(tt.name, func(t *testing.T) { 24 | if got := canJump(tt.args.nums); got != tt.want { 25 | t.Errorf("canJump() = %v, want %v", got, tt.want) 26 | } 27 | }) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /0056.merge-intervals/merge-intervals_test.go: -------------------------------------------------------------------------------- 1 | package _056_merge_intervals 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_merge(t *testing.T) { 9 | type args struct { 10 | intervals [][]int 11 | } 12 | tests := []struct { 13 | name string 14 | args args 15 | want [][]int 16 | }{ 17 | { 18 | "test 1", 19 | args{ 20 | [][]int{{1, 3}, {2, 6}, {8, 10}, {15, 18}}, 21 | }, 22 | [][]int{{1, 6}, {8, 10}, {15, 18}}, 23 | }, 24 | } 25 | for _, tt := range tests { 26 | t.Run(tt.name, func(t *testing.T) { 27 | if got := merge(tt.args.intervals); !reflect.DeepEqual(got, tt.want) { 28 | t.Errorf("merge() = %v, want %v", got, tt.want) 29 | } 30 | }) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /0062.unique-paths/unique-paths.go: -------------------------------------------------------------------------------- 1 | package _062_unique_paths 2 | 3 | func uniquePaths(m int, n int) int { 4 | dp := make([][]int, m) 5 | 6 | for i := 0; i < m; i++ { 7 | dp[i] = make([]int, n) 8 | dp[i][0] = 1 9 | } 10 | 11 | for i := 0; i < n; i++ { 12 | dp[0][i] = 1 13 | } 14 | 15 | for i := 1; i < m; i++ { 16 | for j := 1; j < n; j++ { 17 | dp[i][j] = dp[i-1][j] + dp[i][j-1] 18 | } 19 | } 20 | 21 | return dp[m-1][n-1] 22 | } 23 | -------------------------------------------------------------------------------- /0063.unique-paths-ii/unique-paths-ii.go: -------------------------------------------------------------------------------- 1 | package _063_unique_paths_ii 2 | 3 | func uniquePathsWithObstacles(obstacleGrid [][]int) int { 4 | // m 是纵坐标, n 是横坐标 5 | m := len(obstacleGrid) 6 | n := len(obstacleGrid[0]) 7 | dp := make([][]int, m) 8 | 9 | for i := 0; i < m; i++ { 10 | dp[i] = make([]int, n) 11 | } 12 | 13 | for i := 0; i < m; i++ { 14 | 15 | if obstacleGrid[i][0] == 1 { 16 | break 17 | } 18 | dp[i][0] = 1 19 | } 20 | 21 | for i := 0; i < n; i++ { 22 | if obstacleGrid[0][i] == 1 { 23 | break 24 | } 25 | dp[0][i] = 1 26 | } 27 | 28 | for i := 1; i < m; i++ { 29 | for j := 1; j < n; j++ { 30 | if obstacleGrid[i][j] == 0 { 31 | dp[i][j] = dp[i-1][j] + dp[i][j-1] 32 | } 33 | } 34 | } 35 | return dp[m-1][n-1] 36 | } 37 | -------------------------------------------------------------------------------- /0063.unique-paths-ii/unique-paths-ii_test.go: -------------------------------------------------------------------------------- 1 | package _063_unique_paths_ii 2 | 3 | import "testing" 4 | 5 | func Test_uniquePathsWithObstacles(t *testing.T) { 6 | type args struct { 7 | obstacleGrid [][]int 8 | } 9 | tests := []struct { 10 | name string 11 | args args 12 | want int 13 | }{ 14 | { 15 | "test 1", 16 | args{ 17 | obstacleGrid: [][]int{ 18 | {0, 0}, 19 | }, 20 | }, 21 | 2, 22 | }, 23 | } 24 | for _, tt := range tests { 25 | t.Run(tt.name, func(t *testing.T) { 26 | if got := uniquePathsWithObstacles(tt.args.obstacleGrid); got != tt.want { 27 | t.Errorf("uniquePathsWithObstacles() = %v, want %v", got, tt.want) 28 | } 29 | }) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /0064.minimum-path-sum/minimum-path-sum.go: -------------------------------------------------------------------------------- 1 | package _064_minimum_path_sum 2 | 3 | func minPathSum(grid [][]int) int { 4 | m := len(grid) 5 | n := len(grid[0]) 6 | 7 | if m == 1 && n == 1 { 8 | return grid[m-1][n-1] 9 | } 10 | 11 | dp := make([][]int, m) 12 | 13 | for i := 0; i < m; i++ { 14 | dp[i] = make([]int, n) 15 | } 16 | 17 | for i := 0; i < n; i++ { 18 | for j := 0; j <= i; j++ { 19 | dp[0][i] += grid[0][j] 20 | } 21 | } 22 | 23 | for i := 0; i < m; i++ { 24 | for j := 0; j <= i; j++ { 25 | dp[i][0] += grid[j][0] 26 | } 27 | } 28 | 29 | for i := 1; i < m; i++ { 30 | for j := 1; j < n; j++ { 31 | dp[i][j] = min(dp[i-1][j], dp[i][j-1]) + grid[i][j] 32 | } 33 | } 34 | 35 | return dp[m-1][n-1] 36 | } 37 | 38 | func min(a, b int) int { 39 | if a < b { 40 | return a 41 | } 42 | 43 | return b 44 | } 45 | -------------------------------------------------------------------------------- /0064.minimum-path-sum/minimum-path-sum_test.go: -------------------------------------------------------------------------------- 1 | package _064_minimum_path_sum 2 | 3 | import "testing" 4 | 5 | func Test_minPathSum(t *testing.T) { 6 | type args struct { 7 | grid [][]int 8 | } 9 | tests := []struct { 10 | name string 11 | args args 12 | want int 13 | }{ 14 | { 15 | "test 1", 16 | args{ 17 | grid: [][]int{{1}}, 18 | }, 19 | 1, 20 | }, 21 | } 22 | for _, tt := range tests { 23 | t.Run(tt.name, func(t *testing.T) { 24 | if got := minPathSum(tt.args.grid); got != tt.want { 25 | t.Errorf("minPathSum() = %v, want %v", got, tt.want) 26 | } 27 | }) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /0069.sqrtx/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func mySqrt(x int) int { 6 | if x <= 1 { 7 | return x 8 | } 9 | l, r := 0, x 10 | for r-l > 1 { 11 | mid := (l + r) >> 1 12 | if mid*mid > x { 13 | r = mid 14 | } else { 15 | l = mid 16 | } 17 | } 18 | return l 19 | } 20 | 21 | func main() { 22 | fmt.Println(mySqrt(8)) 23 | } 24 | -------------------------------------------------------------------------------- /0070.climbing-stairs/climbing-stairs.go: -------------------------------------------------------------------------------- 1 | package _070_climbing_stairs 2 | 3 | func climbStairs(n int) int { 4 | if n <= 2 { 5 | return n 6 | } 7 | 8 | dp := make([]int, n+1) 9 | dp[1] = 1 10 | dp[2] = 2 11 | 12 | for i := 3; i <= n; i++ { 13 | dp[i] = dp[i-1] + dp[i-2] 14 | } 15 | 16 | return dp[n] 17 | } 18 | -------------------------------------------------------------------------------- /0072.edit-distance/edit-distance.go: -------------------------------------------------------------------------------- 1 | package _072_edit_distance 2 | 3 | func minDistance(word1 string, word2 string) int { 4 | m, n := len(word1), len(word2) 5 | 6 | // dp[i][j] 表示以下标i-1为结尾的字符串word1,和以下标j-1为结尾的字符串word2,最近编辑距离为dp[i][j] 7 | dp := make([][]int, m+1) 8 | for i := 0; i <= m; i++ { 9 | dp[i] = make([]int, n+1) 10 | } 11 | 12 | // 初始化:下标i的word要变成 空,最少的编辑次数应为 i 13 | for i := 0; i <= m; i++ { 14 | dp[i][0] = i 15 | } 16 | 17 | for i := 0; i <= n; i++ { 18 | dp[0][i] = i 19 | } 20 | 21 | for i := 1; i <= m; i++ { 22 | for j := 1; j <= n; j++ { 23 | if word1[i-1] == word2[j-1] { 24 | dp[i][j] = dp[i-1][j-1] 25 | } else { 26 | dp[i][j] = min(min(dp[i-1][j-1], dp[i][j-1]), dp[i-1][j]) + 1 27 | } 28 | } 29 | } 30 | 31 | return dp[m][n] 32 | } 33 | 34 | func min(a, b int) int { 35 | if a < b { 36 | return a 37 | } 38 | 39 | return b 40 | } 41 | -------------------------------------------------------------------------------- /0072.edit-distance/edit-distance_test.go: -------------------------------------------------------------------------------- 1 | package _072_edit_distance 2 | 3 | import "testing" 4 | 5 | func Test_minDistance(t *testing.T) { 6 | type args struct { 7 | word1 string 8 | word2 string 9 | } 10 | tests := []struct { 11 | name string 12 | args args 13 | want int 14 | }{ 15 | { 16 | "test1", 17 | args{ 18 | "horse", "ros", 19 | }, 20 | 3, 21 | }, 22 | } 23 | for _, tt := range tests { 24 | t.Run(tt.name, func(t *testing.T) { 25 | if got := minDistance(tt.args.word1, tt.args.word2); got != tt.want { 26 | t.Errorf("minDistance() = %v, want %v", got, tt.want) 27 | } 28 | }) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /0075.sort-colors/sort-colors.go: -------------------------------------------------------------------------------- 1 | package _075_sort_colors 2 | 3 | func sortColors(nums []int) { 4 | if len(nums) <= 1 { 5 | return 6 | } 7 | 8 | index, pos := 0, len(nums)-1 9 | 10 | for i := len(nums) - 1; i >= 1; i-- { 11 | if nums[i] > nums[index] { 12 | nums[i], nums[pos] = nums[pos], nums[i] 13 | pos-- 14 | } 15 | } 16 | 17 | nums[pos], nums[index] = nums[index], nums[pos] 18 | 19 | sortColors(nums[:pos]) 20 | sortColors(nums[pos+1:]) 21 | } 22 | -------------------------------------------------------------------------------- /0076.minimum-window-substring/minimum-window-substring.go: -------------------------------------------------------------------------------- 1 | package _076_minimum_window_substring 2 | 3 | func minWindow(s string, t string) string { 4 | 5 | source, target := make(map[byte]int), make(map[byte]int) 6 | 7 | for k := range t { 8 | source[t[k]]++ 9 | } 10 | 11 | left, right := -1, -1 12 | lens := 99999999 13 | for l, r := 0, 0; r < len(s); r++ { 14 | target[s[r]]++ 15 | 16 | for l <= r && check(source, target) { 17 | // 看长度,做减法 18 | if r-l+1 < lens { 19 | lens = r - l + 1 20 | left, right = l, r+1 21 | } 22 | target[s[l]]-- 23 | l++ 24 | } 25 | } 26 | 27 | if left == -1 { 28 | return "" 29 | } 30 | 31 | return s[left:right] 32 | } 33 | 34 | // check 看target里面是否包含source中的所有词 35 | func check(source, target map[byte]int) bool { 36 | for k, cnt := range source { 37 | if cnt > target[k] { 38 | return false 39 | } 40 | } 41 | return true 42 | } 43 | -------------------------------------------------------------------------------- /0077.combinations/combinations.go: -------------------------------------------------------------------------------- 1 | package _077_combinations 2 | 3 | func combine(n int, k int) [][]int { 4 | var res [][]int 5 | 6 | var dfs func(res *[][]int, cur []int, startIndex int) 7 | dfs = func(res *[][]int, cur []int, startIndex int) { 8 | if len(cur) == k { 9 | tmp := make([]int, k) 10 | copy(tmp, cur) 11 | *res = append(*res, tmp) 12 | return 13 | } 14 | 15 | // 单次逻辑 16 | for i := startIndex; i <= n; i++ { 17 | cur = append(cur, i) 18 | dfs(res, cur, i+1) 19 | cur = cur[:len(cur)-1] 20 | } 21 | } 22 | 23 | dfs(&res, []int{}, 1) 24 | return res 25 | } 26 | -------------------------------------------------------------------------------- /0078.subsets/subsets.go: -------------------------------------------------------------------------------- 1 | package _078_subsets 2 | 3 | func subsets(nums []int) [][]int { 4 | var res [][]int 5 | 6 | var dfs func(res *[][]int, cur []int, startIndex int) 7 | 8 | dfs = func(res *[][]int, cur []int, startIndex int) { 9 | t := make([]int, len(cur)) 10 | copy(t, cur) 11 | *res = append(*res, t) 12 | 13 | for i := startIndex; i < len(nums); i++ { 14 | cur = append(cur, nums[i]) 15 | dfs(res, cur, i+1) 16 | cur = cur[:len(cur)-1] 17 | } 18 | } 19 | 20 | dfs(&res, []int{}, 0) 21 | 22 | return res 23 | } 24 | -------------------------------------------------------------------------------- /0078.subsets/subsets_test.go: -------------------------------------------------------------------------------- 1 | package _078_subsets 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_subsets(t *testing.T) { 9 | type args struct { 10 | nums []int 11 | } 12 | tests := []struct { 13 | name string 14 | args args 15 | want [][]int 16 | }{ 17 | { 18 | "test 1", 19 | args{ 20 | []int{1, 2, 3}, 21 | }, 22 | [][]int{{}, {1}, {1, 2}, {1, 2, 3}, {1, 3}, {2}, {2, 3}, {3}}, 23 | }, 24 | } 25 | for _, tt := range tests { 26 | t.Run(tt.name, func(t *testing.T) { 27 | if got := subsets(tt.args.nums); !reflect.DeepEqual(got, tt.want) { 28 | t.Errorf("subsets() = %v, want %v", got, tt.want) 29 | } 30 | }) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /0079.word-search/word-search_test.go: -------------------------------------------------------------------------------- 1 | package _079_word_search 2 | 3 | import "testing" 4 | 5 | func Test_exist(t *testing.T) { 6 | type args struct { 7 | board [][]byte 8 | word string 9 | } 10 | tests := []struct { 11 | name string 12 | args args 13 | want bool 14 | }{ 15 | { 16 | "test 1", 17 | args{ 18 | [][]byte{ 19 | {'a', 'b'}, 20 | {'c', 'd'}, 21 | }, 22 | "acdb", 23 | }, 24 | true, 25 | }, 26 | } 27 | for _, tt := range tests { 28 | t.Run(tt.name, func(t *testing.T) { 29 | if got := exist(tt.args.board, tt.args.word); got != tt.want { 30 | t.Errorf("exist() = %v, want %v", got, tt.want) 31 | } 32 | }) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /0082.remove-duplicates-from-sorted-list-ii/remove-duplicates-from-sorted-list-ii_test.go: -------------------------------------------------------------------------------- 1 | package _082_remove_duplicates_from_sorted_list_ii 2 | 3 | import ( 4 | "github.com/yigenshutiao/Golang-algorithm-template/util" 5 | "reflect" 6 | "testing" 7 | ) 8 | 9 | func Test_deleteDuplicates(t *testing.T) { 10 | type args struct { 11 | head *ListNode 12 | } 13 | 14 | input := util.Ints2List([]int{1, 2, 3, 3, 4, 4, 5}) 15 | got := util.Ints2List([]int{1, 2, 5}) 16 | tests := []struct { 17 | name string 18 | args args 19 | want *ListNode 20 | }{ 21 | { 22 | "test 1", 23 | args{ 24 | input, 25 | }, 26 | got, 27 | }, 28 | } 29 | for _, tt := range tests { 30 | t.Run(tt.name, func(t *testing.T) { 31 | if got := deleteDuplicate(tt.args.head); !reflect.DeepEqual(got, tt.want) { 32 | t.Errorf("deleteDuplicates() = %v, want %v", got, tt.want) 33 | } 34 | }) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /0084.largest-rectangle-in-histogram/largest-rectangle-in-histogram_test.go: -------------------------------------------------------------------------------- 1 | package _084_largest_rectangle_in_histogram 2 | 3 | import "testing" 4 | 5 | func Test_largestRectangleArea(t *testing.T) { 6 | type args struct { 7 | heights []int 8 | } 9 | tests := []struct { 10 | name string 11 | args args 12 | want int 13 | }{ 14 | { 15 | "test 1", 16 | args{ 17 | []int{2, 1, 5, 6, 2, 3}, 18 | }, 19 | 10, 20 | }, 21 | } 22 | for _, tt := range tests { 23 | t.Run(tt.name, func(t *testing.T) { 24 | if got := largestRectangleArea(tt.args.heights); got != tt.want { 25 | t.Errorf("largestRectangleArea() = %v, want %v", got, tt.want) 26 | } 27 | }) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /0088.merge-sorted-array/merge-sorted-array.go: -------------------------------------------------------------------------------- 1 | package _088_merge_sorted_array 2 | 3 | func merge(nums1 []int, m int, nums2 []int, n int) { 4 | j := 0 5 | for i := m; i < len(nums1); i++ { 6 | nums1[i] = nums2[j] 7 | j++ 8 | } 9 | 10 | quickSort(nums1) 11 | } 12 | 13 | func quickSort(a []int) { 14 | if len(a) < 1 { 15 | return 16 | } 17 | 18 | idx, pos := 0, len(a)-1 19 | for i := len(a) - 1; i >= 1; i-- { 20 | if a[i] > a[idx] { 21 | a[i], a[pos] = a[pos], a[i] 22 | pos-- 23 | } 24 | } 25 | 26 | a[idx], a[pos] = a[pos], a[idx] 27 | quickSort(a[:pos]) 28 | quickSort(a[pos+1:]) 29 | } 30 | -------------------------------------------------------------------------------- /0092.reverse-linked-list-ii/reverse-linked-list-ii.go: -------------------------------------------------------------------------------- 1 | package _092_reverse_linked_list_ii 2 | 3 | import "github.com/yigenshutiao/Golang-algorithm-template/util" 4 | 5 | type ListNode = util.ListNode 6 | 7 | func reverseListNodes(head *ListNode) *ListNode { 8 | var prev *ListNode 9 | cur := head 10 | for cur != nil { 11 | next := cur.Next 12 | cur.Next = prev 13 | prev = cur 14 | cur = next 15 | } 16 | 17 | return prev 18 | } 19 | 20 | func reverseBetween(head *ListNode, left int, right int) *ListNode { 21 | dummy := &ListNode{-1, head} 22 | pre := dummy 23 | 24 | for i := 0; i < left-1; i++ { 25 | pre = pre.Next 26 | } 27 | 28 | rightNode := pre 29 | // 得到右边的节点 30 | for i := 0; i < right-left+1; i++ { 31 | rightNode = rightNode.Next 32 | } 33 | 34 | leftNode := pre.Next 35 | cur := rightNode.Next 36 | 37 | pre.Next = nil 38 | rightNode.Next = nil 39 | 40 | reverseListNodes(leftNode) 41 | 42 | pre.Next = rightNode 43 | leftNode.Next = cur 44 | 45 | return dummy.Next 46 | } 47 | -------------------------------------------------------------------------------- /0094.binary-tree-inorder-traversal/binary-tree-inorder-traversal.go: -------------------------------------------------------------------------------- 1 | package _094_binary_tree_inorder_traversal 2 | 3 | import "github.com/yigenshutiao/Golang-algorithm-template/util" 4 | 5 | type TreeNode = util.TreeNode 6 | 7 | func inorderTraversal(root *TreeNode) []int { 8 | var res []int 9 | var dfs func(node *TreeNode) 10 | dfs = func(node *TreeNode) { 11 | if node == nil { 12 | return 13 | } 14 | dfs(node.Left) 15 | res = append(res, node.Val) 16 | dfs(node.Right) 17 | } 18 | 19 | dfs(root) 20 | return res 21 | } 22 | 23 | func inorderTraversalTT(root *TreeNode) (res []int) { 24 | stack := []*TreeNode{} 25 | for root != nil || len(stack) > 0 { 26 | for root != nil { 27 | stack = append(stack, root) 28 | root = root.Left 29 | } 30 | root = stack[len(stack)-1] 31 | stack = stack[:len(stack)-1] 32 | res = append(res, root.Val) 33 | root = root.Right 34 | } 35 | return 36 | } 37 | -------------------------------------------------------------------------------- /0094.binary-tree-inorder-traversal/binary-tree-inorder-traversal_test.go: -------------------------------------------------------------------------------- 1 | package _094_binary_tree_inorder_traversal 2 | 3 | import ( 4 | "github.com/yigenshutiao/Golang-algorithm-template/util" 5 | "reflect" 6 | "testing" 7 | ) 8 | 9 | func Test_inorderTraversal(t *testing.T) { 10 | type args struct { 11 | root *TreeNode 12 | } 13 | 14 | root := util.PreIn2Tree([]int{1, 2, 5}, []int{5, 1, 2}) 15 | tests := []struct { 16 | name string 17 | args args 18 | want []int 19 | }{ 20 | { 21 | "test1", 22 | args{root}, 23 | []int{2, 1, 5}, 24 | }, 25 | } 26 | for _, tt := range tests { 27 | t.Run(tt.name, func(t *testing.T) { 28 | if got := inorderTraversal(tt.args.root); !reflect.DeepEqual(got, tt.want) { 29 | t.Errorf("inorderTraversal() = %v, want %v", got, tt.want) 30 | } 31 | }) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /0095.unique-binary-search-trees-ii/unique-binary-search-trees-ii.go: -------------------------------------------------------------------------------- 1 | package _095_unique_binary_search_trees_ii 2 | 3 | import ( 4 | "github.com/yigenshutiao/Golang-algorithm-template/util" 5 | ) 6 | 7 | type TreeNode = util.TreeNode 8 | 9 | func generateTrees(n int) []*TreeNode { 10 | if n == 0 { 11 | return nil 12 | } 13 | 14 | res := traverse(1, n) 15 | return res 16 | } 17 | 18 | func traverse(min, max int) []*TreeNode { 19 | // min = max 还有一个节点,大于才需要返回 20 | if min > max { 21 | // 不能写成 []*TreeNode{}, 这个相当于 var s []*TreeNode, 只有声明,没有赋值 22 | // 如果不赋值,后面就不能遍历了 23 | return []*TreeNode{nil} 24 | } 25 | // 每次递归的 res 都是不同的 26 | res := []*TreeNode{} 27 | 28 | // 这里要去<=的情况,因为有两个节点相等的情况 29 | // i 是当前的节点, [min, i-1]是左节点,[i+1,max]是右节点 30 | for i := min; i <= max; i++ { 31 | leftTrees := traverse(min, i-1) 32 | rightTrees := traverse(i+1, max) 33 | 34 | for _, left := range leftTrees { 35 | for _, right := range rightTrees { 36 | node := &TreeNode{Val: i} 37 | node.Left = left 38 | node.Right = right 39 | res = append(res, node) 40 | } 41 | } 42 | } 43 | // 返回当前情况能组成的所有树 44 | return res 45 | } 46 | -------------------------------------------------------------------------------- /0095.unique-binary-search-trees-ii/unique-binary-search-trees-ii_test.go: -------------------------------------------------------------------------------- 1 | package _095_unique_binary_search_trees_ii 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_generateTrees(t *testing.T) { 9 | type args struct { 10 | n int 11 | } 12 | tests := []struct { 13 | name string 14 | args args 15 | want []*TreeNode 16 | }{ 17 | { 18 | "test 1", 19 | args{ 20 | 3, 21 | }, 22 | nil, 23 | }, 24 | } 25 | for _, tt := range tests { 26 | t.Run(tt.name, func(t *testing.T) { 27 | if got := generateTrees(tt.args.n); !reflect.DeepEqual(got, tt.want) { 28 | t.Errorf("generateTrees() = %v, want %v", got, tt.want) 29 | } 30 | }) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /0096.unique-binary-search-trees/unique-binary-search-trees.go: -------------------------------------------------------------------------------- 1 | package _096_unique_binary_search_trees 2 | 3 | func numTrees(n int) int { 4 | // dp[n]: 从1到n为节点可以做成多少种二叉树 5 | // dp[i] += dp[以j为头结点左子树节点数量] * dp[以j为头结点右子树节点数量] 6 | // dp[3] 就是 元素1为头结点搜索树的数量 + 元素2为头结点搜索树的数量 + 元素3为头结点搜索树的数量 7 | // 元素1为头结点搜索树的数量 = 右子树有2个元素的搜索树数量 * 左子树有0个元素的搜索树数量 8 | // 元素2为头结点搜索树的数量 = 右子树有1个元素的搜索树数量 * 左子树有1个元素的搜索树数量 9 | // 元素3为头结点搜索树的数量 = 右子树有0个元素的搜索树数量 * 左子树有2个元素的搜索树数量 10 | // dp[3] = dp[2] * dp[0] + dp[1] * dp[1] + dp[0] * dp[2] 11 | dp := make([]int, n+1) 12 | dp[0] = 1 13 | for i := 1; i <= n; i++ { 14 | for j := 1; j <= i; j++ { 15 | dp[i] += dp[i-j] * dp[j-1] 16 | } 17 | } 18 | 19 | return dp[n] 20 | } 21 | -------------------------------------------------------------------------------- /0096.unique-binary-search-trees/unique-binary-search-trees_test.go: -------------------------------------------------------------------------------- 1 | package _096_unique_binary_search_trees 2 | 3 | import "testing" 4 | 5 | func Test_numTrees(t *testing.T) { 6 | type args struct { 7 | n int 8 | } 9 | tests := []struct { 10 | name string 11 | args args 12 | want int 13 | }{ 14 | { 15 | "case 1", 16 | args{ 17 | n: 3, 18 | }, 19 | 5, 20 | }, 21 | } 22 | for _, tt := range tests { 23 | t.Run(tt.name, func(t *testing.T) { 24 | if got := numTrees(tt.args.n); got != tt.want { 25 | t.Errorf("numTrees() = %v, want %v", got, tt.want) 26 | } 27 | }) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /0098.validate-binary-search-tree/validate-binary-search-tree_test.go: -------------------------------------------------------------------------------- 1 | package _098_validate_binary_search_tree 2 | 3 | import ( 4 | "github.com/yigenshutiao/Golang-algorithm-template/util" 5 | "testing" 6 | ) 7 | 8 | func Test_isValidBST(t *testing.T) { 9 | type args struct { 10 | root *TreeNode 11 | } 12 | tree := util.Ints2TreeNode([]int{2, 1, 3}) 13 | tests := []struct { 14 | name string 15 | args args 16 | want bool 17 | }{ 18 | { 19 | "test 1", 20 | args{ 21 | tree, 22 | }, 23 | true, 24 | }, 25 | } 26 | for _, tt := range tests { 27 | t.Run(tt.name, func(t *testing.T) { 28 | if got := isValidBST(tt.args.root); got != tt.want { 29 | t.Errorf("isValidBST() = %v, want %v", got, tt.want) 30 | } 31 | }) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /0102.binary-tree-level-order-traversal/binary-tree-level-order-traversal.go: -------------------------------------------------------------------------------- 1 | package _102_binary_tree_level_order_traversal 2 | 3 | import ( 4 | "github.com/yigenshutiao/Golang-algorithm-template/util" 5 | ) 6 | 7 | type TreeNode = util.TreeNode 8 | 9 | func levelOrder(root *TreeNode) [][]int { 10 | res := [][]int{} 11 | //不要忘了过了nil的情况 12 | if root == nil { 13 | return res 14 | } 15 | 16 | queue := []*TreeNode{root} 17 | 18 | // 这里需要用len判断,因为已经初始化了 19 | for len(queue) > 0 { 20 | l := len(queue) 21 | var tmp []int 22 | // 当前level的处理,queue处理当前层,存储下一层 23 | for i := 0; i < l; i++ { 24 | // 每次遍历第一个元素 25 | node := queue[0] 26 | if node.Left != nil { 27 | queue = append(queue, node.Left) 28 | } 29 | if node.Right != nil { 30 | queue = append(queue, node.Right) 31 | } 32 | tmp = append(tmp, node.Val) 33 | queue = queue[1:] 34 | } 35 | res = append(res, tmp) 36 | } 37 | 38 | return res 39 | } 40 | -------------------------------------------------------------------------------- /0102.binary-tree-level-order-traversal/binary-tree-level-order-traversal_test.go: -------------------------------------------------------------------------------- 1 | package _102_binary_tree_level_order_traversal 2 | 3 | import ( 4 | "fmt" 5 | "github.com/stretchr/testify/assert" 6 | "github.com/yigenshutiao/Golang-algorithm-template/util" 7 | "testing" 8 | ) 9 | 10 | func Test_Problem0102(t *testing.T) { 11 | ast := assert.New(t) 12 | 13 | // tcs is testcase slice 14 | tcs := []struct { 15 | pre, in []int 16 | ans [][]int 17 | }{ 18 | 19 | { 20 | []int{3, 9, 20, 15, 7}, 21 | []int{9, 3, 15, 20, 7}, 22 | [][]int{ 23 | []int{3}, 24 | []int{9, 20}, 25 | []int{15, 7}, 26 | }, 27 | }, 28 | 29 | // 可以多个 testcase 30 | } 31 | 32 | for _, tc := range tcs { 33 | fmt.Printf("~~%v~~\n", tc) 34 | 35 | ast.Equal(tc.ans, levelOrder(util.PreIn2Tree(tc.pre, tc.in)), "输入:%v", tc) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /0104.maximum-depth-of-binary-tree/maximum-depth-of-binary-tree.go: -------------------------------------------------------------------------------- 1 | package _104_maximum_depth_of_binary_tree 2 | 3 | import "github.com/yigenshutiao/Golang-algorithm-template/util" 4 | 5 | type TreeNode = util.TreeNode 6 | 7 | func maxDepth(root *TreeNode) int { 8 | if root == nil { 9 | return 0 10 | } 11 | 12 | leftDepth := maxDepth(root.Left) 13 | rigtDepth := maxDepth(root.Right) 14 | 15 | return 1 + max(leftDepth, rigtDepth) 16 | } 17 | 18 | func max(a, b int) int { 19 | if a < b { 20 | return b 21 | } 22 | return a 23 | } 24 | 25 | func maxDepthBfs(root *TreeNode) int { 26 | if root == nil { 27 | return 0 28 | } 29 | 30 | res := 0 31 | queue := []*TreeNode{root} 32 | 33 | for len(queue) > 0 { 34 | l := len(queue) 35 | res++ 36 | for i := 0; i < l; i++ { 37 | node := queue[0] 38 | if node.Left != nil { 39 | queue = append(queue, node.Left) 40 | } 41 | if node.Right != nil { 42 | queue = append(queue, node.Right) 43 | 44 | } 45 | 46 | queue = queue[1:] 47 | } 48 | } 49 | return res 50 | } 51 | -------------------------------------------------------------------------------- /0105.construct-binary-tree-from-preorder-and-inorder-traversal/construct-binary-tree-from-preorder-and-inorder-traversal.go: -------------------------------------------------------------------------------- 1 | package _105_construct_binary_tree_from_preorder_and_inorder_traversal 2 | 3 | import "github.com/yigenshutiao/Golang-algorithm-template/util" 4 | 5 | type TreeNode = util.TreeNode 6 | 7 | // buildTree 8 | // preorder = [3,9,20,15,7], inorder = [9,3,15,20,7] 9 | func buildTree(preorder []int, inorder []int) *TreeNode { 10 | // 先判断长度,返回空的情况 11 | if len(preorder) == 0 || len(inorder) == 0 { 12 | return nil 13 | } 14 | // 从preorder里面找到根节点的坐标,然后做拆分 15 | idx := getIdx(inorder, preorder[0]) 16 | 17 | // 递归构造树 18 | root := &TreeNode{ 19 | Val: preorder[0], 20 | Left: buildTree(preorder[1:idx+1], inorder[:idx]), 21 | Right: buildTree(preorder[idx+1:], inorder[idx+1:]), 22 | } 23 | return root 24 | } 25 | 26 | func getIdx(preorder []int, target int) int { 27 | for k, v := range preorder { 28 | if v == target { 29 | return k 30 | } 31 | } 32 | return -1 33 | } 34 | -------------------------------------------------------------------------------- /0105.construct-binary-tree-from-preorder-and-inorder-traversal/construct-binary-tree-from-preorder-and-inorder-traversal_test.go: -------------------------------------------------------------------------------- 1 | package _105_construct_binary_tree_from_preorder_and_inorder_traversal 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | func Test_buildTree(t *testing.T) { 9 | // preorder = [3,9,20,15,7], inorder = [9,3,15,20,7] 10 | res := buildTree([]int{3, 9, 20, 15, 7}, []int{9, 3, 15, 20, 7}) 11 | fmt.Println(res) 12 | } 13 | -------------------------------------------------------------------------------- /0106.construct-binary-tree-from-inorder-and-postorder-traversal/construct-binary-tree-from-inorder-and-postorder-traversal.go: -------------------------------------------------------------------------------- 1 | package _106_construct_binary_tree_from_inorder_and_postorder_traversal 2 | 3 | import "github.com/yigenshutiao/Golang-algorithm-template/util" 4 | 5 | type TreeNode = util.TreeNode 6 | 7 | //中序遍历 inorder = [9,3,15,20,7], 后序遍历 postorder = [9,15,7,20,3] 8 | func buildTree(inorder []int, postorder []int) *TreeNode { 9 | if len(inorder) < 1 || len(postorder) < 1 { 10 | return nil 11 | } 12 | idx := findIndex(inorder, postorder[len(postorder)-1]) 13 | 14 | root := &TreeNode{ 15 | Val: postorder[len(postorder)-1], 16 | Left: buildTree(inorder[:idx], postorder[:idx]), 17 | Right: buildTree(inorder[idx+1:], postorder[idx:len(postorder)-1]), 18 | } 19 | 20 | return root 21 | } 22 | 23 | func findIndex(nums []int, target int) int { 24 | for i, v := range nums { 25 | if v == target { 26 | return i 27 | } 28 | } 29 | 30 | return -1 31 | } 32 | -------------------------------------------------------------------------------- /0106.construct-binary-tree-from-inorder-and-postorder-traversal/construct-binary-tree-from-inorder-and-postorder-traversal_test.go: -------------------------------------------------------------------------------- 1 | package _106_construct_binary_tree_from_inorder_and_postorder_traversal 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func Test_buildTree(t *testing.T) { 8 | buildTree([]int{}, []int{}) 9 | } 10 | -------------------------------------------------------------------------------- /0107.binary-tree-level-order-traversal-ii/binary-tree-level-order-traversal-ii.go: -------------------------------------------------------------------------------- 1 | package _107_binary_tree_level_order_traversal_ii 2 | 3 | import "github.com/yigenshutiao/Golang-algorithm-template/util" 4 | 5 | type TreeNode = util.TreeNode 6 | 7 | func levelOrderBottom(root *TreeNode) [][]int { 8 | res := [][]int{} 9 | if root == nil { 10 | return res 11 | } 12 | 13 | queue := []*TreeNode{root} 14 | 15 | for len(queue) > 0 { 16 | l := len(queue) 17 | tmp := []int{} 18 | for i := 0; i < l; i++ { 19 | node := queue[0] 20 | if node.Left != nil { 21 | queue = append(queue, node.Left) 22 | } 23 | if node.Right != nil { 24 | queue = append(queue, node.Right) 25 | } 26 | tmp = append(tmp, node.Val) 27 | queue = queue[1:] 28 | } 29 | res = append(res, tmp) 30 | } 31 | 32 | reverse(res) 33 | return res 34 | } 35 | 36 | func reverse(nums [][]int) { 37 | for i := 0; i < len(nums)/2; i++ { 38 | nums[i], nums[len(nums)-1-i] = nums[len(nums)-i-1], nums[i] 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /0108.convert-sorted-array-to-binary-search-tree/convert-sorted-array-to-binary-search-tree.go: -------------------------------------------------------------------------------- 1 | package _108_convert_sorted_array_to_binary_search_tree 2 | 3 | import "github.com/yigenshutiao/Golang-algorithm-template/util" 4 | 5 | type TreeNode = util.TreeNode 6 | 7 | func sortedArrayToBST(nums []int) *TreeNode { 8 | if len(nums) < 1 { 9 | return nil 10 | } 11 | 12 | mid := len(nums) / 2 13 | root := &TreeNode{ 14 | Val: nums[mid], 15 | } 16 | 17 | root.Left = sortedArrayToBST(nums[:mid]) 18 | root.Right = sortedArrayToBST(nums[mid+1:]) 19 | 20 | return root 21 | } 22 | -------------------------------------------------------------------------------- /0110.balanced-binary-tree/balanced-binary-tree.go: -------------------------------------------------------------------------------- 1 | package _110_balanced_binary_tree 2 | 3 | import "github.com/yigenshutiao/Golang-algorithm-template/util" 4 | 5 | type TreeNode = util.TreeNode 6 | 7 | func isBalanced(root *TreeNode) bool { 8 | if root == nil { 9 | return true 10 | } 11 | 12 | if !isBalanced(root.Left) || !isBalanced(root.Right) { 13 | return false 14 | } 15 | 16 | leftHigh := getHigh(root.Left) 17 | rightHigh := getHigh(root.Right) 18 | 19 | if abs(leftHigh-rightHigh) > 1 { 20 | return false 21 | } 22 | return true 23 | } 24 | 25 | func getHigh(node *TreeNode) int { 26 | if node == nil { 27 | return 0 28 | } 29 | 30 | return max(getHigh(node.Left), getHigh(node.Right)) + 1 31 | } 32 | 33 | func abs(a int) int { 34 | if a > 0 { 35 | return a 36 | } 37 | return -a 38 | } 39 | 40 | func max(a, b int) int { 41 | if a > b { 42 | return a 43 | } 44 | return b 45 | } 46 | -------------------------------------------------------------------------------- /0111.minimum-depth-of-binary-tree/main_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "testing" 4 | 5 | func Test_minDepth(t *testing.T) { 6 | } 7 | -------------------------------------------------------------------------------- /0112.path-sum/path-sum.go: -------------------------------------------------------------------------------- 1 | package _112_path_sum 2 | 3 | import "github.com/yigenshutiao/Golang-algorithm-template/util" 4 | 5 | type TreeNode = util.TreeNode 6 | 7 | func hasPathSum(root *TreeNode, targetSum int) bool { 8 | if root == nil { 9 | return false 10 | } 11 | targetSum -= root.Val 12 | if root.Left == nil && root.Right == nil && targetSum == 0 { 13 | return true 14 | } 15 | 16 | if root.Left == nil && root.Right == nil && targetSum != 0 { 17 | return false 18 | } 19 | 20 | if root.Left != nil { 21 | if hasPathSum(root.Left, targetSum) { 22 | return true 23 | } 24 | } 25 | 26 | if root.Right != nil { 27 | if hasPathSum(root.Right, targetSum) { 28 | return true 29 | } 30 | } 31 | 32 | return false 33 | } 34 | -------------------------------------------------------------------------------- /0113.path-sum-ii/path-sum-ii.go: -------------------------------------------------------------------------------- 1 | package _113_path_sum_ii 2 | 3 | import "github.com/yigenshutiao/Golang-algorithm-template/util" 4 | 5 | type TreeNode = util.TreeNode 6 | 7 | func pathSum(root *TreeNode, targetSum int) [][]int { 8 | res := [][]int{} 9 | if root == nil { 10 | return res 11 | } 12 | 13 | tmp := []int{} 14 | 15 | var traverse func(node *TreeNode, count int, tmp []int) 16 | 17 | traverse = func(node *TreeNode, count int, tmp []int) { 18 | tmp = append(tmp, node.Val) 19 | count -= node.Val 20 | 21 | if node.Left == nil && node.Right == nil && count == 0 { 22 | t := make([]int, len(tmp)) 23 | copy(t, tmp) 24 | res = append(res, t) 25 | return 26 | } 27 | 28 | if node.Left != nil { 29 | traverse(node.Left, count, tmp) 30 | } 31 | 32 | if node.Right != nil { 33 | traverse(node.Right, count, tmp) 34 | } 35 | } 36 | 37 | traverse(root, targetSum, tmp) 38 | 39 | return res 40 | } 41 | -------------------------------------------------------------------------------- /0114.flatten-binary-tree-to-linked-list/flatten-binary-tree-to-linked-list.go: -------------------------------------------------------------------------------- 1 | package _114_flatten_binary_tree_to_linked_list 2 | 3 | import "github.com/yigenshutiao/Golang-algorithm-template/util" 4 | 5 | type TreeNode = util.TreeNode 6 | 7 | // flatten 这个解法比较好理解... 8 | func flatten(root *TreeNode) { 9 | for root != nil { 10 | if root.Left == nil { 11 | // 若左孩子为空,不需要处理 12 | root = root.Right 13 | } else { 14 | // 当前节点同时具备俩子树时,才需要处理,不然属于已处理好的节点 15 | pre := root.Left 16 | // 找到左孩子的最右边节点 17 | for pre.Right != nil { 18 | pre = pre.Right 19 | } 20 | // 把右孩子移到左边 21 | pre.Right = root.Right 22 | // 移好之后把左孩子放到右边 23 | root.Right = root.Left 24 | // 左节点置为空 25 | root.Left = nil 26 | // 处理下一个节点 27 | root = root.Right 28 | } 29 | } 30 | } 31 | 32 | // flatten 这种解法我估计第二次做也做不出来.... 33 | func flattenFk(root *TreeNode) { 34 | if root == nil { 35 | return 36 | } 37 | flatten(root.Left) 38 | flatten(root.Right) 39 | 40 | //postorder 41 | left, right := root.Left, root.Right 42 | root.Left = nil 43 | root.Right = left 44 | for root.Right != nil { 45 | root = root.Right 46 | } 47 | root.Right = right 48 | } 49 | -------------------------------------------------------------------------------- /0116.populating-next-right-pointers-in-each-node/populating-next-right-pointers-in-each-node.go: -------------------------------------------------------------------------------- 1 | package _116_populating_next_right_pointers_in_each_node 2 | 3 | type Node struct { 4 | Val int 5 | Left *Node 6 | Right *Node 7 | Next *Node 8 | } 9 | 10 | func connect(root *Node) *Node { 11 | if root == nil { 12 | return nil 13 | } 14 | 15 | queue := []*Node{root} 16 | nodes := [][]*Node{} 17 | for len(queue) > 0 { 18 | tmp := []*Node{} 19 | l := len(queue) 20 | 21 | for i := 0; i < l; i++ { 22 | node := queue[0] 23 | if node.Left != nil { 24 | queue = append(queue, node.Left) 25 | } 26 | if node.Right != nil { 27 | queue = append(queue, node.Right) 28 | } 29 | queue = queue[1:] 30 | tmp = append(tmp, node) 31 | } 32 | nodes = append(nodes, tmp) 33 | } 34 | 35 | for i := 0; i < len(nodes); i++ { 36 | for j := 0; j < len(nodes[i])-1; j++ { 37 | nodes[i][j].Next = nodes[i][j+1] 38 | } 39 | } 40 | 41 | return root 42 | } 43 | -------------------------------------------------------------------------------- /0117.populating-next-right-pointers-in-each-node-ii/populating-next-right-pointers-in-each-node-ii.go: -------------------------------------------------------------------------------- 1 | package _117_populating_next_right_pointers_in_each_node_ii 2 | 3 | type Node struct { 4 | Val int 5 | Left *Node 6 | Right *Node 7 | Next *Node 8 | } 9 | 10 | func connect(root *Node) *Node { 11 | if root == nil { 12 | return nil 13 | } 14 | 15 | queue := []*Node{root} 16 | nodes := [][]*Node{} 17 | for len(queue) > 0 { 18 | tmp := []*Node{} 19 | l := len(queue) 20 | 21 | for i := 0; i < l; i++ { 22 | node := queue[0] 23 | if node.Left != nil { 24 | queue = append(queue, node.Left) 25 | } 26 | if node.Right != nil { 27 | queue = append(queue, node.Right) 28 | } 29 | queue = queue[1:] 30 | tmp = append(tmp, node) 31 | } 32 | nodes = append(nodes, tmp) 33 | } 34 | 35 | for i := 0; i < len(nodes); i++ { 36 | for j := 0; j < len(nodes[i])-1; j++ { 37 | nodes[i][j].Next = nodes[i][j+1] 38 | } 39 | } 40 | 41 | return root 42 | } 43 | -------------------------------------------------------------------------------- /0121.best-time-to-buy-and-sell-stock/best-time-to-buy-and-sell-stock.go: -------------------------------------------------------------------------------- 1 | package _121_best_time_to_buy_and_sell_stock 2 | 3 | func maxProfit(prices []int) int { 4 | dp := make([][]int, len(prices)) 5 | 6 | for i := 0; i < len(prices); i++ { 7 | dp[i] = make([]int, 2) 8 | } 9 | 10 | dp[0][0] = 0 11 | // dp[i][1] = max(dp[i-1][1], dp[i-1][0] - price[i]) dp[i-1][0] 为0,忽略 12 | // dp[0][1] = -prices[0] 13 | dp[0][1] = -prices[0] 14 | 15 | // 股票只能买卖一次! 16 | for i := 1; i < len(prices); i++ { 17 | // 今天不持有股票,昨天不持有股票; 昨天持有股票,今天卖 18 | dp[i][0] = max(dp[i-1][0], dp[i-1][1]+prices[i]) 19 | // 今天持有股票,昨天持有股票; 昨天不持有股票,今天买 20 | // 买股票不用管之前的值,买的利润就是-prices[i] 21 | dp[i][1] = max(dp[i-1][1], -prices[i]) 22 | } 23 | 24 | return dp[len(prices)-1][0] 25 | } 26 | 27 | func max(a, b int) int { 28 | if a > b { 29 | return a 30 | } 31 | return b 32 | } 33 | -------------------------------------------------------------------------------- /0121.best-time-to-buy-and-sell-stock/best-time-to-buy-and-sell-stock_test.go: -------------------------------------------------------------------------------- 1 | package _121_best_time_to_buy_and_sell_stock 2 | 3 | import "testing" 4 | 5 | func Test_maxProfit(t *testing.T) { 6 | type args struct { 7 | prices []int 8 | } 9 | tests := []struct { 10 | name string 11 | args args 12 | want int 13 | }{ 14 | { 15 | "test 1", 16 | args{ 17 | []int{7, 1, 5, 3, 6, 4}, 18 | }, 19 | 5, 20 | }, 21 | } 22 | for _, tt := range tests { 23 | t.Run(tt.name, func(t *testing.T) { 24 | if got := maxProfit(tt.args.prices); got != tt.want { 25 | t.Errorf("maxProfit() = %v, want %v", got, tt.want) 26 | } 27 | }) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /0122.best-time-to-buy-and-sell-stock-ii/best-time-to-buy-and-sell-stock-ii.go: -------------------------------------------------------------------------------- 1 | package _122_best_time_to_buy_and_sell_stock_ii 2 | 3 | func maxProfit(prices []int) int { 4 | dp := make([][]int, len(prices)) 5 | 6 | for i := 0; i < len(prices); i++ { 7 | dp[i] = make([]int, 2) 8 | } 9 | 10 | dp[0][0] = 0 11 | dp[0][1] = -prices[0] 12 | 13 | for i := 1; i < len(prices); i++ { 14 | // dp[1][0] 今天不持有股票的最大利润 15 | // = max(昨天不持有股票的最大利润,昨天持有股票且今天卖了的最大利润) 16 | dp[i][0] = max(dp[i-1][0], dp[i-1][1]+prices[i]) 17 | // dp[i][1] 今天持有持股的最大利润 18 | // = max(昨天持有股票的最大利润,昨天不持有股票且今天买了股票的最大利润) 19 | dp[i][1] = max(dp[i-1][1], dp[i-1][0]-prices[i]) 20 | } 21 | 22 | return dp[len(prices)-1][0] 23 | } 24 | 25 | func max(a, b int) int { 26 | if a > b { 27 | return a 28 | } 29 | return b 30 | } 31 | -------------------------------------------------------------------------------- /0123.best-time-to-buy-and-sell-stock-iii/best-time-to-buy-and-sell-stock-iii.go: -------------------------------------------------------------------------------- 1 | package _123_best_time_to_buy_and_sell_stock_iii 2 | 3 | func maxProfit(prices []int) int { 4 | dp := make([][][]int, len(prices)) 5 | for i := 0; i < len(prices); i++ { 6 | dp[i] = make([][]int, 3) 7 | for j := 0; j <= 2; j++ { 8 | dp[i][j] = make([]int, 3) 9 | } 10 | } 11 | 12 | for i := 0; i < len(prices); i++ { 13 | // j 是次数,第一次,第二次; 14 | for j := 2; j >= 1; j-- { 15 | if i == 0 { 16 | dp[i][j][0] = 0 17 | dp[i][j][1] = -prices[i] 18 | continue 19 | } 20 | 21 | dp[i][j][0] = max(dp[i-1][j][0], dp[i-1][j][1]+prices[i]) 22 | dp[i][j][1] = max(dp[i-1][j][1], dp[i-1][j-1][0]-prices[i]) 23 | } 24 | } 25 | 26 | return dp[len(prices)-1][2][0] 27 | } 28 | 29 | func max(a, b int) int { 30 | if a > b { 31 | return a 32 | } 33 | return b 34 | } 35 | -------------------------------------------------------------------------------- /0123.best-time-to-buy-and-sell-stock-iii/best-time-to-buy-and-sell-stock-iii_test.go: -------------------------------------------------------------------------------- 1 | package _123_best_time_to_buy_and_sell_stock_iii 2 | 3 | import "testing" 4 | 5 | func Test_maxProfit(t *testing.T) { 6 | type args struct { 7 | prices []int 8 | } 9 | tests := []struct { 10 | name string 11 | args args 12 | want int 13 | }{ 14 | { 15 | "test 1", 16 | args{ 17 | prices: []int{3, 3, 5, 0, 0, 3, 1, 4}, 18 | }, 19 | 6, 20 | }, 21 | } 22 | for _, tt := range tests { 23 | t.Run(tt.name, func(t *testing.T) { 24 | if got := maxProfit(tt.args.prices); got != tt.want { 25 | t.Errorf("maxProfit() = %v, want %v", got, tt.want) 26 | } 27 | }) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /0128.longest-consecutive-sequencelongest/longest-consecutive-sequence.go: -------------------------------------------------------------------------------- 1 | package _128_longest_consecutive_sequence 2 | 3 | func longestConsecutive(nums []int) int { 4 | numExist := make(map[int]bool, len(nums)) 5 | 6 | for _, num := range nums { 7 | numExist[num] = true 8 | } 9 | 10 | var res int 11 | 12 | for i := 0; i < len(nums); i++ { 13 | // 看当前的数字左边的数字是否存在 14 | if _, exist := numExist[nums[i]-1]; !exist { 15 | // 如果不存在,计算从这个数字为起点的最大长度 16 | cur := 0 17 | t := nums[i] 18 | for { 19 | if _, exist := numExist[t]; exist { 20 | t++ 21 | cur++ 22 | } else { 23 | // 不存在就退出循环... 24 | break 25 | } 26 | } 27 | 28 | if cur > res { 29 | res = cur 30 | } 31 | } 32 | } 33 | 34 | return res 35 | } 36 | -------------------------------------------------------------------------------- /0128.longest-consecutive-sequencelongest/longest-consecutive-sequence_test.go: -------------------------------------------------------------------------------- 1 | package _128_longest_consecutive_sequence 2 | 3 | import "testing" 4 | 5 | func Test_longestConsecutive(t *testing.T) { 6 | type args struct { 7 | nums []int 8 | } 9 | tests := []struct { 10 | name string 11 | args args 12 | wantRes int 13 | }{ 14 | { 15 | "test 1", 16 | args{ 17 | []int{100, 4, 200, 1, 3, 2}, 18 | }, 19 | 4, 20 | }, 21 | } 22 | for _, tt := range tests { 23 | t.Run(tt.name, func(t *testing.T) { 24 | if gotRes := longestConsecutive(tt.args.nums); gotRes != tt.wantRes { 25 | t.Errorf("longestConsecutive() = %v, want %v", gotRes, tt.wantRes) 26 | } 27 | }) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /0136.single-number/single-number.go: -------------------------------------------------------------------------------- 1 | package _136_single_number 2 | 3 | // singleNumber 最优解:位运算 4 | func singleNumber(nums []int) int { 5 | var res int 6 | for _, num := range nums { 7 | res ^= num 8 | } 9 | 10 | return res 11 | } 12 | 13 | // 自己的解 14 | func singleNumbers(nums []int) int { 15 | for i := 0; i < len(nums); i++ { 16 | flag := false 17 | for j := 0; j < len(nums); j++ { 18 | if nums[i] == nums[j] && i != j { 19 | flag = true 20 | break 21 | } 22 | } 23 | 24 | if !flag { 25 | return nums[i] 26 | } 27 | } 28 | 29 | return -1 30 | } 31 | -------------------------------------------------------------------------------- /0136.single-number/single-number_test.go: -------------------------------------------------------------------------------- 1 | package _136_single_number 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | func Test_singleNumber(t *testing.T) { 9 | 10 | fmt.Println(10 ^ 0) 11 | fmt.Println(10 ^ 10) 12 | 13 | type args struct { 14 | nums []int 15 | } 16 | tests := []struct { 17 | name string 18 | args args 19 | want int 20 | }{ 21 | { 22 | "test 1", 23 | args{ 24 | []int{2, 2, 1}, 25 | }, 26 | 1, 27 | }, 28 | } 29 | for _, tt := range tests { 30 | t.Run(tt.name, func(t *testing.T) { 31 | if got := singleNumber(tt.args.nums); got != tt.want { 32 | t.Errorf("singleNumber() = %v, want %v", got, tt.want) 33 | } 34 | }) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /0139.word-break/word-break.go: -------------------------------------------------------------------------------- 1 | package _139_word_break 2 | 3 | func wordBreak(s string, wordDict []string) bool { 4 | dp := make([]bool, len(s)+1) 5 | 6 | wd := make(map[string]bool) 7 | 8 | for _, word := range wordDict { 9 | wd[word] = true 10 | } 11 | 12 | // 长度为i的单词,如果在wordDict中出现过的话,结果为true 13 | dp[0] = true 14 | // dp[i] = dp[j] + s[j:i] 15 | for i := 1; i <= len(s); i++ { 16 | for j := 0; j < i; j++ { 17 | if dp[j] && wd[s[j:i]] { 18 | dp[i] = true 19 | break 20 | } 21 | } 22 | } 23 | 24 | return dp[len(s)] 25 | } 26 | -------------------------------------------------------------------------------- /0139.word-break/word-break_test.go: -------------------------------------------------------------------------------- 1 | package _139_word_break 2 | 3 | import "testing" 4 | 5 | func Test_wordBreak(t *testing.T) { 6 | type args struct { 7 | s string 8 | wordDict []string 9 | } 10 | tests := []struct { 11 | name string 12 | args args 13 | want bool 14 | }{ 15 | { 16 | "test 1", 17 | args{ 18 | "leetcode", 19 | []string{"leet", "code"}, 20 | }, 21 | true, 22 | }, 23 | } 24 | for _, tt := range tests { 25 | t.Run(tt.name, func(t *testing.T) { 26 | if got := wordBreak(tt.args.s, tt.args.wordDict); got != tt.want { 27 | t.Errorf("wordBreak() = %v, want %v", got, tt.want) 28 | } 29 | }) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /0141.linked-list-cycle/linked-list-cycle.go: -------------------------------------------------------------------------------- 1 | package _141_linked_list_cycle 2 | 3 | import "github.com/yigenshutiao/Golang-algorithm-template/util" 4 | 5 | type ListNode = util.ListNode 6 | 7 | func hasCycle(head *ListNode) bool { 8 | fast, slow := head, head 9 | // 这里需要用fast来判断,因为fast会更早到达尾部 10 | for fast != nil && fast.Next != nil { 11 | slow = slow.Next 12 | fast = fast.Next.Next 13 | 14 | if fast == slow { 15 | return true 16 | } 17 | } 18 | 19 | return false 20 | } 21 | -------------------------------------------------------------------------------- /0142.linked-list-cycle-ii/linked-list-cycle-ii.go: -------------------------------------------------------------------------------- 1 | package _142_linked_list_cycle_ii 2 | 3 | import "github.com/yigenshutiao/Golang-algorithm-template/util" 4 | 5 | type ListNode = util.ListNode 6 | 7 | //相遇时: 8 | //slow指针走过的节点数为: x + y 9 | //fast指针走过的节点数: x + y + n (y + z),n为fast指针在环内走了n圈才遇到slow指针, (y+z)为 一圈内节点的个数 10 | //因为fast指针是一步走两个节点,slow指针一步走一个节点, 所以 fast指针走过的节点数 = slow指针走过的节点数 * 2 11 | //(x + y) * 2 = x + y + n (y + z) 12 | //两边消掉一个(x+y): x + y = n (y + z) 13 | //因为我们要找环形的入口,那么要求的是x,因为x表示 头结点到 环形入口节点的的距离。 14 | //所以我们要求x ,将x单独放在左面:x = n (y + z) - y 15 | //当 n为1的时候,公式就化解为 x = z 16 | 17 | // !!!这就意味着,从头结点出发一个指针,从相遇节点 也出发一个指针,这两个指针每次只走一个节点, 那么当这两个指针相遇的时候就是 环形入口的节点 !!! 18 | 19 | // 记住相遇之后再走z距离即可 20 | func detectCycle(head *ListNode) *ListNode { 21 | slow, fast := head, head 22 | for fast != nil && fast.Next != nil { 23 | slow = slow.Next 24 | fast = fast.Next.Next 25 | 26 | if slow == fast { 27 | 28 | for head != slow { 29 | slow = slow.Next 30 | head = head.Next 31 | } 32 | return head 33 | } 34 | } 35 | 36 | return nil 37 | } 38 | -------------------------------------------------------------------------------- /0142.linked-list-cycle-ii/linked-list-cycle-ii_test.go: -------------------------------------------------------------------------------- 1 | package _142_linked_list_cycle_ii 2 | 3 | import ( 4 | "github.com/stretchr/testify/assert" 5 | "github.com/yigenshutiao/Golang-algorithm-template/util" 6 | "testing" 7 | ) 8 | 9 | // tcs is testcase slice 10 | var tcs = []struct { 11 | ints []int 12 | pos int 13 | }{ 14 | 15 | //{ 16 | // []int{1}, 17 | // -1, 18 | //}, 19 | // 20 | //{ 21 | // []int{1, 2, 3}, 22 | // -1, 23 | //}, 24 | 25 | { 26 | []int{3, 2, 0, -4}, 27 | 1, 28 | }, 29 | 30 | //{ 31 | // []int{1, 2}, 32 | // 0, 33 | //}, 34 | 35 | // 可以有多个 testcase 36 | } 37 | 38 | func Test_detectCycle(t *testing.T) { 39 | ast := assert.New(t) 40 | for _, tc := range tcs { 41 | head := util.Ints2ListWithCycle(tc.ints, tc.pos) 42 | var ans *ListNode 43 | if tc.pos >= 0 { 44 | ans = head.GetNodeWith(tc.ints[tc.pos]) 45 | } 46 | ast.Equal(ans, detectCycle(head), "输入:%v", tc) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /0144.binary-tree-preorder-traversal/binary-tree-preorder-traversal.go: -------------------------------------------------------------------------------- 1 | package _144_binary_tree_preorder_traversal 2 | 3 | import "github.com/yigenshutiao/Golang-algorithm-template/util" 4 | 5 | type TreeNode = util.TreeNode 6 | 7 | func preorderTraversal(root *TreeNode) []int { 8 | res := []int{} 9 | var dfs func(node *TreeNode) 10 | dfs = func(node *TreeNode) { 11 | if node == nil { 12 | return 13 | } 14 | res = append(res, node.Val) 15 | dfs(node.Left) 16 | dfs(node.Right) 17 | } 18 | 19 | dfs(root) 20 | 21 | return res 22 | } 23 | -------------------------------------------------------------------------------- /0145.binary-tree-postorder-traversal/binary-tree-postorder-traversal.go: -------------------------------------------------------------------------------- 1 | package _145_binary_tree_postorder_traversal 2 | 3 | import "github.com/yigenshutiao/Golang-algorithm-template/util" 4 | 5 | type TreeNode = util.TreeNode 6 | 7 | func postorderTraversal(root *TreeNode) []int { 8 | res := []int{} 9 | 10 | var dfs func(node *TreeNode) 11 | 12 | dfs = func(node *TreeNode) { 13 | if node == nil { 14 | return 15 | } 16 | 17 | dfs(node.Left) 18 | dfs(node.Right) 19 | res = append(res, node.Val) 20 | } 21 | 22 | dfs(root) 23 | return res 24 | } 25 | -------------------------------------------------------------------------------- /0146. LRU 缓存/lru-self_test.go: -------------------------------------------------------------------------------- 1 | package _146_lru_cache 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | func TestLRUCache_Get(t *testing.T) { 9 | lru := Constructor(2) 10 | lru.Put(1, 1) 11 | lru.Put(2, 2) 12 | fmt.Println(lru.Get(1)) 13 | lru.Put(3, 3) 14 | fmt.Println(lru.Get(2)) 15 | lru.Put(4, 4) 16 | fmt.Println(lru.Get(1)) 17 | fmt.Println(lru.Get(3)) 18 | fmt.Println(lru.Get(4)) 19 | } 20 | -------------------------------------------------------------------------------- /0148.sort-list/sort-list.go: -------------------------------------------------------------------------------- 1 | package _148_sort_list 2 | 3 | import "github.com/yigenshutiao/Golang-algorithm-template/util" 4 | 5 | type ListNode = util.ListNode 6 | 7 | func sortList(head *ListNode) *ListNode { 8 | if head == nil || head.Next == nil { 9 | return head 10 | } 11 | slow, fast := head, head 12 | // 这里要做初始化, 不然后面取Next指针可能会nil异常 13 | pre := new(ListNode) 14 | 15 | for fast != nil && fast.Next != nil { 16 | pre = slow 17 | slow = slow.Next 18 | fast = fast.Next.Next 19 | } 20 | 21 | // 不要忘记截断next指针 22 | pre.Next = nil 23 | list1 := sortList(head) 24 | list2 := sortList(slow) 25 | 26 | return merge(list1, list2) 27 | } 28 | 29 | func merge(list1, list2 *ListNode) *ListNode { 30 | dummy := new(ListNode) 31 | cur := dummy 32 | 33 | for list1 != nil && list2 != nil { 34 | if list1.Val < list2.Val { 35 | cur.Next = list1 36 | list1 = list1.Next 37 | } else { 38 | cur.Next = list2 39 | list2 = list2.Next 40 | } 41 | cur = cur.Next 42 | } 43 | 44 | if list1 != nil { 45 | cur.Next = list1 46 | } else { 47 | cur.Next = list2 48 | } 49 | 50 | return dummy.Next 51 | } 52 | -------------------------------------------------------------------------------- /0148.sort-list/sort-list_test.go: -------------------------------------------------------------------------------- 1 | package _148_sort_list 2 | 3 | import ( 4 | "github.com/yigenshutiao/Golang-algorithm-template/util" 5 | "reflect" 6 | "testing" 7 | ) 8 | 9 | func Test_sortList(t *testing.T) { 10 | type args struct { 11 | head *ListNode 12 | } 13 | tests := []struct { 14 | name string 15 | args args 16 | want *ListNode 17 | }{ 18 | { 19 | "test1", 20 | args{ 21 | head: util.Ints2List([]int{4, 2, 1, 3}), 22 | }, 23 | util.Ints2List([]int{1, 2, 3, 4}), 24 | }, 25 | } 26 | for _, tt := range tests { 27 | t.Run(tt.name, func(t *testing.T) { 28 | if got := sortList(tt.args.head); !reflect.DeepEqual(got, tt.want) { 29 | t.Errorf("sortList() = %v, want %v", got, tt.want) 30 | } 31 | }) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /0151.reverse-words-in-a-string/reverse-words-in-a-string.go: -------------------------------------------------------------------------------- 1 | package _151_reverse_words_in_a_string 2 | 3 | func reverseWords(s string) string { 4 | b := []byte(s) 5 | reverse(b) 6 | // 要加一个空格,不然最后会漏掉一个单词 7 | b = append(b, []byte{' '}...) 8 | res := []byte{} 9 | for i := 0; i < len(b); i++ { 10 | for j := i + 1; j < len(b); j++ { 11 | if b[i] != ' ' && b[j] == ' ' { 12 | t := reverse(b[i:j]) 13 | res = append(res, t...) 14 | res = append(res, []byte{' '}...) 15 | i = j 16 | } 17 | } 18 | } 19 | res = res[:len(res)-1] 20 | return string(res) 21 | } 22 | 23 | func reverse(b []byte) []byte { 24 | for i := 0; i < len(b)/2; i++ { 25 | b[i], b[len(b)-i-1] = b[len(b)-i-1], b[i] 26 | } 27 | return b 28 | } 29 | -------------------------------------------------------------------------------- /0151.reverse-words-in-a-string/reverse-words-in-a-string_test.go: -------------------------------------------------------------------------------- 1 | package _151_reverse_words_in_a_string 2 | 3 | import "testing" 4 | 5 | func Test_reverseWords(t *testing.T) { 6 | type args struct { 7 | s string 8 | } 9 | tests := []struct { 10 | name string 11 | args args 12 | want string 13 | }{ 14 | { 15 | "test 1", 16 | args{ 17 | s: "the sky is blue", 18 | }, 19 | "blue is sky the", 20 | }, 21 | } 22 | for _, tt := range tests { 23 | t.Run(tt.name, func(t *testing.T) { 24 | if got := reverseWords(tt.args.s); got != tt.want { 25 | t.Errorf("reverseWords() = %v, want %v", got, tt.want) 26 | } 27 | }) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /0152.maximum-product-subarray/maximum-product-subarray.go: -------------------------------------------------------------------------------- 1 | package _152_maximum_product_subarray 2 | 3 | func maxProduct(nums []int) int { 4 | dp := make([][]int, len(nums)) 5 | 6 | for i := 0; i < len(nums); i++ { 7 | dp[i] = make([]int, 2) 8 | } 9 | 10 | // [0]存小于0的值,[1]存大于0的值 11 | dp[0][0] = nums[0] 12 | dp[0][1] = nums[0] 13 | 14 | for i := 1; i < len(nums); i++ { 15 | if nums[i] > 0 { 16 | // 大于0, 正数*正数 求大,负数*正数 求小 17 | dp[i][1] = max(dp[i-1][1]*nums[i], nums[i]) 18 | dp[i][0] = min(dp[i-1][0]*nums[i], nums[i]) 19 | } else { 20 | // 小于0, 负数*负数 求大,正数*负数 求小 21 | dp[i][1] = max(dp[i-1][0]*nums[i], nums[i]) 22 | dp[i][0] = min(dp[i-1][1]*nums[i], nums[i]) 23 | } 24 | } 25 | 26 | res := -99999 27 | for i := 0; i < len(dp); i++ { 28 | if dp[i][1] > res { 29 | res = dp[i][1] 30 | } 31 | } 32 | 33 | return res 34 | } 35 | 36 | func max(a, b int) int { 37 | if a < b { 38 | return b 39 | } 40 | return a 41 | } 42 | 43 | func min(a, b int) int { 44 | if a > b { 45 | return b 46 | } 47 | return a 48 | } 49 | -------------------------------------------------------------------------------- /0155.min-stack/min-stack.go: -------------------------------------------------------------------------------- 1 | package _155_min_stack 2 | 3 | import "math" 4 | 5 | type MinStack struct { 6 | stack []int 7 | minStack []int // 用了一个辅助栈,栈顶元素最小 8 | } 9 | 10 | func Constructor() MinStack { 11 | return MinStack{ 12 | stack: []int{}, 13 | minStack: []int{math.MaxInt}, 14 | } 15 | } 16 | 17 | func (this *MinStack) Push(val int) { 18 | this.stack = append(this.stack, val) 19 | top := this.minStack[len(this.minStack)-1] 20 | this.minStack = append(this.minStack, min(val, top)) 21 | } 22 | 23 | func (this *MinStack) Pop() { 24 | this.stack = this.stack[:len(this.stack)-1] 25 | this.minStack = this.minStack[:len(this.minStack)-1] 26 | } 27 | 28 | func (this *MinStack) Top() int { 29 | return this.stack[len(this.stack)-1] 30 | } 31 | 32 | func (this *MinStack) GetMin() int { 33 | return this.minStack[len(this.minStack)-1] 34 | } 35 | 36 | func min(a, b int) int { 37 | if a < b { 38 | return a 39 | } 40 | return b 41 | } 42 | 43 | /** 44 | * Your MinStack object will be instantiated and called as such: 45 | * obj := Constructor(); 46 | * obj.Push(val); 47 | * obj.Pop(); 48 | * param_3 := obj.Top(); 49 | * param_4 := obj.GetMin(); 50 | */ 51 | -------------------------------------------------------------------------------- /0169.majority-element/majority-element.go: -------------------------------------------------------------------------------- 1 | package _169_majority_element 2 | 3 | func majorityElement(nums []int) int { 4 | candi, count := 0, 0 5 | 6 | for _, num := range nums { 7 | if count == 0 { 8 | candi = num 9 | } 10 | 11 | if num == candi { 12 | count++ 13 | } else { 14 | count-- 15 | } 16 | } 17 | 18 | return candi 19 | } 20 | -------------------------------------------------------------------------------- /0188.best-time-to-buy-and-sell-stock-iv/best-time-to-buy-and-sell-stock-iv.go: -------------------------------------------------------------------------------- 1 | package _188_best_time_to_buy_and_sell_stock_iv 2 | 3 | // k = 2, prices = [3,2,6,5,0,3] 4 | func maxProfit(k int, prices []int) int { 5 | if len(prices) <= 1 { 6 | return 0 7 | } 8 | 9 | dp := make([][][]int, len(prices)) 10 | for i := 0; i < len(prices); i++ { 11 | dp[i] = make([][]int, k+1) 12 | for j := k; j >= 0; j-- { 13 | dp[i][j] = make([]int, 2) 14 | } 15 | } 16 | 17 | for i := 0; i < len(prices); i++ { 18 | dp[i][0][0] = 0 19 | dp[i][0][1] = -999999999 20 | } 21 | 22 | for i := 0; i < len(prices); i++ { 23 | for j := k; j >= 1; j-- { 24 | if i == 0 { 25 | dp[i][j][0] = 0 26 | dp[i][j][1] = -prices[i] 27 | continue 28 | } 29 | 30 | dp[i][j][0] = max(dp[i-1][j][0], dp[i-1][j][1]+prices[i]) 31 | dp[i][j][1] = max(dp[i-1][j][1], dp[i-1][j-1][0]-prices[i]) 32 | } 33 | } 34 | 35 | return dp[len(prices)-1][k][0] 36 | } 37 | 38 | func max(a, b int) int { 39 | if a > b { 40 | return a 41 | } 42 | return b 43 | } 44 | -------------------------------------------------------------------------------- /0188.best-time-to-buy-and-sell-stock-iv/best-time-to-buy-and-sell-stock-iv_test.go: -------------------------------------------------------------------------------- 1 | package _188_best_time_to_buy_and_sell_stock_iv 2 | 3 | import "testing" 4 | 5 | func Test_maxProfit(t *testing.T) { 6 | type args struct { 7 | k int 8 | prices []int 9 | } 10 | tests := []struct { 11 | name string 12 | args args 13 | want int 14 | }{ 15 | { 16 | "test 1", 17 | args{ 18 | 2, 19 | []int{3, 2, 6, 5, 0, 3}, 20 | }, 21 | 7, 22 | }, 23 | } 24 | for _, tt := range tests { 25 | t.Run(tt.name, func(t *testing.T) { 26 | if got := maxProfit(tt.args.k, tt.args.prices); got != tt.want { 27 | t.Errorf("maxProfit() = %v, want %v", got, tt.want) 28 | } 29 | }) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /0198.house-robber/house-robber.go: -------------------------------------------------------------------------------- 1 | package _198_house_robber 2 | 3 | //input [2,7,9,3,1] 4 | func rob(nums []int) int { 5 | dp := make([][]int, len(nums)) 6 | 7 | for i := 0; i < len(dp); i++ { 8 | dp[i] = make([]int, 2) 9 | } 10 | 11 | // 偷 12 | dp[0][0] = nums[0] 13 | // 不偷 14 | dp[0][1] = 0 15 | 16 | for i := 1; i < len(nums); i++ { 17 | // 今天偷 18 | dp[i][0] = max(dp[i-1][1]+nums[i], dp[i-1][0]) 19 | // 今天不偷:昨天不偷,昨天偷 20 | dp[i][1] = max(dp[i-1][1], dp[i-1][0]) 21 | } 22 | 23 | if dp[len(nums)-1][1] > dp[len(nums)-1][0] { 24 | return dp[len(nums)-1][1] 25 | } else { 26 | return dp[len(nums)-1][0] 27 | } 28 | } 29 | 30 | func max(a, b int) int { 31 | if a < b { 32 | return b 33 | } 34 | 35 | return a 36 | } 37 | -------------------------------------------------------------------------------- /0198.house-robber/house-robber_test.go: -------------------------------------------------------------------------------- 1 | package _198_house_robber 2 | 3 | import "testing" 4 | 5 | func Test_rob(t *testing.T) { 6 | type args struct { 7 | nums []int 8 | } 9 | tests := []struct { 10 | name string 11 | args args 12 | want int 13 | }{ 14 | { 15 | "test1", 16 | args{ 17 | []int{2, 7, 9, 3, 1}, 18 | }, 19 | 12, 20 | }, 21 | } 22 | for _, tt := range tests { 23 | t.Run(tt.name, func(t *testing.T) { 24 | if got := rob(tt.args.nums); got != tt.want { 25 | t.Errorf("rob() = %v, want %v", got, tt.want) 26 | } 27 | }) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /0199.binary-tree-right-side-view/binary-tree-right-side-view.go: -------------------------------------------------------------------------------- 1 | package _199_binary_tree_right_side_view 2 | 3 | import "github.com/yigenshutiao/Golang-algorithm-template/util" 4 | 5 | type TreeNode = util.TreeNode 6 | 7 | func rightSideView(root *TreeNode) []int { 8 | res := [][]int{} 9 | if root == nil { 10 | return nil 11 | } 12 | 13 | queue := []*TreeNode{root} 14 | 15 | for len(queue) > 0 { 16 | l := len(queue) 17 | tmp := []int{} 18 | for i := 0; i < l; i++ { 19 | node := queue[0] 20 | if node.Left != nil { 21 | queue = append(queue, node.Left) 22 | } 23 | if node.Right != nil { 24 | queue = append(queue, node.Right) 25 | } 26 | tmp = append(tmp, node.Val) 27 | queue = queue[1:] 28 | } 29 | res = append(res, tmp) 30 | } 31 | 32 | resp := []int{} 33 | 34 | for i := 0; i < len(res); i++ { 35 | resp = append(resp, res[i][len(res[i])-1]) 36 | } 37 | return resp 38 | } 39 | -------------------------------------------------------------------------------- /0200.number-of-islands/number-of-islands.go: -------------------------------------------------------------------------------- 1 | package _200_number_of_islands 2 | 3 | func numIslands(grid [][]byte) int { 4 | var res int 5 | 6 | var dfs func(i, j int) 7 | 8 | dfs = func(i, j int) { 9 | if i < 0 || i >= len(grid) || j < 0 || j >= len(grid[0]) { 10 | return 11 | } 12 | 13 | if grid[i][j] == '1' { 14 | grid[i][j] = '2' 15 | } else { 16 | return 17 | } 18 | 19 | // 如果这个点是岛屿,往周边蔓延,染色所有岛屿 20 | dfs(i-1, j) 21 | dfs(i+1, j) 22 | dfs(i, j-1) 23 | dfs(i, j+1) 24 | } 25 | 26 | for i := 0; i < len(grid); i++ { 27 | for j := 0; j < len(grid[0]); j++ { 28 | if grid[i][j] == '1' { 29 | res++ 30 | dfs(i, j) 31 | } 32 | } 33 | } 34 | 35 | return res 36 | } 37 | -------------------------------------------------------------------------------- /0200.number-of-islands/number-of-islands_test.go: -------------------------------------------------------------------------------- 1 | package _200_number_of_islands 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func Test_numIslands(t *testing.T) { 8 | type args struct { 9 | grid [][]byte 10 | } 11 | tests := []struct { 12 | name string 13 | args args 14 | want int 15 | }{ 16 | { 17 | "test1", 18 | args{ 19 | [][]byte{{'1', '1', '0', '0', '0'}, {'1', '1', '0', '0', '0'}, {'0', '0', '1', '0', '0'}, {'0', '0', '0', '1', '1'}}, 20 | }, 21 | 3, 22 | }, 23 | } 24 | for _, tt := range tests { 25 | t.Run(tt.name, func(t *testing.T) { 26 | if got := numIslands(tt.args.grid); got != tt.want { 27 | t.Errorf("numIslands() = %v, want %v", got, tt.want) 28 | } 29 | }) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /0206. 反转链表/reverse-linked-list.go: -------------------------------------------------------------------------------- 1 | package _206_reverse_linked_list 2 | 3 | import "github.com/yigenshutiao/Golang-algorithm-template/util" 4 | 5 | type ListNode = util.ListNode 6 | 7 | func reverseList(head *ListNode) *ListNode { 8 | // 这里不能声明为 pre := &ListNode{}, 因为会初始化,这里只需要声明,不需要初始化 9 | var pre *ListNode 10 | 11 | for head != nil { 12 | next := head.Next 13 | head.Next = pre 14 | pre = head 15 | head = next 16 | } 17 | 18 | return pre 19 | } 20 | 21 | //递归 22 | func reverseListRecursion(head *ListNode) *ListNode { 23 | return help(nil, head) 24 | } 25 | 26 | func help(pre, head *ListNode) *ListNode { 27 | if head == nil { 28 | return pre 29 | } 30 | next := head.Next 31 | head.Next = pre 32 | return help(head, next) 33 | } 34 | -------------------------------------------------------------------------------- /0206. 反转链表/reverse-linked-list_test.go: -------------------------------------------------------------------------------- 1 | package _206_reverse_linked_list 2 | 3 | import ( 4 | "github.com/yigenshutiao/Golang-algorithm-template/util" 5 | "reflect" 6 | "testing" 7 | ) 8 | 9 | func Test_reverseListRecursion(t *testing.T) { 10 | nodes := util.Ints2List([]int{1, 2, 3, 4, 5}) 11 | wants := util.Ints2List([]int{5, 4, 3, 2, 1}) 12 | type args struct { 13 | head *ListNode 14 | } 15 | tests := []struct { 16 | name string 17 | args args 18 | want *ListNode 19 | }{ 20 | { 21 | "test1", 22 | args{ 23 | nodes, 24 | }, 25 | wants, 26 | }, 27 | } 28 | for _, tt := range tests { 29 | t.Run(tt.name, func(t *testing.T) { 30 | if got := reverseListRecursion(tt.args.head); !reflect.DeepEqual(got, tt.want) { 31 | t.Errorf("reverseListRecursion() = %v, want %v", got, tt.want) 32 | } 33 | }) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /0207.course-schedule/course-schedule.go: -------------------------------------------------------------------------------- 1 | package _207_course_schedule 2 | 3 | func canFinish(numCourses int, prerequisites [][]int) bool { 4 | // 依赖出度明细和入度值 5 | // 记录每个元素的出度 6 | graph := make([][]int, numCourses) 7 | // 记录从 0 到 n-1,所有元素的入度 8 | degreeIn := make([]int, numCourses) 9 | 10 | for _, pair := range prerequisites { 11 | cur, rely := pair[0], pair[1] 12 | degreeIn[cur]++ 13 | graph[rely] = append(graph[rely], cur) 14 | } 15 | 16 | queue := make([]int, 0) 17 | // 把所有入度为0的元素放在queue里面 18 | for node, val := range degreeIn { 19 | if val == 0 { 20 | queue = append(queue, node) 21 | } 22 | } 23 | 24 | var cnt int 25 | for len(queue) > 0 { 26 | node := queue[0] 27 | queue = queue[1:] 28 | cnt++ 29 | 30 | // 遍历元素所有的出度,把出度元素的入度-- 31 | for _, val := range graph[node] { 32 | degreeIn[val]-- 33 | if degreeIn[val] == 0 { 34 | queue = append(queue, val) 35 | } 36 | } 37 | } 38 | 39 | return cnt == numCourses 40 | } 41 | -------------------------------------------------------------------------------- /0207.course-schedule/course-schedule_test.go: -------------------------------------------------------------------------------- 1 | package _207_course_schedule 2 | 3 | import "testing" 4 | 5 | func Test_canFinish(t *testing.T) { 6 | type args struct { 7 | numCourses int 8 | prerequisites [][]int 9 | } 10 | tests := []struct { 11 | name string 12 | args args 13 | want bool 14 | }{ 15 | { 16 | "test1", 17 | args{ 18 | 6, 19 | [][]int{{3, 0}, {3, 1}, {4, 1}, {4, 2}, {5, 3}, {5, 4}}, 20 | }, 21 | true, 22 | }, 23 | } 24 | for _, tt := range tests { 25 | t.Run(tt.name, func(t *testing.T) { 26 | if got := canFinish(tt.args.numCourses, tt.args.prerequisites); got != tt.want { 27 | t.Errorf("canFinish() = %v, want %v", got, tt.want) 28 | } 29 | }) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /0213.house-robber-ii/house-robber-ii.go: -------------------------------------------------------------------------------- 1 | package _213_house_robber_ii 2 | 3 | // nums= []int{1,2,3,1} 4 | func rob(nums []int) int { 5 | 6 | if nums == nil { 7 | return 0 8 | } 9 | 10 | if len(nums) == 1 { 11 | return nums[0] 12 | } 13 | 14 | if len(nums) == 2 { 15 | return max(nums[0], nums[1]) 16 | } 17 | 18 | // 偷了第一间,不能偷最后一间 19 | res1 := robs(nums[0 : len(nums)-1]) 20 | // 偷了最后一间,不能偷第一间 21 | res2 := robs(nums[1:len(nums)]) 22 | 23 | // 所以两种方案都试试,最后选择利润高的方案 24 | return max(res1, res2) 25 | } 26 | func robs(nums []int) int { 27 | if len(nums) == 2 { 28 | return max(nums[0], nums[1]) 29 | } 30 | dp := make([]int, len(nums)+1) 31 | dp[0] = 0 32 | for i := 0; i < len(nums); i++ { 33 | if i == 0 { 34 | dp[1] = nums[0] 35 | continue 36 | } 37 | if i == 1 { 38 | dp[2] = max(dp[0], nums[i]) 39 | } 40 | 41 | dp[i+1] = max(dp[i], dp[i-1]+nums[i]) 42 | } 43 | 44 | return dp[len(nums)] 45 | } 46 | 47 | func max(a, b int) int { 48 | if a > b { 49 | return a 50 | } 51 | return b 52 | } 53 | -------------------------------------------------------------------------------- /0213.house-robber-ii/house-robber-ii_test.go: -------------------------------------------------------------------------------- 1 | package _213_house_robber_ii 2 | 3 | import "testing" 4 | 5 | func Test_rob(t *testing.T) { 6 | type args struct { 7 | nums []int 8 | } 9 | tests := []struct { 10 | name string 11 | args args 12 | want int 13 | }{ 14 | { 15 | "test 1", 16 | args{ 17 | []int{1, 2, 3, 1}, 18 | }, 19 | 4, 20 | }, 21 | } 22 | for _, tt := range tests { 23 | t.Run(tt.name, func(t *testing.T) { 24 | if got := rob(tt.args.nums); got != tt.want { 25 | t.Errorf("rob() = %v, want %v", got, tt.want) 26 | } 27 | }) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /0215.kth-largest-element-in-an-array/kth-largest-element-in-an-array.go: -------------------------------------------------------------------------------- 1 | package _215_kth_largest_element_in_an_array 2 | 3 | func findKthLargest(nums []int, k int) int { 4 | // 找k大的,就是找pos小的 5 | resPos := len(nums) - k 6 | left, right := 0, len(nums)-1 7 | for { 8 | pos := getPos(nums, left, right) 9 | if pos == resPos { 10 | return nums[pos] 11 | } else if pos > resPos { 12 | // 如果找到的位置在结果的右边, 说明答案在左边,往左边收缩 13 | right = pos - 1 14 | } else if pos < resPos { 15 | // 如果找到位置在pos左边,说明答案在右边,往右边收缩 16 | left = pos + 1 17 | } 18 | } 19 | } 20 | 21 | func getPos(nums []int, left, right int) int { 22 | idx, pos := left, right 23 | for i := right; i >= left; i-- { 24 | if nums[i] > nums[idx] { 25 | nums[i], nums[pos] = nums[pos], nums[i] 26 | pos-- 27 | } 28 | } 29 | nums[pos], nums[idx] = nums[idx], nums[pos] 30 | return pos 31 | } 32 | -------------------------------------------------------------------------------- /0215.kth-largest-element-in-an-array/kth-largest-element-in-an-array_test.go: -------------------------------------------------------------------------------- 1 | package _215_kth_largest_element_in_an_array 2 | 3 | import "testing" 4 | 5 | func Test_findKthLargest(t *testing.T) { 6 | type args struct { 7 | nums []int 8 | k int 9 | } 10 | tests := []struct { 11 | name string 12 | args args 13 | want int 14 | }{ 15 | //{ 16 | // "test 1", 17 | // args{ 18 | // []int{3, 2, 3, 1, 2, 4, 5, 5, 6, 7, 7, 8, 2, 3, 1, 1, 1, 10, 11, 5, 6, 2, 4, 7, 8, 5, 6}, 19 | // 1, 20 | // }, 21 | // 11, 22 | //}, 23 | { 24 | "test 1", 25 | args{ 26 | []int{6, 5, 4, 3, 2, 1}, 27 | 2, 28 | }, 29 | 5, 30 | }, 31 | { 32 | "test 2", 33 | args{ 34 | []int{2, 1}, 35 | 2, 36 | }, 37 | 1, 38 | }, 39 | } 40 | for _, tt := range tests { 41 | t.Run(tt.name, func(t *testing.T) { 42 | if got := findKthLargest(tt.args.nums, tt.args.k); got != tt.want { 43 | t.Errorf("findKthLargest() = %v, want %v", got, tt.want) 44 | } 45 | }) 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /0221.maximal-square/maximal-square.go: -------------------------------------------------------------------------------- 1 | package _221_maximal_square 2 | 3 | func maximalSquare(matrix [][]byte) int { 4 | dp := make([][]int, len(matrix)) 5 | 6 | square := 0 7 | for i := 0; i < len(dp); i++ { 8 | dp[i] = make([]int, len(matrix[i])) 9 | for j := 0; j < len(dp[i]); j++ { 10 | x := matrix[i][j] - '0' 11 | if x == 1 { 12 | dp[i][j] = 1 13 | square = 1 14 | } 15 | } 16 | } 17 | 18 | for i := 1; i < len(dp); i++ { 19 | for j := 1; j < len(dp[i]); j++ { 20 | // 这个if条件需要注意一下,当是1的时候才需要计算 21 | if dp[i][j] == 1 { 22 | dp[i][j] = min(min(dp[i-1][j], dp[i][j-1]), dp[i-1][j-1]) + 1 23 | if dp[i][j] > square { 24 | square = dp[i][j] 25 | } 26 | } 27 | } 28 | } 29 | 30 | return square * square 31 | } 32 | 33 | func min(a, b int) int { 34 | if a < b { 35 | return a 36 | } 37 | return b 38 | } 39 | -------------------------------------------------------------------------------- /0221.maximal-square/maximal-square_test.go: -------------------------------------------------------------------------------- 1 | package _221_maximal_square 2 | 3 | import "testing" 4 | 5 | func Test_maximalSquare(t *testing.T) { 6 | type args struct { 7 | matrix [][]byte 8 | } 9 | tests := []struct { 10 | name string 11 | args args 12 | want int 13 | }{ 14 | { 15 | "test 1", 16 | args{[][]byte{ 17 | {'1', '0', '1', '0', '0'}, 18 | {'1', '0', '1', '1', '1'}, 19 | {'1', '1', '1', '1', '1'}, 20 | {'1', '0', '0', '1', '0'}, 21 | }}, 22 | 4, 23 | }, 24 | } 25 | for _, tt := range tests { 26 | t.Run(tt.name, func(t *testing.T) { 27 | if got := maximalSquare(tt.args.matrix); got != tt.want { 28 | t.Errorf("maximalSquare() = %v, want %v", got, tt.want) 29 | } 30 | }) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /0222.count-complete-tree-nodes/count-complete-tree-nodes.go: -------------------------------------------------------------------------------- 1 | package _222_count_complete_tree_nodes 2 | 3 | import "github.com/yigenshutiao/Golang-algorithm-template/util" 4 | 5 | type TreeNode = util.TreeNode 6 | 7 | func countNodes(root *TreeNode) int { 8 | var res int 9 | var dfs func(root *TreeNode) 10 | dfs = func(root *TreeNode) { 11 | if root == nil { 12 | return 13 | } 14 | res += 1 15 | dfs(root.Left) 16 | dfs(root.Right) 17 | 18 | } 19 | dfs(root) 20 | return res 21 | } 22 | -------------------------------------------------------------------------------- /0226.invert-binary-tree/invert-binary-tree.go: -------------------------------------------------------------------------------- 1 | package _226_invert_binary_tree 2 | 3 | import "github.com/yigenshutiao/Golang-algorithm-template/util" 4 | 5 | type TreeNode = util.TreeNode 6 | 7 | func invertTree(root *TreeNode) *TreeNode { 8 | if root == nil { 9 | return nil 10 | } 11 | 12 | root.Left, root.Right = root.Right, root.Left 13 | 14 | invertTree(root.Left) 15 | invertTree(root.Right) 16 | 17 | return root 18 | } 19 | -------------------------------------------------------------------------------- /0230.kth-smallest-element-in-a-bst/kth-smallest-element-in-a-bst.go: -------------------------------------------------------------------------------- 1 | package _230_kth_smallest_element_in_a_bst 2 | 3 | import "github.com/yigenshutiao/Golang-algorithm-template/util" 4 | 5 | type TreeNode = util.TreeNode 6 | 7 | var i int 8 | var res int 9 | 10 | func kthSmallest(root *TreeNode, k int) int { 11 | i = 0 12 | res = -1 13 | run(root, k) 14 | return res 15 | } 16 | 17 | func run(root *TreeNode, k int) { 18 | if root == nil { 19 | return 20 | } 21 | run(root.Left, k) 22 | 23 | i++ 24 | if i == k { 25 | res = root.Val 26 | return 27 | } 28 | run(root.Right, k) 29 | } 30 | -------------------------------------------------------------------------------- /0230.kth-smallest-element-in-a-bst/kth-smallest-element-in-a-bst_test.go: -------------------------------------------------------------------------------- 1 | package _230_kth_smallest_element_in_a_bst 2 | 3 | import ( 4 | "fmt" 5 | "github.com/stretchr/testify/assert" 6 | "github.com/yigenshutiao/Golang-algorithm-template/util" 7 | "testing" 8 | ) 9 | 10 | var tcs = []struct { 11 | pre, in []int 12 | k int 13 | ans int 14 | }{ 15 | 16 | //{ 17 | // []int{1, 2}, 18 | // []int{1, 2}, 19 | // 2, 20 | // 2, 21 | //}, 22 | // 23 | //{ 24 | // []int{2, 1, 3}, 25 | // []int{1, 2, 3}, 26 | // 1, 27 | // 1, 28 | //}, 29 | 30 | { 31 | []int{2, 1, 3}, 32 | []int{1, 2, 3}, 33 | 2, 34 | 2, 35 | }, 36 | 37 | //{ 38 | // []int{2, 1, 3}, 39 | // []int{1, 2, 3}, 40 | // 3, 41 | // 3, 42 | //}, 43 | 44 | // 可以有多个 testcase 45 | } 46 | 47 | func Test_kthSmallest(t *testing.T) { 48 | ast := assert.New(t) 49 | 50 | for _, tc := range tcs { 51 | fmt.Printf("~~%v~~\n", tc) 52 | root := util.PreIn2Tree(tc.pre, tc.in) 53 | ast.Equal(tc.ans, kthSmallest(root, tc.k), "输入:%v", tc) 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /0234.palindrome-linked-list/palindrome-linked-list.go: -------------------------------------------------------------------------------- 1 | package _234_palindrome_linked_list 2 | 3 | import "github.com/yigenshutiao/Golang-algorithm-template/util" 4 | 5 | /** 6 | * Definition for singly-linked list. 7 | * type ListNode struct { 8 | * Val int 9 | * Next *ListNode 10 | * } 11 | */ 12 | 13 | type ListNode = util.ListNode 14 | 15 | func isPalindrome(head *ListNode) bool { 16 | fast, slow := head, head 17 | for fast != nil && fast.Next != nil { 18 | slow = slow.Next 19 | fast = fast.Next.Next 20 | } 21 | 22 | right := traverse(slow) 23 | 24 | newCur := head 25 | for right != nil { 26 | if newCur.Val != right.Val { 27 | return false 28 | } 29 | right = right.Next 30 | newCur = newCur.Next 31 | } 32 | 33 | return true 34 | 35 | } 36 | 37 | func traverse(head *ListNode) *ListNode { 38 | var pre *ListNode 39 | for head != nil { 40 | next := head.Next 41 | head.Next = pre 42 | pre = head 43 | head = next 44 | } 45 | return pre 46 | } 47 | -------------------------------------------------------------------------------- /0234.palindrome-linked-list/palindrome-linked-list_test.go: -------------------------------------------------------------------------------- 1 | package _234_palindrome_linked_list 2 | 3 | import ( 4 | "github.com/yigenshutiao/Golang-algorithm-template/util" 5 | "testing" 6 | ) 7 | 8 | func Test_isPalindrome(t *testing.T) { 9 | head := util.Ints2List([]int{1, 2, 2, 1}) 10 | type args struct { 11 | head *ListNode 12 | } 13 | tests := []struct { 14 | name string 15 | args args 16 | want bool 17 | }{ 18 | { 19 | "test 1", 20 | args{ 21 | head, 22 | }, 23 | true, 24 | }, 25 | } 26 | for _, tt := range tests { 27 | t.Run(tt.name, func(t *testing.T) { 28 | if got := isPalindrome(tt.args.head); got != tt.want { 29 | t.Errorf("isPalindrome() = %v, want %v", got, tt.want) 30 | } 31 | }) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /0235.lowest-common-ancestor-of-a-binary-search-tree/lowest-common-ancestor-of-a-binary-search-tree.go: -------------------------------------------------------------------------------- 1 | package _235_lowest_common_ancestor_of_a_binary_search_tree 2 | 3 | import "github.com/yigenshutiao/Golang-algorithm-template/util" 4 | 5 | type TreeNode = util.TreeNode 6 | 7 | func lowestCommonAncestor(root, p, q *TreeNode) *TreeNode { 8 | if root == nil { 9 | return nil 10 | } 11 | if root.Val > p.Val && root.Val > q.Val { 12 | return lowestCommonAncestor(root.Left, p, q) 13 | } else if root.Val < p.Val && root.Val < q.Val { 14 | return lowestCommonAncestor(root.Right, p, q) 15 | } 16 | return root 17 | } 18 | -------------------------------------------------------------------------------- /0238.product-of-array-except-self/product-of-array-except-self.go: -------------------------------------------------------------------------------- 1 | package _238_product_of_array_except_self 2 | 3 | func productExceptSelf(nums []int) []int { 4 | res := make([]int, len(nums)) 5 | if len(nums) < 1 { 6 | return res 7 | } 8 | leftNums := make([]int, len(nums)) 9 | leftNums[0] = 1 10 | for i := 1; i < len(nums); i++ { 11 | leftNums[i] = nums[i-1] * leftNums[i-1] 12 | } 13 | rigtNums := make([]int, len(nums)) 14 | rigtNums[len(nums)-1] = 1 15 | for i := len(nums) - 2; i >= 0; i-- { 16 | rigtNums[i] = nums[i+1] * rigtNums[i+1] 17 | } 18 | 19 | for i := 0; i < len(nums); i++ { 20 | res[i] = leftNums[i] * rigtNums[i] 21 | } 22 | 23 | return res 24 | } 25 | -------------------------------------------------------------------------------- /0238.product-of-array-except-self/product-of-array-except-self_test.go: -------------------------------------------------------------------------------- 1 | package _238_product_of_array_except_self 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_productExceptSelf(t *testing.T) { 9 | type args struct { 10 | nums []int 11 | } 12 | tests := []struct { 13 | name string 14 | args args 15 | want []int 16 | }{ 17 | { 18 | "test1", 19 | args{[]int{1, 2, 3, 4}}, 20 | []int{24, 12, 8, 6}, 21 | }, 22 | } 23 | for _, tt := range tests { 24 | t.Run(tt.name, func(t *testing.T) { 25 | if got := productExceptSelf(tt.args.nums); !reflect.DeepEqual(got, tt.want) { 26 | t.Errorf("productExceptSelf() = %v, want %v", got, tt.want) 27 | } 28 | }) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /0240.search-a-2d-matrix-ii/search-a-2d-matrix-ii.go: -------------------------------------------------------------------------------- 1 | package _240_search_a_2d_matrix_ii 2 | 3 | // searchMatrix 方法比较巧妙,从第一行最右边开始遍历,是二分属性 4 | // 第一行左边的值都小于x ,第一行下面的值都大于x 5 | func searchMatrix(matrix [][]int, target int) bool { 6 | 7 | i, j := len(matrix[0])-1, 0 8 | for i >= 0 && j < len(matrix) { 9 | if matrix[j][i] == target { 10 | return true 11 | } else if matrix[j][i] > target { 12 | i-- 13 | } else if matrix[j][i] < target { 14 | j++ 15 | } 16 | } 17 | 18 | return false 19 | } 20 | -------------------------------------------------------------------------------- /0257.binary-tree-paths/binary-tree-paths.go: -------------------------------------------------------------------------------- 1 | package _257_binary_tree_paths 2 | 3 | import ( 4 | "fmt" 5 | "github.com/yigenshutiao/Golang-algorithm-template/util" 6 | ) 7 | 8 | type TreeNode = util.TreeNode 9 | 10 | func binaryTreePaths(root *TreeNode) []string { 11 | res := make([]string, 0) 12 | var traverse func(node *TreeNode, path string) 13 | traverse = func(node *TreeNode, path string) { 14 | if node.Left == nil && node.Right == nil { 15 | v := path + fmt.Sprintf("%+v", node.Val) 16 | res = append(res, v) 17 | return 18 | } 19 | 20 | path = path + fmt.Sprintf("%+v", node.Val) + "->" 21 | if node.Left != nil { 22 | traverse(node.Left, path) 23 | } 24 | 25 | if node.Right != nil { 26 | traverse(node.Right, path) 27 | } 28 | } 29 | 30 | traverse(root, "") 31 | return res 32 | } 33 | -------------------------------------------------------------------------------- /0279.perfect-squares/perfect-squares.go: -------------------------------------------------------------------------------- 1 | package _279_perfect_squares 2 | 3 | func numSquares(n int) int { 4 | dp := make([]int, n+1) 5 | 6 | dp[0] = 0 7 | for i := 1; i <= n; i++ { 8 | dp[i] = i + 1 9 | for j := 1; j*j <= i; j++ { 10 | dp[i] = min(dp[i], dp[i-j*j]+1) 11 | } 12 | } 13 | 14 | return dp[n] 15 | } 16 | 17 | func min(a, b int) int { 18 | if a < b { 19 | return a 20 | } 21 | 22 | return b 23 | } 24 | -------------------------------------------------------------------------------- /0279.perfect-squares/perfect-squares_test.go: -------------------------------------------------------------------------------- 1 | package _279_perfect_squares 2 | 3 | import "testing" 4 | 5 | func Test_numSquares(t *testing.T) { 6 | type args struct { 7 | n int 8 | } 9 | tests := []struct { 10 | name string 11 | args args 12 | want int 13 | }{ 14 | { 15 | "test1", 16 | args{ 17 | 13, 18 | }, 19 | 2, 20 | }, 21 | } 22 | for _, tt := range tests { 23 | t.Run(tt.name, func(t *testing.T) { 24 | if got := numSquares(tt.args.n); got != tt.want { 25 | t.Errorf("numSquares() = %v, want %v", got, tt.want) 26 | } 27 | }) 28 | } 29 | } 30 | 31 | func Test_numSquare(t *testing.T) { 32 | type args struct { 33 | n int 34 | } 35 | tests := []struct { 36 | name string 37 | args args 38 | want int 39 | }{ 40 | { 41 | "test1", 42 | args{ 43 | 12, 44 | }, 45 | 3, 46 | }, 47 | } 48 | for _, tt := range tests { 49 | t.Run(tt.name, func(t *testing.T) { 50 | if got := numSquare(tt.args.n); got != tt.want { 51 | t.Errorf("numSquare() = %v, want %v", got, tt.want) 52 | } 53 | }) 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /0283.move-zeroes/move-zeroes.go: -------------------------------------------------------------------------------- 1 | package _283_move_zeroes 2 | 3 | // 双指针 4 | func moveZeroes(nums []int) []int { 5 | // l想要指的是0值所处的位置 6 | // r是非0值的位置,要不断移动 7 | l, r := 0, 0 8 | n := len(nums) 9 | 10 | for r < n { 11 | if nums[r] != 0 { 12 | nums[l], nums[r] = nums[r], nums[l] 13 | l++ 14 | } 15 | r++ 16 | } 17 | return nums 18 | } 19 | 20 | // 暴力解法 21 | func moveZeroes2(nums []int) []int { 22 | if len(nums) < 2 { 23 | return nums 24 | } 25 | for i := 0; i < len(nums); i++ { 26 | if nums[i] == 0 { 27 | t := i 28 | for j := i + 1; j < len(nums); j++ { 29 | if nums[j] != 0 { 30 | nums[i], nums[j] = nums[j], nums[i] 31 | i = j 32 | } 33 | } 34 | i = t 35 | } 36 | } 37 | return nums 38 | } 39 | -------------------------------------------------------------------------------- /0287.find-the-duplicate-number/find-the-duplicate-number.go: -------------------------------------------------------------------------------- 1 | package _287_find_the_duplicate_number 2 | 3 | func findDuplicate(nums []int) int { 4 | n := len(nums) 5 | l, r := 1, n-1 6 | 7 | for l < r { 8 | mid := (l + r) >> 1 9 | cnt := 0 10 | 11 | // 这里一定是小于 等于mid的个数 12 | for _, num := range nums { 13 | if num <= mid { 14 | cnt++ 15 | } 16 | } 17 | 18 | // 如果小于mid的cnt > mid,说明左边"]"有重复,否则说明右边(有重复 19 | if cnt > mid { 20 | r = mid 21 | } else { 22 | l = mid + 1 23 | } 24 | } 25 | 26 | return l 27 | } 28 | -------------------------------------------------------------------------------- /0287.find-the-duplicate-number/find-the-duplicate-number_test.go: -------------------------------------------------------------------------------- 1 | package _287_find_the_duplicate_number 2 | 3 | import "testing" 4 | 5 | func Test_findDuplicate(t *testing.T) { 6 | type args struct { 7 | nums []int 8 | } 9 | tests := []struct { 10 | name string 11 | args args 12 | want int 13 | }{ 14 | { 15 | "test 1", 16 | args{ 17 | []int{1, 3, 4, 2, 2}, 18 | }, 19 | 2, 20 | }, 21 | } 22 | for _, tt := range tests { 23 | t.Run(tt.name, func(t *testing.T) { 24 | if got := findDuplicate(tt.args.nums); got != tt.want { 25 | t.Errorf("findDuplicate() = %v, want %v", got, tt.want) 26 | } 27 | }) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /0297.serialize-and-deserialize-binary-tree/serialize-and-deserialize-binary-tree_test.go: -------------------------------------------------------------------------------- 1 | package _297_serialize_and_deserialize_binary_tree 2 | 3 | import ( 4 | "fmt" 5 | "github.com/yigenshutiao/Golang-algorithm-template/util" 6 | "testing" 7 | ) 8 | 9 | func TestCodec_deserialize(t *testing.T) { 10 | 11 | tcs := struct { 12 | pre, in []int 13 | }{ 14 | []int{1, 2, 3, 4, 5}, 15 | []int{2, 1, 4, 3, 5}, 16 | } 17 | 18 | ser := Constructor() 19 | 20 | deser := Constructor() 21 | 22 | data := ser.serialize(util.PreIn2Tree(tcs.pre, tcs.in)) 23 | 24 | ans := deser.deserialize(data) 25 | 26 | fmt.Println(ans) 27 | } 28 | -------------------------------------------------------------------------------- /0300.longest-increasing-subsequence/longest-increasing-subsequence.go: -------------------------------------------------------------------------------- 1 | package _300_longest_increasing_subsequence 2 | 3 | func lengthOfLIS(nums []int) int { 4 | var res int 5 | 6 | dp := make([]int, len(nums)+1) 7 | for i := 0; i < len(dp); i++ { 8 | dp[i] = 1 9 | } 10 | 11 | for i := 0; i < len(nums); i++ { 12 | for j := i + 1; j < len(nums); j++ { 13 | if nums[j] > nums[i] { 14 | dp[j] = max(dp[j], dp[i]+1) 15 | } 16 | } 17 | } 18 | 19 | for i := 0; i < len(dp); i++ { 20 | if res < dp[i] { 21 | res = dp[i] 22 | } 23 | } 24 | 25 | return res 26 | } 27 | 28 | func max(a, b int) int { 29 | if a < b { 30 | return b 31 | } 32 | return a 33 | } 34 | -------------------------------------------------------------------------------- /0301.remove-invalid-parentheses/remove-invalid-parentheses_test.go: -------------------------------------------------------------------------------- 1 | package _301_remove_invalid_parentheses 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_removeInvalidParentheses(t *testing.T) { 9 | type args struct { 10 | s string 11 | } 12 | tests := []struct { 13 | name string 14 | args args 15 | wantAns []string 16 | }{ 17 | { 18 | "test 1", 19 | args{ 20 | "(a)())()", 21 | }, 22 | []string{"(a())()", "(a)()()"}, 23 | }, 24 | } 25 | for _, tt := range tests { 26 | t.Run(tt.name, func(t *testing.T) { 27 | if gotAns := removeInvalidParentheses(tt.args.s); !reflect.DeepEqual(gotAns, tt.wantAns) { 28 | t.Errorf("removeInvalidParentheses() = %v, want %v", gotAns, tt.wantAns) 29 | } 30 | }) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /0309.best-time-to-buy-and-sell-stock-with-cooldown/best-time-to-buy-and-sell-stock-with-cooldown.go: -------------------------------------------------------------------------------- 1 | package _309_best_time_to_buy_and_sell_stock_with_cooldown 2 | 3 | //input [1,2,3,0,2] 4 | func maxProfit(prices []int) int { 5 | dp := make([][]int, len(prices)) 6 | for i := 0; i < len(prices); i++ { 7 | dp[i] = make([]int, 2) 8 | } 9 | 10 | // 第一个元素是天数,第二个元素,0没有股票,1代表有股票 11 | dp[0][0] = 0 12 | dp[0][1] = -prices[0] 13 | 14 | for i := 1; i < len(prices); i++ { 15 | 16 | if i == 1 { 17 | // 第一天的话,不持有股票: 前一天不持有股票,前一天持有股票,今天卖了 18 | dp[i][0] = max(dp[i-1][0], dp[i-1][1]+prices[i]) 19 | // 持有股票:前一天持有股票,前一天不持有股票,今天买 20 | dp[i][1] = max(dp[i-1][1], -prices[i]) 21 | continue 22 | } 23 | 24 | // 今天不持有股票:昨天不持有股票,昨天持有股票,今天卖 25 | dp[i][0] = max(dp[i-1][0], dp[i-1][1]+prices[i]) 26 | // 今天持有股票:昨天持有股票,前天不持有股票,昨天冷冻期,今天买 27 | dp[i][1] = max(dp[i-1][1], dp[i-2][0]-prices[i]) 28 | } 29 | return dp[len(prices)-1][0] 30 | } 31 | 32 | func max(a, b int) int { 33 | if a > b { 34 | return a 35 | } 36 | return b 37 | } 38 | -------------------------------------------------------------------------------- /0309.best-time-to-buy-and-sell-stock-with-cooldown/best-time-to-buy-and-sell-stock-with-cooldown_test.go: -------------------------------------------------------------------------------- 1 | package _309_best_time_to_buy_and_sell_stock_with_cooldown 2 | 3 | import "testing" 4 | 5 | func Test_maxProfit(t *testing.T) { 6 | type args struct { 7 | prices []int 8 | } 9 | tests := []struct { 10 | name string 11 | args args 12 | want int 13 | }{ 14 | { 15 | "test1", 16 | args{ 17 | []int{1, 2, 3, 0, 2}, 18 | }, 19 | 3, 20 | }, 21 | } 22 | for _, tt := range tests { 23 | t.Run(tt.name, func(t *testing.T) { 24 | if got := maxProfit(tt.args.prices); got != tt.want { 25 | t.Errorf("maxProfit() = %v, want %v", got, tt.want) 26 | } 27 | }) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /0322.coin-change/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | // 6 | // 硬币面额为:c1 ~ cn 7 | // 状态转移方程:f(n) = min(f(n - c1), f(n - c2), ... f(n - cn)) + 1 8 | func coinChange(coins []int, amount int) int { 9 | // dp[i] 金额为 i 时,所需零钱最小数量 10 | // dp[0] 应该等于0,兑换0,需要的零钱是0 11 | dp := make([]int, amount+1) 12 | 13 | for i := 1; i <= amount; i++ { 14 | // 随便搞个无解的默认值,用来初始化dp数组,这一步很关键 15 | dp[i] = amount + 1 16 | for _, c := range coins { 17 | if i >= c { 18 | dp[i] = min(dp[i], dp[i-c]+1) 19 | } 20 | } 21 | } 22 | 23 | if dp[amount] > amount { 24 | return -1 25 | } 26 | 27 | return dp[amount] 28 | } 29 | 30 | func min(i, j int) int { 31 | if i < j { 32 | return i 33 | } 34 | return j 35 | } 36 | 37 | func main() { 38 | fmt.Println(coinChange([]int{1, 2, 5}, 11)) 39 | } 40 | -------------------------------------------------------------------------------- /0337.house-robber-iii/house-robber-iii.go: -------------------------------------------------------------------------------- 1 | package _337_house_robber_iii 2 | 3 | import "github.com/yigenshutiao/Golang-algorithm-template/util" 4 | 5 | type TreeNode = util.TreeNode 6 | 7 | func rob(root *TreeNode) int { 8 | // dp数组就两个元素,一个是0代表偷当前节点的最大值,1代表不偷当前节点的最大值 9 | // 当前节点依赖子节点,所以遍历顺序是后续遍历 10 | val := dfs(root) 11 | // 0代表选择当前节点,1代表不选择当前节点 12 | return max(val[0], val[1]) 13 | } 14 | 15 | func dfs(root *TreeNode) []int { 16 | if root == nil { 17 | return []int{0, 0} 18 | } 19 | 20 | left, right := dfs(root.Left), dfs(root.Right) 21 | // 偷当前节点,左右孩子就不能偷 22 | choose := root.Val + left[1] + right[1] 23 | // 不偷当前节点,可以任意选择左右孩子的最大值 24 | notChoose := max(left[0], left[1]) + max(right[0], right[1]) 25 | 26 | return []int{choose, notChoose} 27 | } 28 | 29 | func max(a, b int) int { 30 | if a > b { 31 | return a 32 | } 33 | return b 34 | } 35 | -------------------------------------------------------------------------------- /0338.counting-bits/counting-bits.go: -------------------------------------------------------------------------------- 1 | package _338_counting_bits 2 | 3 | func countBits(n int) []int { 4 | dp := make([]int, n+1) 5 | 6 | dp[0] = 0 7 | 8 | for i := 1; i <= n; i++ { 9 | if i%2 == 1 { 10 | dp[i] = dp[i-1] + 1 11 | } else { 12 | dp[i] = dp[i/2] 13 | } 14 | } 15 | return dp 16 | } 17 | -------------------------------------------------------------------------------- /0341.flatten-nested-list-iterator/flatten-nested-list-iterator.go: -------------------------------------------------------------------------------- 1 | package _341_flatten_nested_list_iterator 2 | 3 | type NestedInteger struct { 4 | } 5 | 6 | func (this NestedInteger) GetInteger() int { 7 | // 题里给了 8 | return 0 9 | } 10 | 11 | func (this NestedInteger) GetList() []*NestedInteger { 12 | // xx 13 | return nil 14 | } 15 | 16 | func (this NestedInteger) IsInteger() bool { 17 | // 题里给了 18 | return false 19 | } 20 | 21 | type NestedIterator struct { 22 | Vals []int 23 | } 24 | 25 | func Constructor(nestedList []*NestedInteger) *NestedIterator { 26 | var vals []int 27 | var dfs func(nestedList []*NestedInteger) 28 | dfs = func(nestedList []*NestedInteger) { 29 | for _, nest := range nestedList { 30 | if nest.IsInteger() { 31 | vals = append(vals, nest.GetInteger()) 32 | } else { 33 | dfs(nest.GetList()) 34 | } 35 | } 36 | } 37 | dfs(nestedList) 38 | return &NestedIterator{Vals: vals} 39 | } 40 | 41 | func (this *NestedIterator) Next() int { 42 | node := this.Vals[0] 43 | this.Vals = this.Vals[1:] 44 | return node 45 | } 46 | 47 | func (this *NestedIterator) HasNext() bool { 48 | return len(this.Vals) > 0 49 | } 50 | -------------------------------------------------------------------------------- /0343.integer-break/integer-break.go: -------------------------------------------------------------------------------- 1 | package _343_integer_break 2 | 3 | func integerBreak(n int) int { 4 | dp := make([]int, n+1) 5 | 6 | dp[2] = 1 7 | 8 | for i := 3; i <= n; i++ { 9 | for j := 1; j < i-1; j++ { 10 | dp[i] = max(dp[i], max((i-j)*j, dp[i-j]*j)) 11 | } 12 | } 13 | 14 | return dp[n] 15 | } 16 | 17 | func max(a, b int) int { 18 | if a > b { 19 | return a 20 | } 21 | return b 22 | } 23 | -------------------------------------------------------------------------------- /0347.top-k-frequent-elements/top-k-frequent-elements.go: -------------------------------------------------------------------------------- 1 | package _347_top_k_frequent_elements 2 | 3 | import "sort" 4 | 5 | func topKFrequent(nums []int, k int) []int { 6 | kv := make(map[int]int) 7 | 8 | for _, v := range nums { 9 | kv[v]++ 10 | } 11 | 12 | var a []int 13 | for k := range kv { 14 | a = append(a, k) 15 | } 16 | 17 | sort.Slice(a, func(i, j int) bool { 18 | // 按照kv对中k出现的次数降序排序 19 | return kv[a[i]] > kv[a[j]] 20 | }) 21 | 22 | return a[:k] 23 | } 24 | -------------------------------------------------------------------------------- /0347.top-k-frequent-elements/top-k-frequent-elements_test.go: -------------------------------------------------------------------------------- 1 | package _347_top_k_frequent_elements 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_topKFrequent(t *testing.T) { 9 | type args struct { 10 | nums []int 11 | k int 12 | } 13 | tests := []struct { 14 | name string 15 | args args 16 | want []int 17 | }{ 18 | { 19 | "test1", 20 | args{ 21 | []int{3, 6, 6, 6, 4, 4}, 22 | 2, 23 | }, 24 | []int{6, 4}, 25 | }, 26 | } 27 | for _, tt := range tests { 28 | t.Run(tt.name, func(t *testing.T) { 29 | if got := topKFrequent(tt.args.nums, tt.args.k); !reflect.DeepEqual(got, tt.want) { 30 | t.Errorf("topKFrequent() = %v, want %v", got, tt.want) 31 | } 32 | }) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /0394.decode-string/decode-string.go: -------------------------------------------------------------------------------- 1 | package _394_decode_string 2 | 3 | import ( 4 | "strconv" 5 | "strings" 6 | ) 7 | 8 | func decodeString(s string) string { 9 | numStack := []int{} 10 | strStack := []string{} 11 | num := 0 12 | result := "" 13 | for _, char := range s { 14 | if char >= '0' && char <= '9' { 15 | n, _ := strconv.Atoi(string(char)) 16 | num = num*10 + n 17 | } else if char == '[' { 18 | strStack = append(strStack, result) 19 | result = "" 20 | 21 | numStack = append(numStack, num) 22 | num = 0 23 | } else if char == ']' { 24 | // 这里的数字和字母都要重新声明,不能影响前面的结果 25 | count := numStack[len(numStack)-1] 26 | numStack = numStack[:len(numStack)-1] 27 | 28 | str := strStack[len(strStack)-1] 29 | strStack = strStack[:len(strStack)-1] 30 | // 最终结果 = pope出来的字段 + 当前的字符 * 重复次数,这个公式要注意一下 31 | result = str + strings.Repeat(result, count) 32 | } else { 33 | result += string(char) 34 | } 35 | } 36 | return result 37 | } 38 | -------------------------------------------------------------------------------- /0394.decode-string/decode-string_test.go: -------------------------------------------------------------------------------- 1 | package _394_decode_string 2 | 3 | import "testing" 4 | 5 | func Test_decodeString(t *testing.T) { 6 | type args struct { 7 | s string 8 | } 9 | tests := []struct { 10 | name string 11 | args args 12 | want string 13 | }{ 14 | { 15 | "test 1", 16 | args{ 17 | "3[a2[c]]", 18 | }, 19 | "accaccacc", 20 | }, 21 | } 22 | for _, tt := range tests { 23 | t.Run(tt.name, func(t *testing.T) { 24 | if got := decodeString(tt.args.s); got != tt.want { 25 | t.Errorf("decodeString() = %v, want %v", got, tt.want) 26 | } 27 | }) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /0404.sum-of-left-leaves/sum-of-left-leaves.go: -------------------------------------------------------------------------------- 1 | package _404_sum_of_left_leaves 2 | 3 | import "github.com/yigenshutiao/Golang-algorithm-template/util" 4 | 5 | type TreeNode = util.TreeNode 6 | 7 | func sumOfLeftLeaves(root *TreeNode) int { 8 | if root == nil { 9 | return 0 10 | } 11 | 12 | res := 0 13 | 14 | var traverse func(node *TreeNode) 15 | traverse = func(node *TreeNode) { 16 | if node == nil { 17 | return 18 | } 19 | 20 | if node.Left != nil && node.Left.Left == nil && node.Left.Right == nil { 21 | res += node.Left.Val 22 | } 23 | 24 | traverse(node.Left) 25 | traverse(node.Right) 26 | } 27 | 28 | traverse(root) 29 | 30 | return res 31 | } 32 | -------------------------------------------------------------------------------- /0406.queue-reconstruction-by-height/queue-reconstruction-by-height.go: -------------------------------------------------------------------------------- 1 | package _406_queue_reconstruction_by_height 2 | 3 | import "sort" 4 | 5 | func reconstructQueue(people [][]int) [][]int { 6 | //先将身高从大到小排序,确定最大个子的相对位置 7 | sort.Slice(people, func(i, j int) bool { 8 | if people[i][0] == people[j][0] { 9 | return people[i][1] < people[j][1] //这个才是当身高相同时,将K按照从小到大排序 10 | } 11 | return people[i][0] > people[j][0] //这个只是确保身高按照由大到小的顺序来排,并不确定K是按照从小到大排序的 12 | }) 13 | //再按照K进行插入排序,优先插入K小的 14 | result := make([][]int, 0) 15 | for _, info := range people { 16 | result = append(result, info) 17 | copy(result[info[1]+1:], result[info[1]:]) //将插入位置之后的元素后移动一位(意思是腾出空间) 18 | result[info[1]] = info //将插入元素位置插入元素 19 | } 20 | return result 21 | } 22 | -------------------------------------------------------------------------------- /0406.queue-reconstruction-by-height/queue-reconstruction-by-height_test.go: -------------------------------------------------------------------------------- 1 | package _406_queue_reconstruction_by_height 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_reconstructQueue(t *testing.T) { 9 | type args struct { 10 | people [][]int 11 | } 12 | tests := []struct { 13 | name string 14 | args args 15 | want [][]int 16 | }{ 17 | { 18 | "test 1", 19 | args{ 20 | [][]int{{7, 0}, {4, 4}, {7, 1}, {5, 0}, {6, 1}, {5, 2}}, 21 | }, 22 | [][]int{{5, 0}, {7, 0}, {5, 2}, {6, 1}, {4, 4}, {7, 1}}, 23 | }, 24 | } 25 | for _, tt := range tests { 26 | t.Run(tt.name, func(t *testing.T) { 27 | if got := reconstructQueue(tt.args.people); !reflect.DeepEqual(got, tt.want) { 28 | t.Errorf("reconstructQueue() = %v, want %v", got, tt.want) 29 | } 30 | }) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /0415.add-strings/add-strings.go: -------------------------------------------------------------------------------- 1 | package _415_add_strings 2 | 3 | import "strconv" 4 | 5 | func addStrings(num1 string, num2 string) string { 6 | add := 0 7 | res := "" 8 | 9 | for i, j := len(num1)-1, len(num2)-1; i >= 0 || j >= 0 || add != 0; i, j = i-1, j-1 { 10 | x, y := 0, 0 11 | if i >= 0 { 12 | x = int(num1[i] - '0') 13 | } 14 | 15 | if j >= 0 { 16 | y = int(num2[j] - '0') 17 | } 18 | 19 | cur := x + y + add 20 | res = strconv.Itoa(cur%10) + res 21 | add = cur / 10 22 | } 23 | 24 | return res 25 | } 26 | -------------------------------------------------------------------------------- /0415.add-strings/add-strings_test.go: -------------------------------------------------------------------------------- 1 | package _415_add_strings 2 | 3 | import "testing" 4 | 5 | func Test_addStrings(t *testing.T) { 6 | type args struct { 7 | num1 string 8 | num2 string 9 | } 10 | tests := []struct { 11 | name string 12 | args args 13 | want string 14 | }{ 15 | { 16 | "test1", 17 | args{ 18 | num1: "123", 19 | num2: "2345", 20 | }, 21 | "2468", 22 | }, 23 | } 24 | for _, tt := range tests { 25 | t.Run(tt.name, func(t *testing.T) { 26 | if got := addStrings(tt.args.num1, tt.args.num2); got != tt.want { 27 | t.Errorf("addStrings() = %v, want %v", got, tt.want) 28 | } 29 | }) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /0416.partition-equal-subset-sum/partition-equal-subset-sum.go: -------------------------------------------------------------------------------- 1 | package _416_partition_equal_subset_sum 2 | 3 | //canPartition 0-1背包问题 4 | func canPartition(nums []int) bool { 5 | sum := 0 6 | for _, num := range nums { 7 | sum += num 8 | } 9 | // 和为单数,肯定不能被均分 10 | if sum%2 == 1 { 11 | return false 12 | } 13 | // 找出目标值 14 | target := sum / 2 15 | dp := make([]int, target+1) 16 | 17 | for i := 0; i < len(nums); i++ { 18 | for j := target; j >= nums[i]; j-- { 19 | // dp[j] : 背包总容量是j,放入物品后,背包的最大容量是dp[j] 20 | dp[j] = max(dp[j], dp[j-nums[i]]+nums[i]) 21 | } 22 | } 23 | 24 | return dp[target] == target 25 | } 26 | 27 | func max(a, b int) int { 28 | if a > b { 29 | return a 30 | } 31 | 32 | return b 33 | } 34 | -------------------------------------------------------------------------------- /0416.partition-equal-subset-sum/partition-equal-subset-sum_test.go: -------------------------------------------------------------------------------- 1 | package _416_partition_equal_subset_sum 2 | 3 | import "testing" 4 | 5 | func Test_canPartition(t *testing.T) { 6 | type args struct { 7 | nums []int 8 | } 9 | tests := []struct { 10 | name string 11 | args args 12 | want bool 13 | }{ 14 | { 15 | "test1", 16 | args{ 17 | []int{1, 5, 11, 5}, 18 | }, 19 | true, 20 | }, 21 | } 22 | for _, tt := range tests { 23 | t.Run(tt.name, func(t *testing.T) { 24 | if got := canPartition(tt.args.nums); got != tt.want { 25 | t.Errorf("canPartition() = %v, want %v", got, tt.want) 26 | } 27 | }) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /0429.n-ary-tree-level-order-traversal/n-ary-tree-level-order-traversal.go: -------------------------------------------------------------------------------- 1 | package _429_n_ary_tree_level_order_traversal 2 | 3 | type Node struct { 4 | Val int 5 | Children []*Node 6 | } 7 | 8 | func levelOrder(root *Node) [][]int { 9 | res := [][]int{} 10 | if root == nil { 11 | return res 12 | } 13 | 14 | queue := []*Node{root} 15 | 16 | for len(queue) > 0 { 17 | l := len(queue) 18 | tmp := []int{} 19 | for i := 0; i < l; i++ { 20 | node := queue[0] 21 | for _, n := range node.Children { 22 | queue = append(queue, n) 23 | } 24 | queue = queue[1:] 25 | tmp = append(tmp, node.Val) 26 | } 27 | res = append(res, tmp) 28 | } 29 | 30 | return res 31 | } 32 | -------------------------------------------------------------------------------- /0437.path-sum-iii/path-sum-iii.go: -------------------------------------------------------------------------------- 1 | package _437_path_sum_iii 2 | 3 | import "github.com/yigenshutiao/Golang-algorithm-template/util" 4 | 5 | type TreeNode = util.TreeNode 6 | 7 | // pathSum 这个题的精髓就是内外都循环... 8 | func pathSum(root *TreeNode, targetSum int) int { 9 | res := 0 10 | // 这里要提前判断,很重要 11 | if root == nil { 12 | return res 13 | } 14 | 15 | var traverse func(node *TreeNode, cur int) 16 | traverse = func(node *TreeNode, cur int) { 17 | if node == nil { 18 | return 19 | } 20 | 21 | if cur == node.Val { 22 | res++ 23 | } 24 | 25 | traverse(node.Left, cur-node.Val) 26 | traverse(node.Right, cur-node.Val) 27 | return 28 | } 29 | 30 | traverse(root, targetSum) 31 | 32 | // 对于每一个节点,都循环一遍... 33 | res += pathSum(root.Left, targetSum) 34 | res += pathSum(root.Right, targetSum) 35 | return res 36 | } 37 | -------------------------------------------------------------------------------- /0438.find-all-anagrams-in-a-string/find-all-anagrams-in-a-string.go: -------------------------------------------------------------------------------- 1 | package _438_find_all_anagrams_in_a_string 2 | 3 | //输入: s = "cbaebabacd", p = "abc" 4 | //输出: [0,6] 5 | // findAnagrams 不要每次都把所有值重新输入,每次滑动一个值即可 6 | func findAnagrams(s string, p string) []int { 7 | if len(s) < len(p) { 8 | return nil 9 | } 10 | // source是p组成的目标值 11 | source := map[byte]int{} 12 | for i := 0; i < len(p); i++ { 13 | source[p[i]]++ 14 | } 15 | 16 | var result []int 17 | 18 | target := map[byte]int{} 19 | 20 | // 这里要注意一下,right应该初始化为len(p) - 1, 这是因为坐标从0开始计算 21 | left, right := 0, len(p)-1 22 | // target是滑动窗口值 23 | for i := left; i <= right; i++ { 24 | target[s[i]]++ 25 | } 26 | 27 | for right < len(s) { 28 | if check(source, target) { 29 | result = append(result, left) 30 | } 31 | // 左边的值滑动走 32 | target[s[left]]-- 33 | left++ 34 | 35 | // 右边的值滑动来 36 | right++ 37 | if right == len(s) { 38 | break 39 | } 40 | target[s[right]]++ 41 | } 42 | 43 | return result 44 | } 45 | 46 | func check(source, target map[byte]int) bool { 47 | for k, v := range target { 48 | if source[k] != v { 49 | return false 50 | } 51 | } 52 | return true 53 | } 54 | -------------------------------------------------------------------------------- /0438.find-all-anagrams-in-a-string/find-all-anagrams-in-a-string_test.go: -------------------------------------------------------------------------------- 1 | package _438_find_all_anagrams_in_a_string 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_findAnagrams(t *testing.T) { 9 | type args struct { 10 | s string 11 | p string 12 | } 13 | tests := []struct { 14 | name string 15 | args args 16 | want []int 17 | }{ 18 | { 19 | "test 1", 20 | args{ 21 | "cbaebabacd", 22 | "abc", 23 | }, 24 | []int{0, 1, 2}, 25 | }, 26 | } 27 | for _, tt := range tests { 28 | t.Run(tt.name, func(t *testing.T) { 29 | if got := findAnagrams(tt.args.s, tt.args.p); !reflect.DeepEqual(got, tt.want) { 30 | t.Errorf("findAnagrams() = %v, want %v", got, tt.want) 31 | } 32 | }) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /0448.find-all-numbers-disappeared-in-an-array/find-all-numbers-disappeared-in-an-array.go: -------------------------------------------------------------------------------- 1 | package _448_find_all_numbers_disappeared_in_an_array 2 | 3 | func findDisappearedNumbers(nums []int) []int { 4 | i := 0 5 | for i < len(nums) { 6 | if nums[i] == i+1 { // 当前元素出现在它该出现的位置,无需交换 7 | i++ 8 | continue 9 | } 10 | idealIdx := nums[i] - 1 // idealIdx:当前元素应该出现的位置 11 | if nums[i] == nums[idealIdx] { // 当前元素=它理应出现的位置上的现有元素,说明重复了 12 | i++ 13 | continue 14 | } 15 | nums[idealIdx], nums[i] = nums[i], nums[idealIdx] // 不重复,进行交换 16 | // 这里不要i++,因为交换过来的数字本身也需要考察,需要交换到合适的位置上 17 | // 如果 i++ 就会跳过它,少考察了它 18 | } 19 | 20 | var res []int 21 | for i := 0; i < len(nums); i++ { 22 | if nums[i] != i+1 { // 值与索引 不对应 23 | res = append(res, i+1) 24 | } 25 | } 26 | return res 27 | } 28 | -------------------------------------------------------------------------------- /0448.find-all-numbers-disappeared-in-an-array/find-all-numbers-disappeared-in-an-array_test.go: -------------------------------------------------------------------------------- 1 | package _448_find_all_numbers_disappeared_in_an_array 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_findDisappearedNumbers(t *testing.T) { 9 | type args struct { 10 | nums []int 11 | } 12 | tests := []struct { 13 | name string 14 | args args 15 | want []int 16 | }{ 17 | { 18 | "test 1", 19 | args{ 20 | []int{4, 3, 2, 7, 8, 2, 3, 1}, 21 | }, 22 | []int{5, 6}, 23 | }, 24 | } 25 | for _, tt := range tests { 26 | t.Run(tt.name, func(t *testing.T) { 27 | if got := findDisappearedNumbers(tt.args.nums); !reflect.DeepEqual(got, tt.want) { 28 | t.Errorf("findDisappearedNumbers() = %v, want %v", got, tt.want) 29 | } 30 | }) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /0450.delete-node-in-a-bst/delete-node-in-a-bst.go: -------------------------------------------------------------------------------- 1 | package _450_delete_node_in_a_bst 2 | 3 | import "github.com/yigenshutiao/Golang-algorithm-template/util" 4 | 5 | type TreeNode = util.TreeNode 6 | 7 | func deleteNode(root *TreeNode, key int) *TreeNode { 8 | if root == nil { 9 | return nil 10 | } 11 | 12 | if root.Val == key { 13 | if root.Left == nil && root.Right == nil { 14 | return nil 15 | } 16 | if root.Left == nil { 17 | return root.Right 18 | } 19 | if root.Right == nil { 20 | return root.Left 21 | } 22 | 23 | tmp := root.Right 24 | 25 | for tmp.Left != nil { 26 | tmp = tmp.Left 27 | } 28 | 29 | tmp.Left = root.Left 30 | root = root.Right 31 | 32 | return root 33 | 34 | } else if root.Val > key { 35 | root.Left = deleteNode(root.Left, key) 36 | } else if root.Val < key { 37 | root.Right = deleteNode(root.Right, key) 38 | } 39 | 40 | return root 41 | } 42 | -------------------------------------------------------------------------------- /0459.repeated-substring-pattern/repeated-substring-pattern.go: -------------------------------------------------------------------------------- 1 | package _459_repeated_substring_pattern 2 | 3 | func repeatedSubstringPattern(s string) bool { 4 | n := len(s) 5 | for i := 1; i <= n/2; i++ { 6 | // i 代表子串,限制n%i==0,是因为n一定是子串的倍数 7 | if n%i == 0 { 8 | match := true 9 | for j := i; j < n; j++ { 10 | if s[j] != s[j-i] { 11 | match = false 12 | break 13 | } 14 | } 15 | if match { 16 | return true 17 | } 18 | } 19 | } 20 | return false 21 | } 22 | -------------------------------------------------------------------------------- /0459.repeated-substring-pattern/repeated-substring-pattern_test.go: -------------------------------------------------------------------------------- 1 | package _459_repeated_substring_pattern 2 | 3 | import "testing" 4 | 5 | func Test_repeatedSubstringPattern(t *testing.T) { 6 | type args struct { 7 | s string 8 | } 9 | tests := []struct { 10 | name string 11 | args args 12 | want bool 13 | }{ 14 | { 15 | "test 1", 16 | args{ 17 | "abcabcabc", 18 | }, 19 | true, 20 | }, 21 | } 22 | for _, tt := range tests { 23 | t.Run(tt.name, func(t *testing.T) { 24 | if got := repeatedSubstringPattern(tt.args.s); got != tt.want { 25 | t.Errorf("repeatedSubstringPattern() = %v, want %v", got, tt.want) 26 | } 27 | }) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /0461.hamming-distance/hamming-distance.go: -------------------------------------------------------------------------------- 1 | package _461_hamming_distance 2 | 3 | func hammingDistance(x int, y int) int { 4 | res := 0 5 | 6 | for x > 0 || y > 0 { 7 | res += (x & 1) ^ (y & 1) 8 | x = x >> 1 9 | y = y >> 1 10 | } 11 | 12 | return res 13 | } 14 | -------------------------------------------------------------------------------- /0494.target-sum/target-sum_test.go: -------------------------------------------------------------------------------- 1 | package _494_target_sum 2 | 3 | import "testing" 4 | 5 | func Test_findTargetSumWays(t *testing.T) { 6 | type args struct { 7 | nums []int 8 | target int 9 | } 10 | tests := []struct { 11 | name string 12 | args args 13 | want int 14 | }{ 15 | { 16 | "test 1", 17 | args{ 18 | []int{100}, 19 | -200, 20 | }, 21 | 0, 22 | }, 23 | } 24 | for _, tt := range tests { 25 | t.Run(tt.name, func(t *testing.T) { 26 | if got := findTargetSumWays(tt.args.nums, tt.args.target); got != tt.want { 27 | t.Errorf("findTargetSumWays() = %v, want %v", got, tt.want) 28 | } 29 | }) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /0501.find-mode-in-binary-search-tree/find-mode-in-binary-search-tree.go: -------------------------------------------------------------------------------- 1 | package _501_find_mode_in_binary_search_tree 2 | 3 | import "github.com/yigenshutiao/Golang-algorithm-template/util" 4 | 5 | type TreeNode = util.TreeNode 6 | 7 | func findMode(root *TreeNode) []int { 8 | max := 1 9 | count := 1 10 | 11 | res := []int{} 12 | var pre *TreeNode 13 | 14 | var traverse func(node *TreeNode) 15 | traverse = func(node *TreeNode) { 16 | if node == nil { 17 | return 18 | } 19 | 20 | traverse(node.Left) 21 | 22 | if pre != nil && pre.Val == node.Val { 23 | count++ 24 | } else { 25 | count = 1 26 | } 27 | 28 | if count >= max { 29 | if count > max { 30 | res = []int{node.Val} 31 | } else { 32 | res = append(res, node.Val) 33 | } 34 | max = count 35 | } 36 | 37 | pre = node 38 | traverse(node.Right) 39 | } 40 | 41 | traverse(root) 42 | 43 | return res 44 | } 45 | -------------------------------------------------------------------------------- /0501.find-mode-in-binary-search-tree/find-mode-in-binary-search-tree_test.go: -------------------------------------------------------------------------------- 1 | package _501_find_mode_in_binary_search_tree 2 | 3 | import ( 4 | "fmt" 5 | "github.com/stretchr/testify/assert" 6 | "github.com/yigenshutiao/Golang-algorithm-template/util" 7 | "testing" 8 | ) 9 | 10 | func Test_findMode(t *testing.T) { 11 | ast := assert.New(t) 12 | 13 | // tcs is testcase slice 14 | tcs := []struct { 15 | pre, in []int 16 | ans []int 17 | }{ 18 | 19 | { 20 | []int{1, 2, 1, 2}, 21 | []int{1, 1, 2, 2}, 22 | []int{1, 2}, 23 | }, 24 | } 25 | 26 | for _, tc := range tcs { 27 | fmt.Printf("~~%v~~\n", tc) 28 | 29 | ast.Equal(tc.ans, findMode(util.PreIn2Tree(tc.pre, tc.in)), "输入:%v", tc) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /0509.fibonacci-number/fibonacci-number.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | // 自底向顶进行计算,用的动态规划思想 4 | func fib(n int) int { 5 | if n <= 1 { 6 | return n 7 | } 8 | 9 | dp := make([]int, n+1) 10 | dp[0], dp[1] = 0, 1 11 | for i := 2; i <= n; i++ { 12 | dp[i] = dp[i-1] + dp[i-2] 13 | } 14 | 15 | return dp[n] 16 | } 17 | -------------------------------------------------------------------------------- /0513.find-bottom-left-tree-value/find-bottom-left-tree-value.go: -------------------------------------------------------------------------------- 1 | package _513_find_bottom_left_tree_value 2 | 3 | import ( 4 | "fmt" 5 | "github.com/yigenshutiao/Golang-algorithm-template/util" 6 | ) 7 | 8 | type TreeNode = util.TreeNode 9 | 10 | func findBottomLeftValue(root *TreeNode) int { 11 | if root == nil { 12 | return -1 13 | } 14 | 15 | queue := []*TreeNode{root} 16 | res := [][]int{} 17 | 18 | for len(queue) > 0 { 19 | t := []int{} 20 | l := len(queue) 21 | for i := 0; i < l; i++ { 22 | node := queue[0] 23 | t = append(t, node.Val) 24 | 25 | if node.Left != nil { 26 | queue = append(queue, node.Left) 27 | } 28 | 29 | if node.Right != nil { 30 | queue = append(queue, node.Right) 31 | } 32 | queue = queue[1:] 33 | } 34 | res = append(res, t) 35 | } 36 | 37 | fmt.Println(res) 38 | 39 | return res[len(res)-1][0] 40 | } 41 | -------------------------------------------------------------------------------- /0516.longest-palindromic-subsequence/longest-palindromic-subsequence.go: -------------------------------------------------------------------------------- 1 | package _516_longest_palindromic_subsequence 2 | 3 | func longestPalindromeSubseq(s string) int { 4 | dp := make([][]int, len(s)) 5 | for i := 0; i < len(s); i++ { 6 | if dp[i] == nil { 7 | dp[i] = make([]int, len(s)) 8 | } 9 | for j := 0; j < len(s); j++ { 10 | if i == j { 11 | dp[i][j] = 1 12 | } 13 | } 14 | } 15 | // 这里需注意坐标 16 | for i := len(s) - 1; i >= 0; i-- { 17 | for j := i + 1; j < len(s); j++ { 18 | if s[i] == s[j] { 19 | dp[i][j] = dp[i+1][j-1] + 2 20 | } else { 21 | dp[i][j] = max(dp[i+1][j], dp[i][j-1]) 22 | } 23 | } 24 | } 25 | return dp[0][len(s)-1] 26 | } 27 | 28 | func max(a, b int) int { 29 | if a > b { 30 | return a 31 | } 32 | return b 33 | } 34 | -------------------------------------------------------------------------------- /0518.coin-change-2/coin-change-2.go: -------------------------------------------------------------------------------- 1 | package _518_coin_change_2 2 | 3 | import "fmt" 4 | 5 | func change(amount int, coins []int) int { 6 | dp := make([]int, amount+1) 7 | 8 | dp[0] = 1 9 | 10 | // 这个题是求组合,要先遍历背包元素 11 | for _, coin := range coins { 12 | for j := coin; j <= amount; j++ { 13 | // 求组合元素的常用递推公式 14 | dp[j] += dp[j-coin] 15 | } 16 | fmt.Println(dp) 17 | } 18 | return dp[amount] 19 | } 20 | -------------------------------------------------------------------------------- /0518.coin-change-2/coin-change-2_test.go: -------------------------------------------------------------------------------- 1 | package _518_coin_change_2 2 | 3 | import "testing" 4 | 5 | func Test_change(t *testing.T) { 6 | type args struct { 7 | amount int 8 | coins []int 9 | } 10 | tests := []struct { 11 | name string 12 | args args 13 | want int 14 | }{ 15 | { 16 | "test 1", 17 | args{ 18 | 5, 19 | []int{1, 2, 5}, 20 | }, 21 | 4, 22 | }, 23 | } 24 | for _, tt := range tests { 25 | t.Run(tt.name, func(t *testing.T) { 26 | if got := change(tt.args.amount, tt.args.coins); got != tt.want { 27 | t.Errorf("change() = %v, want %v", got, tt.want) 28 | } 29 | }) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /0530.minimum-absolute-difference-in-bst/minimum-absolute-difference-in-bst.go: -------------------------------------------------------------------------------- 1 | package _530_minimum_absolute_difference_in_bst 2 | 3 | import "github.com/yigenshutiao/Golang-algorithm-template/util" 4 | 5 | type TreeNode = util.TreeNode 6 | 7 | func getMinimumDifference(root *TreeNode) int { 8 | 9 | s := []int{} 10 | 11 | var traverse func(node *TreeNode) 12 | traverse = func(node *TreeNode) { 13 | if node == nil { 14 | return 15 | } 16 | traverse(node.Left) 17 | s = append(s, node.Val) 18 | traverse(node.Right) 19 | } 20 | 21 | traverse(root) 22 | 23 | res := 99999999999 24 | 25 | for i := len(s) - 1; i > 0; i-- { 26 | t := s[i] - s[i-1] 27 | if t < res { 28 | res = t 29 | } 30 | } 31 | 32 | return res 33 | } 34 | -------------------------------------------------------------------------------- /0538.convert-bst-to-greater-tree/convert-bst-to-greater-tree.go: -------------------------------------------------------------------------------- 1 | package _538_convert_bst_to_greater_tree 2 | 3 | import "github.com/yigenshutiao/Golang-algorithm-template/util" 4 | 5 | type TreeNode = util.TreeNode 6 | 7 | func convertBST(root *TreeNode) *TreeNode { 8 | var num int 9 | var traverse func(node *TreeNode) 10 | 11 | traverse = func(node *TreeNode) { 12 | if node == nil { 13 | return 14 | } 15 | 16 | traverse(node.Right) 17 | node.Val += num 18 | num = node.Val 19 | traverse(node.Left) 20 | } 21 | traverse(root) 22 | 23 | return root 24 | } 25 | -------------------------------------------------------------------------------- /0541.reverse-string-ii/reverse-string-ii.go: -------------------------------------------------------------------------------- 1 | package _541_reverse_string_ii 2 | 3 | func reverseStr(s string, k int) string { 4 | res := []byte(s) 5 | 6 | for i := 0; i < len(res); i += k * 2 { 7 | if len(res[i:]) >= k { 8 | reverse(res[i : i+k]) 9 | } else { 10 | reverse(res[i:]) 11 | } 12 | } 13 | return string(res) 14 | } 15 | 16 | func reverse(s []byte) { 17 | for i := 0; i < len(s)/2; i++ { 18 | s[i], s[len(s)-i-1] = s[len(s)-i-1], s[i] 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /0543.diameter-of-binary-tree/diameter-of-binary-tree.go: -------------------------------------------------------------------------------- 1 | package _543_diameter_of_binary_tree 2 | 3 | import "github.com/yigenshutiao/Golang-algorithm-template/util" 4 | 5 | type TreeNode = util.TreeNode 6 | 7 | // diameterOfBinaryTree 直径就是二叉树最长的边 8 | func diameterOfBinaryTree(root *TreeNode) int { 9 | var res int 10 | var traverse func(node *TreeNode) int 11 | traverse = func(node *TreeNode) int { 12 | if node == nil { 13 | return 0 14 | } 15 | 16 | left := traverse(node.Left) 17 | right := traverse(node.Right) 18 | // 每个点都应该试着找最大值 19 | res = max(res, left+right) 20 | 21 | return max(left, right) + 1 22 | } 23 | 24 | traverse(root) 25 | 26 | return res 27 | } 28 | 29 | func max(a, b int) int { 30 | if a > b { 31 | return a 32 | } 33 | return b 34 | } 35 | -------------------------------------------------------------------------------- /0559.maximum-depth-of-n-ary-tree/maximum-depth-of-n-ary-tree.go: -------------------------------------------------------------------------------- 1 | package _559_maximum_depth_of_n_ary_tree 2 | 3 | type Node struct { 4 | Val int 5 | Children []*Node 6 | } 7 | 8 | func maxDepth(root *Node) int { 9 | if root == nil { 10 | return 0 11 | } 12 | 13 | res := 0 14 | queue := []*Node{root} 15 | 16 | for len(queue) > 0 { 17 | l := len(queue) 18 | 19 | for i := 0; i < l; i++ { 20 | node := queue[0] 21 | 22 | for i := 0; i < len(node.Children); i++ { 23 | queue = append(queue, node.Children[i]) 24 | } 25 | queue = queue[1:] 26 | } 27 | res++ 28 | } 29 | 30 | return res 31 | } 32 | -------------------------------------------------------------------------------- /0560.subarray-sum-equals-k/subarray-sum-equals-k.go: -------------------------------------------------------------------------------- 1 | package _560_subarray_sum_equals_k 2 | 3 | // 前缀和版本 4 | func subarraySum(nums []int, k int) int { 5 | res := 0 6 | // 这个前缀和map比较关键,记录每个前缀和的个数 7 | pre := map[int]int{} 8 | pre[0] = 1 9 | 10 | sum := 0 11 | for i := 0; i < len(nums); i++ { 12 | sum += nums[i] 13 | if _, exist := pre[sum-k]; exist { 14 | res += pre[sum-k] 15 | } 16 | pre[sum]++ 17 | } 18 | 19 | return res 20 | } 21 | 22 | // 暴力版本 23 | func subarraySums(nums []int, k int) int { 24 | res := 0 25 | for i := 0; i < len(nums); i++ { 26 | sum := 0 27 | for j := i; j < len(nums); j++ { 28 | sum += nums[j] 29 | if sum == k { 30 | res++ 31 | } 32 | } 33 | } 34 | return res 35 | } 36 | -------------------------------------------------------------------------------- /0560.subarray-sum-equals-k/subarray-sum-equals-k_test.go: -------------------------------------------------------------------------------- 1 | package _560_subarray_sum_equals_k 2 | 3 | import "testing" 4 | 5 | func Test_subarraySum(t *testing.T) { 6 | type args struct { 7 | nums []int 8 | k int 9 | } 10 | tests := []struct { 11 | name string 12 | args args 13 | want int 14 | }{ 15 | { 16 | " test 1", 17 | args{ 18 | []int{3, 4, 7, 2, -3, 1, 4, 2}, 19 | 7, 20 | }, 21 | 5, 22 | }, 23 | } 24 | for _, tt := range tests { 25 | t.Run(tt.name, func(t *testing.T) { 26 | if got := subarraySum(tt.args.nums, tt.args.k); got != tt.want { 27 | t.Errorf("subarraySum() = %v, want %v", got, tt.want) 28 | } 29 | }) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /0567.permutation-in-string/permutation-in-string.go: -------------------------------------------------------------------------------- 1 | package _567_permutation_in_string 2 | 3 | func checkInclusion(s1 string, s2 string) bool { 4 | source := map[byte]int{} 5 | for i := 0; i < len(s1); i++ { 6 | source[s1[i]]++ 7 | } 8 | 9 | for left, right := 0, len(s1)-1; right < len(s2); { 10 | target := map[byte]int{} 11 | for i := left; i <= right; i++ { 12 | target[s2[i]]++ 13 | } 14 | 15 | if check(source, target) { 16 | return true 17 | } 18 | left++ 19 | right++ 20 | } 21 | 22 | return false 23 | } 24 | 25 | func check(source, target map[byte]int) bool { 26 | for k, v := range target { 27 | if source[k] != v { 28 | return false 29 | } 30 | } 31 | return true 32 | } 33 | -------------------------------------------------------------------------------- /0567.permutation-in-string/permutation-in-string_test.go: -------------------------------------------------------------------------------- 1 | package _567_permutation_in_string 2 | 3 | import "testing" 4 | 5 | func Test_checkInclusion(t *testing.T) { 6 | type args struct { 7 | s1 string 8 | s2 string 9 | } 10 | tests := []struct { 11 | name string 12 | args args 13 | want bool 14 | }{ 15 | { 16 | "test1", 17 | args{ 18 | "ab", 19 | "eidbaooo", 20 | }, 21 | true, 22 | }, 23 | } 24 | for _, tt := range tests { 25 | t.Run(tt.name, func(t *testing.T) { 26 | if got := checkInclusion(tt.args.s1, tt.args.s2); got != tt.want { 27 | t.Errorf("checkInclusion() = %v, want %v", got, tt.want) 28 | } 29 | }) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /0581.shortest-unsorted-continuous-subarray/shortest-unsorted-continuous-subarray.go: -------------------------------------------------------------------------------- 1 | package _581_shortest_unsorted_continuous_subarray 2 | 3 | func findUnsortedSubarray(nums []int) int { 4 | left, right := -1, -1 5 | n := len(nums) 6 | minN, maxN := 999999999, -999999999 7 | for i := 0; i < n; i++ { 8 | // 从左往右走,应为升序(或者平),若遇到降序,记录节点,取最后一个节点作为右边端点 9 | if nums[i] < maxN { 10 | right = i 11 | } else { 12 | maxN = nums[i] 13 | } 14 | // 从右往左走,应为降序(或者平),若遇到升序,记录节点,取最后一个节点作为左边端点 15 | x := n - i - 1 16 | if nums[x] > minN { 17 | left = x 18 | } else { 19 | minN = nums[x] 20 | } 21 | } 22 | 23 | if right == -1 { 24 | return 0 25 | } 26 | 27 | return right - left + 1 28 | } 29 | -------------------------------------------------------------------------------- /0581.shortest-unsorted-continuous-subarray/shortest-unsorted-continuous-subarray_test.go: -------------------------------------------------------------------------------- 1 | package _581_shortest_unsorted_continuous_subarray 2 | 3 | import "testing" 4 | 5 | func Test_findUnsortedSubarray(t *testing.T) { 6 | type args struct { 7 | nums []int 8 | } 9 | tests := []struct { 10 | name string 11 | args args 12 | want int 13 | }{ 14 | { 15 | "test 1", 16 | args{ 17 | []int{2, 6, 4, 8, 10, 9, 15}, 18 | }, 19 | 5, 20 | }, 21 | } 22 | for _, tt := range tests { 23 | t.Run(tt.name, func(t *testing.T) { 24 | if got := findUnsortedSubarray(tt.args.nums); got != tt.want { 25 | t.Errorf("findUnsortedSubarray() = %v, want %v", got, tt.want) 26 | } 27 | }) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /0617.merge-two-binary-trees/merge-two-binary-trees.go: -------------------------------------------------------------------------------- 1 | package _617_merge_two_binary_trees 2 | 3 | import "github.com/yigenshutiao/Golang-algorithm-template/util" 4 | 5 | type TreeNode = util.TreeNode 6 | 7 | func mergeTrees(root1 *TreeNode, root2 *TreeNode) *TreeNode { 8 | if root1 == nil { 9 | return root2 10 | } 11 | 12 | if root2 == nil { 13 | return root1 14 | } 15 | 16 | root1.Val += root2.Val 17 | 18 | root1.Left = mergeTrees(root1.Left, root2.Left) 19 | root1.Right = mergeTrees(root1.Right, root2.Right) 20 | 21 | return root1 22 | } 23 | -------------------------------------------------------------------------------- /0637.average-of-levels-in-binary-tree/average-of-levels-in-binary-tree.go: -------------------------------------------------------------------------------- 1 | package _637_average_of_levels_in_binary_tree 2 | 3 | import "github.com/yigenshutiao/Golang-algorithm-template/util" 4 | 5 | type TreeNode = util.TreeNode 6 | 7 | func averageOfLevels(root *TreeNode) []float64 { 8 | nodes := [][]int{} 9 | if root == nil { 10 | return nil 11 | } 12 | 13 | queue := []*TreeNode{root} 14 | 15 | for len(queue) > 0 { 16 | l := len(queue) 17 | tmp := []int{} 18 | for i := 0; i < l; i++ { 19 | node := queue[0] 20 | if node.Left != nil { 21 | queue = append(queue, node.Left) 22 | } 23 | if node.Right != nil { 24 | queue = append(queue, node.Right) 25 | } 26 | tmp = append(tmp, node.Val) 27 | queue = queue[1:] 28 | } 29 | 30 | nodes = append(nodes, tmp) 31 | } 32 | res := []float64{} 33 | for i := 0; i < len(nodes); i++ { 34 | t := 0 35 | for j := 0; j < len(nodes[i]); j++ { 36 | t += nodes[i][j] 37 | } 38 | res = append(res, float64(t)/float64(len(nodes[i]))) 39 | } 40 | 41 | return res 42 | } 43 | -------------------------------------------------------------------------------- /0647.palindromic-substrings/palindromic-substrings.go: -------------------------------------------------------------------------------- 1 | package _647_palindromic_substrings 2 | 3 | func countSubstrings(s string) int { 4 | dp := make([][]bool, len(s)) 5 | for i := 0; i < len(s); i++ { 6 | dp[i] = make([]bool, len(s)) 7 | } 8 | res := 0 9 | for i := len(s) - 1; i >= 0; i-- { 10 | for j := i; j < len(s); j++ { 11 | if s[i] == s[j] { 12 | if j-i <= 1 { 13 | dp[i][j] = true 14 | res++ 15 | } else { 16 | if dp[i+1][j-1] == true { 17 | dp[i][j] = true 18 | res++ 19 | } 20 | } 21 | } 22 | } 23 | } 24 | return res 25 | } 26 | -------------------------------------------------------------------------------- /0647.palindromic-substrings/palindromic-substrings_test.go: -------------------------------------------------------------------------------- 1 | package _647_palindromic_substrings 2 | 3 | import "testing" 4 | 5 | func Test_countSubstrings(t *testing.T) { 6 | type args struct { 7 | s string 8 | } 9 | tests := []struct { 10 | name string 11 | args args 12 | want int 13 | }{ 14 | { 15 | "test 1", 16 | args{ 17 | s: "aaa", 18 | }, 19 | 6, 20 | }, 21 | } 22 | for _, tt := range tests { 23 | t.Run(tt.name, func(t *testing.T) { 24 | if got := countSubstrings(tt.args.s); got != tt.want { 25 | t.Errorf("countSubstrings() = %v, want %v", got, tt.want) 26 | } 27 | }) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /0652.find-duplicate-subtrees/find-duplicate-subtrees.go: -------------------------------------------------------------------------------- 1 | package _652_find_duplicate_subtrees 2 | 3 | import ( 4 | "github.com/yigenshutiao/Golang-algorithm-template/util" 5 | "strconv" 6 | ) 7 | 8 | type TreeNode = util.TreeNode 9 | 10 | func findDuplicateSubtrees(root *TreeNode) []*TreeNode { 11 | m := map[string]int{} 12 | res := []*TreeNode{} 13 | 14 | dfs(root, m, &res) 15 | 16 | return res 17 | } 18 | 19 | func dfs(root *TreeNode, m map[string]int, res *[]*TreeNode) string { 20 | if root == nil { 21 | return "*" 22 | } 23 | 24 | left := dfs(root.Left, m, res) 25 | right := dfs(root.Right, m, res) 26 | 27 | // 这里注意一下,必须用 strconv.Itoa 28 | key := strconv.Itoa(root.Val) + "_" + left + "_" + right 29 | m[key]++ 30 | 31 | if m[key] == 2 { 32 | *res = append(*res, root) 33 | } 34 | 35 | return key 36 | } 37 | -------------------------------------------------------------------------------- /0652.find-duplicate-subtrees/find-duplicate-subtrees_test.go: -------------------------------------------------------------------------------- 1 | package _652_find_duplicate_subtrees 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_findDuplicateSubtrees(t *testing.T) { 9 | type args struct { 10 | root *TreeNode 11 | } 12 | tests := []struct { 13 | name string 14 | args args 15 | want []*TreeNode 16 | }{ 17 | // TODO: Add test cases. 18 | } 19 | for _, tt := range tests { 20 | t.Run(tt.name, func(t *testing.T) { 21 | if got := findDuplicateSubtrees(tt.args.root); !reflect.DeepEqual(got, tt.want) { 22 | t.Errorf("findDuplicateSubtrees() = %v, want %v", got, tt.want) 23 | } 24 | }) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /0654.maximum-binary-tree/maximum-binary-tree.go: -------------------------------------------------------------------------------- 1 | package _654_maximum_binary_tree 2 | 3 | import "github.com/yigenshutiao/Golang-algorithm-template/util" 4 | 5 | type TreeNode = util.TreeNode 6 | 7 | // [3,2,1,6,0,5] 8 | func constructMaximumBinaryTree(nums []int) *TreeNode { 9 | if len(nums) < 1 { 10 | return nil 11 | } 12 | 13 | idx := getMax(nums) 14 | 15 | root := &TreeNode{ 16 | Val: nums[idx], 17 | Left: constructMaximumBinaryTree(nums[0:idx]), 18 | Right: constructMaximumBinaryTree(nums[idx+1 : len(nums)]), 19 | } 20 | 21 | return root 22 | } 23 | 24 | func getMax(nums []int) int { 25 | if len(nums) <= 1 { 26 | return 0 27 | } 28 | res := 0 29 | 30 | for i := 1; i < len(nums); i++ { 31 | if nums[i] > nums[res] { 32 | res = i 33 | } 34 | } 35 | 36 | return res 37 | } 38 | -------------------------------------------------------------------------------- /0669.trim-a-binary-search-tree/trim-a-binary-search-tree.go: -------------------------------------------------------------------------------- 1 | package _669_trim_a_binary_search_tree 2 | 3 | import "github.com/yigenshutiao/Golang-algorithm-template/util" 4 | 5 | type TreeNode = util.TreeNode 6 | 7 | func trimBST(root *TreeNode, low int, high int) *TreeNode { 8 | if root == nil { 9 | return nil 10 | } 11 | 12 | if root.Val < low { 13 | node := trimBST(root.Right, low, high) 14 | return node 15 | } 16 | 17 | if root.Val > high { 18 | node := trimBST(root.Left, low, high) 19 | return node 20 | } 21 | 22 | root.Left = trimBST(root.Left, low, high) 23 | root.Right = trimBST(root.Right, low, high) 24 | return root 25 | } 26 | -------------------------------------------------------------------------------- /0674.longest-continuous-increasing-subsequence/longest-continuous-increasing-subsequence.go: -------------------------------------------------------------------------------- 1 | package _674_longest_continuous_increasing_subsequence 2 | 3 | func findLengthOfLCIS(nums []int) int { 4 | var res int 5 | var tmp int 6 | for i := 0; i < len(nums); i++ { 7 | tmp = 1 8 | cur := nums[i] 9 | for j := i + 1; j < len(nums); j++ { 10 | if nums[j] > cur { 11 | cur = nums[j] 12 | tmp++ 13 | } else { 14 | break 15 | } 16 | } 17 | if tmp > res { 18 | res = tmp 19 | } 20 | } 21 | 22 | return res 23 | } 24 | -------------------------------------------------------------------------------- /0674.longest-continuous-increasing-subsequence/longest-continuous-increasing-subsequence_test.go: -------------------------------------------------------------------------------- 1 | package _674_longest_continuous_increasing_subsequence 2 | 3 | import "testing" 4 | 5 | func Test_findLengthOfLCIS(t *testing.T) { 6 | type args struct { 7 | nums []int 8 | } 9 | tests := []struct { 10 | name string 11 | args args 12 | want int 13 | }{ 14 | { 15 | "test1", 16 | args{ 17 | []int{1, 3, 5, 7}, 18 | }, 19 | 4, 20 | }, 21 | } 22 | for _, tt := range tests { 23 | t.Run(tt.name, func(t *testing.T) { 24 | if got := findLengthOfLCIS(tt.args.nums); got != tt.want { 25 | t.Errorf("findLengthOfLCIS() = %v, want %v", got, tt.want) 26 | } 27 | }) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /0695.max-area-of-island/max-area-of-island.go: -------------------------------------------------------------------------------- 1 | package _695_max_area_of_island 2 | 3 | func maxAreaOfIsland(grid [][]int) int { 4 | var res int 5 | for i := 0; i < len(grid); i++ { 6 | for j := 0; j < len(grid[0]); j++ { 7 | if grid[i][j] == 1 { 8 | var tmp int 9 | dfs(grid, i, j, &tmp) 10 | if tmp > res { 11 | res = tmp 12 | } 13 | } 14 | } 15 | } 16 | return res 17 | } 18 | 19 | func dfs(grid [][]int, i, j int, tmp *int) { 20 | if i < 0 || j < 0 || i >= len(grid) || j >= len(grid[0]) { 21 | return 22 | } 23 | 24 | if grid[i][j] == 0 { 25 | return 26 | } 27 | *tmp += 1 28 | 29 | grid[i][j] = 0 30 | 31 | dfs(grid, i, j-1, tmp) 32 | dfs(grid, i, j+1, tmp) 33 | dfs(grid, i-1, j, tmp) 34 | dfs(grid, i+1, j, tmp) 35 | } 36 | -------------------------------------------------------------------------------- /0700.search-in-a-binary-search-tree/search-in-a-binary-search-tree.go: -------------------------------------------------------------------------------- 1 | package _700_search_in_a_binary_search_tree 2 | 3 | import "github.com/yigenshutiao/Golang-algorithm-template/util" 4 | 5 | type TreeNode = util.TreeNode 6 | 7 | func searchBST(root *TreeNode, val int) *TreeNode { 8 | if root == nil { 9 | return nil 10 | } 11 | 12 | if root.Val > val { 13 | root = searchBST(root.Left, val) 14 | } else if root.Val < val { 15 | root = searchBST(root.Right, val) 16 | } 17 | 18 | return root 19 | } 20 | -------------------------------------------------------------------------------- /0701.insert-into-a-binary-search-tree/insert-into-a-binary-search-tree.go: -------------------------------------------------------------------------------- 1 | package _701_insert_into_a_binary_search_tree 2 | 3 | import "github.com/yigenshutiao/Golang-algorithm-template/util" 4 | 5 | type TreeNode = util.TreeNode 6 | 7 | func insertIntoBST(root *TreeNode, val int) *TreeNode { 8 | if root == nil { 9 | return &TreeNode{Val: val} 10 | } 11 | 12 | if root.Val > val { 13 | root.Left = insertIntoBST(root.Left, val) 14 | } else if root.Val < val { 15 | root.Right = insertIntoBST(root.Right, val) 16 | } 17 | 18 | return root 19 | } 20 | -------------------------------------------------------------------------------- /0704.binary-search/binary-search.go: -------------------------------------------------------------------------------- 1 | package _704_binary_search 2 | 3 | func search(nums []int, target int) int { 4 | left, right := 0, len(nums)-1 5 | // 这里需要是<=,如果是<, 在只有一个元素的情况下,run不起来 6 | for left <= right { 7 | mid := (left + right) >> 1 8 | if nums[mid] == target { 9 | return mid 10 | } else if nums[mid] < target { 11 | left = mid + 1 12 | } else { 13 | right = mid - 1 14 | } 15 | } 16 | 17 | return -1 18 | } 19 | -------------------------------------------------------------------------------- /0714.best-time-to-buy-and-sell-stock-with-transaction-fee/best-time-to-buy-and-sell-stock-with-transaction-fee.go: -------------------------------------------------------------------------------- 1 | package _714_best_time_to_buy_and_sell_stock_with_transaction_fee 2 | 3 | func maxProfit(prices []int, fee int) int { 4 | dp := make([][]int, len(prices)) 5 | 6 | for i := 0; i < len(prices); i++ { 7 | dp[i] = make([]int, 2) 8 | } 9 | 10 | for i := 0; i < len(prices); i++ { 11 | if i == 0 { 12 | dp[0][0] = 0 13 | dp[0][1] = -prices[i] - fee 14 | continue 15 | } 16 | 17 | dp[i][0] = max(dp[i-1][0], dp[i-1][1]+prices[i]) 18 | dp[i][1] = max(dp[i-1][1], dp[i-1][0]-prices[i]-fee) 19 | 20 | } 21 | return dp[len(prices)-1][0] 22 | } 23 | 24 | func max(a, b int) int { 25 | if a > b { 26 | return a 27 | } 28 | return b 29 | } 30 | -------------------------------------------------------------------------------- /0739.daily-temperatures/daily-temperatures.go: -------------------------------------------------------------------------------- 1 | package _739_daily_temperatures 2 | 3 | func dailyTemperatures(temperatures []int) []int { 4 | 5 | res := make([]int, len(temperatures)) 6 | 7 | // 对于温度表里的每个温度 8 | for i := 0; i < len(temperatures); i++ { 9 | // 找到第一个大于t[i]的元素的索引值 10 | for j := i + 1; j < len(temperatures); j++ { 11 | if temperatures[j] > temperatures[i] { 12 | res[i] = j - i 13 | break 14 | } 15 | } 16 | } 17 | return res 18 | } 19 | 20 | // 递减栈 21 | func dailyTemperature(temperatures []int) []int { 22 | res := make([]int, len(temperatures)) 23 | var stack []int 24 | 25 | for i := 0; i < len(temperatures); i++ { 26 | // 当前元素 27 | cur := temperatures[i] 28 | // 当前元素大于栈顶元素 29 | for len(stack) > 0 && cur > temperatures[stack[len(stack)-1]] { 30 | // 获取栈顶元素的下标 31 | idx := stack[len(stack)-1] 32 | // 将栈顶元素出栈 33 | stack = stack[:len(stack)-1] 34 | // 更新结果表 35 | res[idx] = i - idx 36 | } 37 | // 将新元素入栈 38 | stack = append(stack, i) 39 | } 40 | return res 41 | } 42 | -------------------------------------------------------------------------------- /0739.daily-temperatures/daily-temperatures_test.go: -------------------------------------------------------------------------------- 1 | package _739_daily_temperatures 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_dailyTemperature(t *testing.T) { 9 | type args struct { 10 | temperatures []int 11 | } 12 | tests := []struct { 13 | name string 14 | args args 15 | want []int 16 | }{ 17 | { 18 | "test 1", 19 | args{ 20 | []int{73, 74, 75, 71, 69, 72, 76, 73}, 21 | }, 22 | []int{1, 1, 4, 2, 1, 1, 0, 0}, 23 | }, 24 | } 25 | for _, tt := range tests { 26 | t.Run(tt.name, func(t *testing.T) { 27 | if got := dailyTemperature(tt.args.temperatures); !reflect.DeepEqual(got, tt.want) { 28 | t.Errorf("dailyTemperature() = %v, want %v", got, tt.want) 29 | } 30 | }) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /0743.network-delay-time/network-delay-time_test.go: -------------------------------------------------------------------------------- 1 | package _743_network_delay_time 2 | 3 | import "testing" 4 | 5 | func Test_networkDelayTime(t *testing.T) { 6 | type args struct { 7 | times [][]int 8 | n int 9 | k int 10 | } 11 | tests := []struct { 12 | name string 13 | args args 14 | want int 15 | }{ 16 | { 17 | "test1", 18 | args{ 19 | [][]int{{2, 1, 1}, {2, 3, 1}, {3, 4, 1}}, 20 | 4, 21 | 2, 22 | }, 23 | 2, 24 | }, 25 | } 26 | for _, tt := range tests { 27 | t.Run(tt.name, func(t *testing.T) { 28 | if got := networkDelayTime(tt.args.times, tt.args.n, tt.args.k); got != tt.want { 29 | t.Errorf("networkDelayTime() = %v, want %v", got, tt.want) 30 | } 31 | }) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /0746.min-cost-climbing-stairs/min-cost-climbing-stairs.go: -------------------------------------------------------------------------------- 1 | package _746_min_cost_climbing_stairs 2 | 3 | func minCostClimbingStairs(cost []int) int { 4 | dp := make([]int, len(cost)+1) 5 | dp[0] = cost[0] 6 | dp[1] = cost[1] 7 | 8 | for i := 2; i < len(cost); i++ { 9 | dp[i] = min(dp[i-1], dp[i-2]) + cost[i] 10 | } 11 | 12 | return min(dp[len(cost)-2], dp[len(cost)-1]) 13 | } 14 | 15 | func min(a, b int) int { 16 | if a < b { 17 | return a 18 | } 19 | return b 20 | } 21 | -------------------------------------------------------------------------------- /0876.middle-of-the-linked-list/middle-of-the-linked-list.go: -------------------------------------------------------------------------------- 1 | package _876_middle_of_the_linked_list 2 | 3 | import "github.com/yigenshutiao/Golang-algorithm-template/util" 4 | 5 | type ListNode = util.ListNode 6 | 7 | func middleNode(head *ListNode) *ListNode { 8 | 9 | one, second := head, head 10 | 11 | // second != nil 为了判断快指针走到末尾的情况 12 | // 当second 已经走到末尾的nil, 若再判断second的Next,就会panic 13 | for second != nil && second.Next != nil { 14 | one = one.Next 15 | second = second.Next.Next 16 | } 17 | 18 | return one 19 | } 20 | -------------------------------------------------------------------------------- /0876.middle-of-the-linked-list/middle-of-the-linked-list_test.go: -------------------------------------------------------------------------------- 1 | package _876_middle_of_the_linked_list 2 | 3 | import ( 4 | "fmt" 5 | "github.com/stretchr/testify/assert" 6 | "github.com/yigenshutiao/Golang-algorithm-template/util" 7 | "testing" 8 | ) 9 | 10 | var tcs = []struct { 11 | head []int 12 | ans []int 13 | }{ 14 | 15 | //{ 16 | // []int{1, 2, 3, 4, 5}, 17 | // []int{3, 4, 5}, 18 | //}, 19 | 20 | { 21 | []int{1, 2, 3, 4, 5, 6}, 22 | []int{4, 5, 6}, 23 | }, 24 | 25 | // 可以有多个 testcase 26 | } 27 | 28 | func Test_middleNode(t *testing.T) { 29 | ast := assert.New(t) 30 | 31 | for _, tc := range tcs { 32 | fmt.Printf("~~%v~~\n", tc) 33 | head := util.Ints2List(tc.head) 34 | actual := util.List2Ints(middleNode(head)) 35 | ast.Equal(tc.ans, actual, "输入:%v", tc) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /1038.binary-search-tree-to-greater-sum-tree/binary-search-tree-to-greater-sum-tree.go: -------------------------------------------------------------------------------- 1 | package _038_binary_search_tree_to_greater_sum_tree 2 | 3 | import "github.com/yigenshutiao/Golang-algorithm-template/util" 4 | 5 | type TreeNode = util.TreeNode 6 | 7 | func bstToGst(root *TreeNode) *TreeNode { 8 | sum := 0 9 | var dfs func(*TreeNode) 10 | 11 | dfs = func(node *TreeNode) { 12 | if node != nil { 13 | dfs(node.Right) 14 | sum += node.Val 15 | node.Val = sum 16 | dfs(node.Left) 17 | } 18 | } 19 | dfs(root) 20 | 21 | return root 22 | } 23 | -------------------------------------------------------------------------------- /1049.last-stone-weight-ii/last-stone-weight-ii.go: -------------------------------------------------------------------------------- 1 | package _049_last_stone_weight_ii 2 | 3 | func lastStoneWeightII(stones []int) int { 4 | target := 0 5 | for _, stone := range stones { 6 | target += stone 7 | } 8 | 9 | dp := make([]int, target+1) 10 | 11 | for i := 0; i < len(stones); i++ { 12 | for j := target / 2; j >= stones[i]; j-- { 13 | dp[j] = max(dp[j], dp[j-stones[i]]+stones[i]) 14 | } 15 | } 16 | 17 | return target - (dp[target/2] * 2) 18 | } 19 | 20 | func max(a, b int) int { 21 | if a > b { 22 | return a 23 | } 24 | return b 25 | } 26 | -------------------------------------------------------------------------------- /1254.number-of-closed-islands/number-of-closed-islands.go: -------------------------------------------------------------------------------- 1 | package _254_number_of_closed_islands 2 | 3 | func closedIsland(grid [][]int) int { 4 | if grid == nil { 5 | return 0 6 | } 7 | var res int 8 | 9 | for i := 0; i < len(grid); i++ { 10 | for j := 0; j < len(grid[0]); j++ { 11 | if grid[i][j] == 0 { 12 | if dfs(grid, i, j) { 13 | res += 1 14 | } 15 | } 16 | } 17 | } 18 | 19 | return res 20 | } 21 | 22 | func dfs(grid [][]int, i, j int) bool { 23 | if i < 0 || j < 0 || i >= len(grid) || j >= len(grid[0]) { 24 | return false 25 | } 26 | 27 | if grid[i][j] == 1 { 28 | return true 29 | } 30 | 31 | grid[i][j] = 1 32 | 33 | up := dfs(grid, i, j-1) 34 | down := dfs(grid, i, j+1) 35 | left := dfs(grid, i-1, j) 36 | right := dfs(grid, i+1, j) 37 | 38 | return up && down && left && right 39 | } 40 | -------------------------------------------------------------------------------- /1905.count-sub-islands/count-sub-islands.go: -------------------------------------------------------------------------------- 1 | package _905_count_sub_islands 2 | 3 | func countSubIslands(grid1 [][]int, grid2 [][]int) int { 4 | 5 | for i := 0; i < len(grid1); i++ { 6 | for j := 0; j < len(grid1[0]); j++ { 7 | if grid1[i][j] == 0 && grid2[i][j] == 1 { 8 | dfs(grid2, i, j) 9 | } 10 | } 11 | } 12 | 13 | var res int 14 | 15 | for i := 0; i < len(grid2); i++ { 16 | for j := 0; j < len(grid2[0]); j++ { 17 | if grid2[i][j] == 1 { 18 | res += 1 19 | dfs(grid2, i, j) 20 | } 21 | } 22 | } 23 | 24 | return res 25 | } 26 | 27 | func dfs(grid2 [][]int, i, j int) { 28 | if i < 0 || j < 0 || i >= len(grid2) || j >= len(grid2[0]) { 29 | return 30 | } 31 | 32 | // 如果已经被淹掉了,可以返回 33 | if grid2[i][j] == 0 { 34 | return 35 | } 36 | 37 | // 否则把岛屿淹掉 38 | grid2[i][j] = 0 39 | 40 | dfs(grid2, i, j-1) 41 | dfs(grid2, i, j+1) 42 | dfs(grid2, i-1, j) 43 | dfs(grid2, i+1, j) 44 | } 45 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Xing Gao 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [toc] 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 | - [ ] 链表与邻接表:树与图的存储 28 | - [ ] 栈与队列:单调队列、单调栈 29 | - [ ] kmp 30 | - [ ] Trie 31 | - [ ] 并查集 32 | - [ ] 堆 33 | - [ ] Hash表 34 | - [ ] C++ STL使用技巧 35 | 36 | ### 搜索与图论 37 | 38 | - [x] DFS 39 | - [ ] BFS 40 | - [ ] 树与图的遍历:拓扑排序 41 | - [ ] 最短路 42 | - [ ] 最小生成树 43 | - [ ] 二分图:染色法、匈牙利算法 44 | 45 | ### 数学知识 46 | 47 | - [ ] 欧几里得算法 48 | - [ ] 筛素数 49 | - [ ] 快速幂 50 | - [ ] 组合计数 51 | - [ ] 容斥原理 52 | - [ ] 简单博弈论 53 | 54 | ### 动态规划 55 | 56 | - [ ] 背包问题 57 | - [ ] 线性DP 58 | - [ ] 区间DP 59 | - [ ] 计数类DP 60 | - [ ] 数位统计DP 61 | - [ ] 状态压缩DP 62 | - [ ] 树形DP 63 | 64 | ### 贪心 65 | 66 | 67 | 68 | ### 时空复杂度分析 -------------------------------------------------------------------------------- /bfs/bfs-note.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ### 应用 4 | 5 | bfs广泛用于搜索**最短路**问题。 6 | 7 | 8 | 9 | ### 模板 10 | 11 | -------------------------------------------------------------------------------- /bfs/bfs.md: -------------------------------------------------------------------------------- 1 | ### BFS应用场景 2 | 3 | bfs被广泛应用于寻找最短路径。 4 | 5 | ### 思想 6 | 7 | bfs本质上是在一副图里找到起点和终点之间Eden最短距离。 8 | 9 | -------------------------------------------------------------------------------- /big-num-operation/README.md: -------------------------------------------------------------------------------- 1 | ## 高精度问题 2 | 3 | 高精度问题指的是两个非常大的整数的运算,比如len(a) > 10^3 4 | ,这样大的数在c++里需要开数组计算. 5 | 6 | 高精度思想在处理字符串时可以用到。 -------------------------------------------------------------------------------- /big-num-operation/big_num_add.go: -------------------------------------------------------------------------------- 1 | package big_num_operation 2 | 3 | import "fmt" 4 | 5 | func bigNumAdd(a, b []int) []int { 6 | res := []int{} 7 | t := 0 8 | for i := 0; i < len(a) || i < len(b); i++ { 9 | if i < len(a) { 10 | t += a[i] 11 | } 12 | if i < len(b) { 13 | t += b[i] 14 | } 15 | res = append(res, t%10) 16 | t /= 10 17 | } 18 | if t == 1 { 19 | res = append(res, 1) 20 | } 21 | return res 22 | } 23 | 24 | func callAdd() { 25 | a := "89" 26 | b := "31" 27 | arrA, arrB := []int{}, []int{} 28 | for i := len(a) - 1; i >= 0; i-- { 29 | arrA = append(arrA, int(a[i])-'0') 30 | } 31 | for i := len(b) - 1; i >= 0; i-- { 32 | arrB = append(arrB, int(b[i])-'0') 33 | } 34 | c := bigNumAdd(arrA, arrB) 35 | 36 | for i := len(c) - 1; i >= 0; i-- { 37 | fmt.Print(c[i]) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /big-num-operation/big_num_div.go: -------------------------------------------------------------------------------- 1 | package big_num_operation 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | func div(a []int, b int) []int { 8 | if b == 0 { 9 | return nil 10 | } 11 | res := []int{} 12 | r := 0 13 | for i := len(a) - 1; i >= 0; i-- { 14 | r = r*10 + a[i] 15 | res = append(res, r/b) 16 | r %= b 17 | } 18 | // reverse arr 19 | for i := 0; i < len(res)/2; i++ { 20 | res[i], res[len(res)-1-i] = res[len(res)-1-i], res[i] 21 | } 22 | // 去掉答案中的前导0 23 | for len(res) > 1 && res[len(res)-1] == 0 { 24 | res = res[:len(res)-1] 25 | } 26 | return res 27 | } 28 | 29 | func callDiv() { 30 | 31 | a := "120" 32 | b := 0 33 | 34 | A := []int{} 35 | for i := len(a) - 1; i >= 0; i-- { 36 | A = append(A, int(a[i])-'0') 37 | } 38 | 39 | c := div(A, b) 40 | for i := len(c) - 1; i >= 0; i-- { 41 | fmt.Print(c[i]) 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /big-num-operation/big_num_mult.go: -------------------------------------------------------------------------------- 1 | package big_num_operation 2 | 3 | import "fmt" 4 | 5 | func mult(a []int, b int) []int { 6 | res := []int{} 7 | t := 0 8 | for i := 0; i < len(a) || t > 0; i++ { 9 | if i < len(a) { 10 | t += a[i] * b 11 | } 12 | res = append(res, t%10) 13 | t /= 10 14 | } 15 | return res 16 | } 17 | 18 | func callMult() { 19 | a := "9999" 20 | b := 9 21 | 22 | A := []int{} 23 | for i := len(a) - 1; i >= 0; i-- { 24 | A = append(A, int(a[i])-'0') 25 | } 26 | c := mult(A, b) 27 | for i := len(c) - 1; i >= 0; i-- { 28 | fmt.Print(c[i]) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /binary-operation/lowbit.go: -------------------------------------------------------------------------------- 1 | package binary_operation 2 | 3 | import "fmt" 4 | 5 | func lowbit(x int) int { 6 | return x & -x 7 | } 8 | 9 | func getCount(x int) int { 10 | //给定一个长度为n的数列,请你求出数列中每个数的二进制表示中1的个数 11 | res := 0 12 | for x > 0 { 13 | x -= lowbit(x) 14 | res++ 15 | } 16 | return res 17 | } 18 | 19 | func main() { 20 | fmt.Print(getCount(15)) 21 | } 22 | -------------------------------------------------------------------------------- /binary-sort/search_range.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | // 此问题用到两种二分模板来寻找边界 6 | // 题目,在一个单调递增的序列里找到一个数字的起始、终止坐标,找不到返回[-1,-1] 7 | func searchRange(num []int, target int) []int { 8 | if len(num) == 0 { 9 | return []int{-1, -1} 10 | } 11 | 12 | // 先寻找起点,即左边界 13 | l, r := 0, len(num)-1 14 | for l < r { 15 | mid := (l + r) >> 1 16 | if num[mid] >= target { 17 | r = mid 18 | } else { 19 | l = mid + 1 20 | } 21 | } 22 | if num[l] != target { 23 | return []int{-1, -1} 24 | } 25 | start := l 26 | 27 | // 寻找终点,即右边界 28 | l, r = 0, len(num)-1 29 | for l < r { 30 | // 当 l = r - 1 时,mid 若不加1,则等于l,区间为[l, r], 没有变化, 造成死循环 31 | // 只有 +1,才能保证mid = r,跳出终止条件 32 | mid := (l + r + 1) >> 1 33 | if num[mid] <= target { 34 | l = mid 35 | } else { 36 | r = mid - 1 37 | } 38 | } 39 | end := r 40 | return []int{start, end} 41 | 42 | } 43 | 44 | func main() { 45 | fmt.Println(searchRange([]int{1, 2, 4, 4, 5, 8, 9}, 4)) 46 | } 47 | -------------------------------------------------------------------------------- /binary-sort/sqrt.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | //threeSqrt 给定一个浮点数 n,求它的三次方根 6 | func threeSqrt(x float64) float64 { 7 | l, r := 0.0, x 8 | for (r - l) > 1e-6 { 9 | mid := (l + r) / 2 10 | if (mid * mid * mid) > x { 11 | r = mid 12 | } else { 13 | l = mid 14 | } 15 | } 16 | return r 17 | } 18 | 19 | func main() { 20 | fmt.Println(threeSqrt(1000.00)) 21 | } 22 | -------------------------------------------------------------------------------- /data-structure/README.md: -------------------------------------------------------------------------------- 1 | ## 基本数据结构 2 | 3 | 这里实现的数据结构都是用数组实现的 -------------------------------------------------------------------------------- /data-structure/double_linklist.go: -------------------------------------------------------------------------------- 1 | package dataStructure 2 | 3 | import "fmt" 4 | 5 | var ( 6 | index int 7 | val = make(map[int]int) 8 | l = make(map[int]int) //存左指针 9 | r = make(map[int]int) //存右指针 10 | ) 11 | 12 | func init() { 13 | r[0] = 1 14 | l[1] = 0 15 | index = 2 16 | 17 | } 18 | 19 | // 在节点k的右边插入一个值x 20 | // 若想在k的左边插入节点, 则insert(l[k], x) 21 | func insert(k, x int) { 22 | val[index] = x 23 | l[index] = k 24 | r[index] = r[k] 25 | l[r[k]] = index 26 | r[k] = index 27 | index++ 28 | } 29 | 30 | // 删除节点k 31 | func removeNode(k int) { 32 | r[l[k]] = r[k] 33 | l[r[k]] = l[k] 34 | } 35 | 36 | func traverses() { 37 | for i := r[0]; i != 1; i = r[i] { 38 | fmt.Println(val[i]) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /data-structure/stack.go: -------------------------------------------------------------------------------- 1 | package dataStructure 2 | 3 | import "fmt" 4 | 5 | var ( 6 | tt int 7 | stk = make(map[int]int) 8 | ) 9 | 10 | func pop() { 11 | if tt > 0 { 12 | tt-- 13 | } 14 | } 15 | 16 | func push(x int) { 17 | stk[tt] = x 18 | tt++ 19 | } 20 | 21 | func boolEmpty() bool { 22 | if tt > 0 { 23 | return false 24 | } 25 | return true 26 | } 27 | 28 | func getStack() int { 29 | if boolEmpty() { 30 | return -1 31 | } 32 | return stk[tt] 33 | } 34 | 35 | func traverseStack() { 36 | for i := tt; i >= 0; i-- { 37 | fmt.Println(stk[tt]) 38 | } 39 | } 40 | 41 | func main() { 42 | push(1) 43 | fmt.Println(tt, stk) 44 | } 45 | -------------------------------------------------------------------------------- /dfs/dfs-note.md: -------------------------------------------------------------------------------- 1 | ### 介绍 2 | 3 | DFS(Depth First Search)意思是深度优先搜索,在寻找**所有可能性**类型的题目中经常可以用到。 4 | 5 | 解决回溯问题,关键是这三个点: 6 | 1. 已经做出的选择 7 | 2. 还可以做的选择 8 | 3. 回溯的终止条件 9 | 10 | #### dfs框架 11 | 12 | ```python 13 | result = [] 14 | def dfs(路径, 选择列表): 15 | if 满足结束条件: 16 | result.add(路径) 17 | return 18 | 19 | for 选择 in 选择列表: 20 | 做选择 21 | backtrack(路径, 选择列表) 22 | 撤销选择 23 | ``` 24 | 25 | 26 | ### LeetCode相关题目 27 | 28 | [46.全排列](https://leetcode-cn.com/problems/permutations/) 29 | 30 | [51.N皇后](https://leetcode-cn.com/problems/n-queens/) 31 | 32 | -------------------------------------------------------------------------------- /dfs/n_queens.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func dfs(y int, n int, pic []string, res *[][]string, col, bias, rbias []bool) { 4 | if y == n { 5 | t := make([]string, n) 6 | copy(t, pic) 7 | *res = append(*res, t) 8 | } 9 | 10 | for x := 0; x < n; x++ { 11 | if !col[x] && !bias[x+y] && !rbias[y-x+n] { 12 | col[x], bias[x+y], rbias[y-x+n] = true, true, true 13 | t := make([]byte, n) 14 | for k := range t { 15 | t[k] = '.' 16 | } 17 | t[x] = 'Q' 18 | 19 | pic[y] = string(t) 20 | 21 | dfs(y+1, n, pic, res, col, bias, rbias) 22 | 23 | col[x], bias[x+y], rbias[y-x+n] = false, false, false 24 | 25 | t[x] = '.' 26 | } 27 | } 28 | 29 | } 30 | 31 | func solveNQueens(n int) [][]string { 32 | res := make([][]string, 0) 33 | pic := make([]string, n) 34 | 35 | col := make([]bool, n) 36 | bias := make([]bool, n*2) 37 | rbias := make([]bool, n*2) 38 | 39 | dfs(0, n, pic, &res, col, bias, rbias) 40 | 41 | return res 42 | } 43 | -------------------------------------------------------------------------------- /dfs/permutations.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func permute(nums []int) [][]int { 6 | // 回溯问题,主调用里面准备参数 7 | var res [][]int 8 | used := make([]bool, len(nums)) 9 | tmp := make([]int, len(nums)) 10 | 11 | // dfs里面算调用关系,注意把各种当前状态传进去,本题状态,cur 12 | permuteDfs(0, nums, used, tmp, &res) 13 | 14 | return res 15 | } 16 | 17 | func permuteDfs(cur int, nums []int, used []bool, tmp []int, res *[][]int) { 18 | 19 | if cur == len(nums) { 20 | t := make([]int, len(nums)) 21 | copy(t, tmp) 22 | *res = append(*res, t) 23 | } 24 | 25 | for i := 0; i < len(nums); i++ { 26 | if !used[i] { // 还可以选的元素 27 | tmp[cur] = nums[i] // 选择这个元素 28 | used[i] = true 29 | permuteDfs(cur+1, nums, used, tmp, res) 30 | used[i] = false 31 | } 32 | } 33 | } 34 | 35 | func main() { 36 | fmt.Println(permute([]int{1, 2, 3})) 37 | } 38 | -------------------------------------------------------------------------------- /double-pointer/README.md: -------------------------------------------------------------------------------- 1 | ## 双指针算法 2 | 3 | 核心思想 4 | > 把**O(n^2)**时间复杂度的算法优化到**O(n)**. 5 | 6 | -------------------------------------------------------------------------------- /double-pointer/get_char.go: -------------------------------------------------------------------------------- 1 | package double_pointer 2 | 3 | import "fmt" 4 | 5 | func getChar(str string) { 6 | // 打印出str中的每个子字符串, 并用","分隔, str以字母开头, 子字符串之间只有一个空格 7 | n := len(str) 8 | for i := 0; i < n; i++ { 9 | j := i 10 | for j < n && str[j] != ' ' { 11 | j++ 12 | } 13 | for k := i; k < j; k++ { 14 | fmt.Print(string(str[k])) 15 | } 16 | fmt.Print(",") 17 | i = j 18 | } 19 | 20 | } 21 | 22 | func main() { 23 | getChar("adb adha ahdjka") 24 | } 25 | -------------------------------------------------------------------------------- /double-pointer/max_sub_seq.go: -------------------------------------------------------------------------------- 1 | package double_pointer 2 | 3 | import "fmt" 4 | 5 | func max(i, j int) int { 6 | if i > j { 7 | return i 8 | } else { 9 | return j 10 | } 11 | } 12 | 13 | func maxSubSeq(num []int) int { 14 | //给定一个长度为n的整数序列,返回最长的不包含重复数字的连续子序列的长度 15 | res := 0 16 | count := make(map[int]int, len(num)) 17 | j := 0 18 | for i := 0; i < len(num); i++ { 19 | count[num[i]]++ 20 | for count[num[i]] > 1 { 21 | count[num[j]]-- 22 | j++ 23 | } 24 | res = max(res, i-j+1) 25 | } 26 | return res 27 | } 28 | 29 | func main() { 30 | fmt.Print(maxSubSeq([]int{1, 2, 2, 3, 5})) 31 | } 32 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/yigenshutiao/Golang-algorithm-template 2 | 3 | go 1.17 4 | 5 | require github.com/stretchr/testify v1.7.0 6 | 7 | require ( 8 | github.com/davecgh/go-spew v1.1.0 // indirect 9 | github.com/pmezard/go-difflib v1.0.0 // indirect 10 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect 11 | ) 12 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= 2 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 3 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 4 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 5 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 6 | github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= 7 | github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= 8 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= 9 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 10 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= 11 | gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 12 | -------------------------------------------------------------------------------- /listnode.md: -------------------------------------------------------------------------------- 1 | 刷链表题的一些心得: 2 | 1. 声明类型是链表类型还是链表指针类型时,主要看会不会有head = head.Next的操作 3 | 2. 双指针算法遍历链表时,要用快指针判断是否到达边界 4 | 3. 有必要背一下提供head 和 提供head、tail的反转链表的模板 5 | -------------------------------------------------------------------------------- /max-num-less-n/get_num.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | ) 7 | 8 | func main() { 9 | n := 23121 10 | 11 | nums := []int{2, 4, 9} 12 | num := strconv.Itoa(n) 13 | var res int 14 | 15 | var flag bool 16 | var cur int 17 | 18 | var dfs func(idx int, flag bool, cur int) bool 19 | 20 | dfs = func(idx int, flag bool, cur int) bool { 21 | if idx == len(num) { 22 | res = cur 23 | return true 24 | } 25 | 26 | if flag { 27 | return dfs(idx+1, true, cur*10+nums[len(nums)-1]) 28 | } else { 29 | val := num[idx] 30 | vv, _ := strconv.Atoi(string(val)) 31 | for i := len(nums) - 1; i >= 0; i-- { 32 | if vv == nums[i] { 33 | if dfs(idx+1, false, cur*10+nums[i]) { 34 | return true 35 | } 36 | } else if vv > nums[i] { 37 | if dfs(idx+1, true, cur*10+nums[i]) { 38 | return true 39 | } 40 | } 41 | } 42 | 43 | if idx != 0 { 44 | return false 45 | } 46 | 47 | return dfs(idx+1, true, cur) 48 | } 49 | } 50 | 51 | dfs(0, flag, cur) 52 | 53 | fmt.Println(res) 54 | } 55 | -------------------------------------------------------------------------------- /offer-question/offer03.shu-zu-zhong-zhong-fu-de-shu-zi-lcof/shu-zu-zhong-zhong-fu-de-shu-zi-lcof.go: -------------------------------------------------------------------------------- 1 | package offer03_shu_zu_zhong_zhong_fu_de_shu_zi_lcof 2 | 3 | func findRepeatNumberMap(nums []int) int { 4 | numInfo := make(map[int]bool) 5 | 6 | for _, num := range nums { 7 | if !numInfo[num] { 8 | numInfo[num] = true 9 | } else { 10 | return num 11 | } 12 | } 13 | 14 | return -1 15 | } 16 | 17 | // findRepeatNumber nums[i] 需要为 i,一直交换,直到 nums[i]和i相等为止 18 | func findRepeatNumber(nums []int) int { 19 | 20 | for i := 0; i < len(nums); { 21 | if nums[i] == i { 22 | i++ 23 | continue 24 | } 25 | if nums[nums[i]] == nums[i] { 26 | return nums[i] 27 | } 28 | nums[i], nums[nums[i]] = nums[nums[i]], nums[i] 29 | } 30 | return -1 31 | } 32 | -------------------------------------------------------------------------------- /offer-question/offer03.shu-zu-zhong-zhong-fu-de-shu-zi-lcof/shu-zu-zhong-zhong-fu-de-shu-zi-lcof_test.go: -------------------------------------------------------------------------------- 1 | package offer03_shu_zu_zhong_zhong_fu_de_shu_zi_lcof 2 | 3 | import "testing" 4 | 5 | func Test_findRepeatNumber(t *testing.T) { 6 | type args struct { 7 | nums []int 8 | } 9 | tests := []struct { 10 | name string 11 | args args 12 | want int 13 | }{ 14 | { 15 | "test1", 16 | args{ 17 | nums: []int{3, 4, 2, 1, 1, 0}, 18 | }, 19 | 1, 20 | }, 21 | } 22 | for _, tt := range tests { 23 | t.Run(tt.name, func(t *testing.T) { 24 | if got := findRepeatNumber(tt.args.nums); got != tt.want { 25 | t.Errorf("findRepeatNumber() = %v, want %v", got, tt.want) 26 | } 27 | }) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /offer-question/offer04.er-wei-shu-zu-zhong-de-cha-zhao-lcof/er-wei-shu-zu-zhong-de-cha-zhao-lcof.go: -------------------------------------------------------------------------------- 1 | package offer04_er_wei_shu_zu_zhong_de_cha_zhao_lcof 2 | 3 | func findNumberIn2DArray(matrix [][]int, target int) bool { 4 | if len(matrix) <= 0 { 5 | return false 6 | } 7 | for m, n := 0, len(matrix[0])-1; m < len(matrix) && n >= 0; { 8 | if matrix[m][n] == target { 9 | return true 10 | } else if matrix[m][n] > target { 11 | n-- 12 | } else if matrix[m][n] < target { 13 | m++ 14 | } 15 | } 16 | return false 17 | } 18 | -------------------------------------------------------------------------------- /offer-question/offer05.ti-huan-kong-ge-lcof/ti-huan-kong-ge-lcof.go: -------------------------------------------------------------------------------- 1 | package offer05_ti_huan_kong_ge_lcof 2 | 3 | func replaceSpace(s string) string { 4 | res := []byte(s) 5 | 6 | cnt := 0 7 | for i := 0; i < len(res); i++ { 8 | if res[i] == ' ' { 9 | cnt++ 10 | } 11 | } 12 | 13 | tmp := make([]byte, cnt*2) 14 | res = append(res, tmp...) 15 | 16 | i := len(res) - 1 17 | j := len(s) - 1 18 | 19 | for j >= 0 { 20 | if res[j] != ' ' { 21 | res[i] = res[j] 22 | i-- 23 | j-- 24 | } else { 25 | res[i] = '0' 26 | res[i-1] = '2' 27 | res[i-2] = '%' 28 | j-- 29 | i -= 3 30 | } 31 | } 32 | 33 | return string(res) 34 | } 35 | -------------------------------------------------------------------------------- /offer-question/offer06.cong-wei-dao-tou-da-yin-lian-biao-lcof/cong-wei-dao-tou-da-yin-lian-biao-lcof.go: -------------------------------------------------------------------------------- 1 | package offer06_cong_wei_dao_tou_da_yin_lian_biao_lcof 2 | 3 | type ListNode struct { 4 | Val int 5 | Next *ListNode 6 | } 7 | 8 | func reversePrint(head *ListNode) []int { 9 | var pre *ListNode 10 | 11 | for head != nil { 12 | next := head.Next 13 | head.Next = pre 14 | pre = head 15 | head = next 16 | } 17 | 18 | res := []int{} 19 | 20 | cur := pre 21 | for cur != nil { 22 | res = append(res, cur.Val) 23 | cur = cur.Next 24 | } 25 | 26 | return res 27 | } 28 | -------------------------------------------------------------------------------- /offer-question/offer07.zhong-jian-er-cha-shu-lcof/zhong-jian-er-cha-shu-lcof.go: -------------------------------------------------------------------------------- 1 | package offer07_zhong_jian_er_cha_shu_lcof 2 | 3 | type TreeNode struct { 4 | Val int 5 | Left *TreeNode 6 | Right *TreeNode 7 | } 8 | 9 | func buildTree(preorder []int, inorder []int) *TreeNode { 10 | if len(preorder) < 1 || len(inorder) < 1 { 11 | return nil 12 | } 13 | 14 | idx := getIndex(inorder, preorder[0]) 15 | return &TreeNode{ 16 | Val: preorder[0], 17 | Left: buildTree(preorder[1:idx+1], inorder[:idx]), 18 | Right: buildTree(preorder[idx+1:], inorder[idx+1:]), 19 | } 20 | } 21 | 22 | func getIndex(order []int, target int) int { 23 | for i := 0; i < len(order); i++ { 24 | if order[i] == target { 25 | return i 26 | } 27 | } 28 | 29 | return -1 30 | } 31 | -------------------------------------------------------------------------------- /offer-question/offer09.yong-liang-ge-zhan-shi-xian-dui-lie-lcof/yong-liang-ge-zhan-shi-xian-dui-lie-lcof.go: -------------------------------------------------------------------------------- 1 | package offer09_yong_liang_ge_zhan_shi_xian_dui_lie_lcof 2 | 3 | type CQueue struct { 4 | inStack, outStack []int 5 | } 6 | 7 | func Constructor() CQueue { 8 | return CQueue{} 9 | } 10 | 11 | func (this *CQueue) AppendTail(value int) { 12 | this.inStack = append(this.inStack, value) 13 | } 14 | 15 | func (this *CQueue) DeleteHead() int { 16 | if len(this.outStack) == 0 { 17 | if len(this.inStack) == 0 { 18 | return -1 19 | } 20 | this.in2out() 21 | } 22 | value := this.outStack[len(this.outStack)-1] 23 | this.outStack = this.outStack[:len(this.outStack)-1] 24 | return value 25 | } 26 | 27 | func (this *CQueue) in2out() { 28 | for len(this.inStack) > 0 { 29 | this.outStack = append(this.outStack, this.inStack[len(this.inStack)-1]) 30 | this.inStack = this.inStack[:len(this.inStack)-1] 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /offer-question/offer10.qing-wa-tiao-tai-jie-wen-ti-lcof/qing-wa-tiao-tai-jie-wen-ti-lcof.go: -------------------------------------------------------------------------------- 1 | package offer10_qing_wa_tiao_tai_jie_wen_ti_lcof 2 | 3 | func numWays(n int) int { 4 | if n == 0 { 5 | return 1 6 | } 7 | 8 | if n == 1 { 9 | return 1 10 | } 11 | 12 | dp := make([]int, n+1) 13 | dp[0], dp[1] = 1, 1 14 | for i := 2; i <= n; i++ { 15 | dp[i] = (dp[i-1] + dp[i-2]) % 1000000007 16 | } 17 | 18 | return dp[n] 19 | } 20 | -------------------------------------------------------------------------------- /offer-question/offer12.ju-zhen-zhong-de-lu-jing-lcof/ju-zhen-zhong-de-lu-jing-lcof.go: -------------------------------------------------------------------------------- 1 | package offer12_ju_zhen_zhong_de_lu_jing_lcof 2 | 3 | func exist(board [][]byte, word string) bool { 4 | m, n := len(board), len(board[0]) 5 | 6 | isUsed := make([][]bool, len(board)) 7 | for i := 0; i < m; i++ { 8 | isUsed[i] = make([]bool, len(board[0])) 9 | } 10 | 11 | var dfs func(i, j int, idx int) bool 12 | 13 | dfs = func(i, j int, idx int) bool { 14 | if idx == len(word) { 15 | return true 16 | } 17 | 18 | if i < 0 || j < 0 || i >= m || j >= n { 19 | return false 20 | } 21 | 22 | if isUsed[i][j] == true || board[i][j] != word[idx] { 23 | return false 24 | } 25 | 26 | isUsed[i][j] = true 27 | next := dfs(i-1, j, idx+1) || dfs(i+1, j, idx+1) || dfs(i, j-1, idx+1) || dfs(i, j+1, idx+1) 28 | if !next { 29 | isUsed[i][j] = false 30 | return false 31 | } else { 32 | return true 33 | } 34 | } 35 | 36 | for i := 0; i < m; i++ { 37 | for j := 0; j < n; j++ { 38 | if board[i][j] == word[0] && dfs(i, j, 0) { 39 | return true 40 | } 41 | } 42 | } 43 | 44 | return false 45 | } 46 | -------------------------------------------------------------------------------- /offer-question/offer14.jian-sheng-zi-ii-lcof/jian-sheng-zi-ii-lcof.go: -------------------------------------------------------------------------------- 1 | package offer14_jian_sheng_zi_ii_lcof 2 | 3 | func cuttingRope(n int) int { 4 | if n <= 3 { 5 | // 因为题目要求必须要剪>1段 6 | return n - 1 7 | } 8 | var b = n % 3 9 | var p = 1000000007 10 | var rem = 1 11 | // n = 3a+b, 对 x ^ (a-1) 循环求余 12 | for a := 1; a <= n/3-1; a++ { 13 | rem = (rem * 3) % p 14 | } 15 | if b == 0 { 16 | // 直接 补上最后一个3 即可 17 | return rem * 3 % p 18 | } 19 | if b == 1 { 20 | // 最后一个3+1 替换成 2 * 2 21 | return rem * 4 % p 22 | } 23 | // if b== 2, 3 * 2 24 | return rem * 6 % p 25 | } 26 | -------------------------------------------------------------------------------- /offer-question/offer14.jian-sheng-zi-lcof/jian-sheng-zi-lcof.go: -------------------------------------------------------------------------------- 1 | package offer14_jian_sheng_zi_lcof 2 | 3 | import "math" 4 | 5 | func cuttingRope(n int) int { 6 | if n <= 3 { 7 | return n - 1 8 | } 9 | 10 | x := n % 3 11 | a := n / 3 12 | if x == 0 { 13 | return int(math.Pow(3, float64(a))) 14 | } else if x == 1 { 15 | return int(4 * math.Pow(3, float64(a-1))) 16 | } else if x == 2 { 17 | return int(2 * math.Pow(3, float64(a))) 18 | } 19 | return -1 20 | } 21 | -------------------------------------------------------------------------------- /offer-question/offer14.jian-sheng-zi-lcof/jian-sheng-zi-lcof_test.go: -------------------------------------------------------------------------------- 1 | package offer14_jian_sheng_zi_lcof 2 | 3 | import "testing" 4 | 5 | func Test_cuttingRope(t *testing.T) { 6 | type args struct { 7 | n int 8 | } 9 | tests := []struct { 10 | name string 11 | args args 12 | want int 13 | }{ 14 | { 15 | "test1", 16 | args{n: 10}, 17 | 36, 18 | }, 19 | } 20 | for _, tt := range tests { 21 | t.Run(tt.name, func(t *testing.T) { 22 | if got := cuttingRope(tt.args.n); got != tt.want { 23 | t.Errorf("cuttingRope() = %v, want %v", got, tt.want) 24 | } 25 | }) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /offer-question/offer15.er-jin-zhi-zhong-1de-ge-shu-lcof/er-jin-zhi-zhong-1de-ge-shu-lcof.go: -------------------------------------------------------------------------------- 1 | package offer15_er_jin_zhi_zhong_1de_ge_shu_lcof 2 | 3 | func hammingWeight(num uint32) int { 4 | res := 0 5 | 6 | for num != 0 { 7 | tmp := num & 1 8 | res += int(tmp) 9 | num = num >> 1 10 | } 11 | 12 | return res 13 | } 14 | -------------------------------------------------------------------------------- /offer-question/offer21.diao-zheng-shu-zu-shun-xu-shi-qi-shu-wei-yu-ou-shu-qian-mian-lcof/diao-zheng-shu-zu-shun-xu-shi-qi-shu-wei-yu-ou-shu-qian-mian-lcof.go: -------------------------------------------------------------------------------- 1 | package offer21_diao_zheng_shu_zu_shun_xu_shi_qi_shu_wei_yu_ou_shu_qian_mian_lcof 2 | 3 | func exchange(nums []int) []int { 4 | for i := len(nums) - 1; i > 0; i-- { 5 | for j := 0; j < i; j++ { 6 | if nums[j]%2 == 0 && nums[j+1]%2 != 0 { 7 | nums[j], nums[j+1] = nums[j+1], nums[j] 8 | } 9 | } 10 | } 11 | return nums 12 | } 13 | -------------------------------------------------------------------------------- /offer-question/offer21.diao-zheng-shu-zu-shun-xu-shi-qi-shu-wei-yu-ou-shu-qian-mian-lcof/diao-zheng-shu-zu-shun-xu-shi-qi-shu-wei-yu-ou-shu-qian-mian-lcof_test.go: -------------------------------------------------------------------------------- 1 | package offer21_diao_zheng_shu_zu_shun_xu_shi_qi_shu_wei_yu_ou_shu_qian_mian_lcof 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_exchange(t *testing.T) { 9 | type args struct { 10 | nums []int 11 | } 12 | tests := []struct { 13 | name string 14 | args args 15 | want []int 16 | }{ 17 | { 18 | "test 1", 19 | args{ 20 | []int{1, 2, 3, 4, 5}, 21 | }, 22 | []int{1, 3, 5, 2, 4}, 23 | }, 24 | } 25 | for _, tt := range tests { 26 | t.Run(tt.name, func(t *testing.T) { 27 | if got := exchange(tt.args.nums); !reflect.DeepEqual(got, tt.want) { 28 | t.Errorf("exchange() = %v, want %v", got, tt.want) 29 | } 30 | }) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /offer-question/offer29.shun-shi-zhen-da-yin-ju-zhen-lcof/shun-shi-zhen-da-yin-ju-zhen-lcof.go: -------------------------------------------------------------------------------- 1 | package offer29_shun_shi_zhen_da_yin_ju_zhen_lcof 2 | 3 | func spiralOrder(matrix [][]int) []int { 4 | if len(matrix) == 0 { 5 | return nil 6 | } 7 | res := []int{} 8 | top, bottom, left, right := 0, len(matrix)-1, 0, len(matrix[0])-1 //初始边界 9 | 10 | // 循环条件,下大于等于上,右大于等于左 11 | for bottom >= top && right >= left { 12 | // top行的从左到右遍历 13 | for i := left; i <= right; i++ { 14 | res = append(res, matrix[top][i]) 15 | } 16 | 17 | // top行遍历完了,top往下移动 18 | top++ 19 | 20 | // right列的从上到下遍历 21 | for i := top; i <= bottom; i++ { 22 | res = append(res, matrix[i][right]) 23 | } 24 | 25 | // right列遍历完了,right向左移动 26 | right-- 27 | 28 | // 这里一定要做一个判断,因为如果只剩下一个元素就会出错 29 | if left > right || top > bottom { 30 | break 31 | } 32 | 33 | // bottom行的从右往左遍历 34 | for i := right; i >= left; i-- { 35 | res = append(res, matrix[bottom][i]) 36 | } 37 | 38 | //bottom往上移动 39 | bottom-- 40 | 41 | for i := bottom; i >= top; i-- { //left列的从下到上遍历 42 | res = append(res, matrix[i][left]) 43 | } 44 | //left向右移动 45 | left++ 46 | } 47 | return res 48 | } 49 | -------------------------------------------------------------------------------- /offer-question/offer29.shun-shi-zhen-da-yin-ju-zhen-lcof/shun-shi-zhen-da-yin-ju-zhen-lcof_test.go: -------------------------------------------------------------------------------- 1 | package offer29_shun_shi_zhen_da_yin_ju_zhen_lcof 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_spiralOrder(t *testing.T) { 9 | type args struct { 10 | matrix [][]int 11 | } 12 | tests := []struct { 13 | name string 14 | args args 15 | want []int 16 | }{ 17 | { 18 | "test1", 19 | args{[][]int{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}}, 20 | []int{1, 2, 3, 6, 9, 8, 7, 4, 5}, 21 | }, 22 | } 23 | for _, tt := range tests { 24 | t.Run(tt.name, func(t *testing.T) { 25 | if got := spiralOrder(tt.args.matrix); !reflect.DeepEqual(got, tt.want) { 26 | t.Errorf("spiralOrder() = %v, want %v", got, tt.want) 27 | } 28 | }) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /offer-question/offer58.zuo-xuan-zhuan-zi-fu-chuan-lcof/zuo-xuan-zhuan-zi-fu-chuan-lcof.go: -------------------------------------------------------------------------------- 1 | package offer58_zuo_xuan_zhuan_zi_fu_chuan_lcof 2 | 3 | func reverseLeftWords(s string, n int) string { 4 | // 先把前n个元素提取出来 5 | tmp := []byte{} 6 | b := []byte(s) 7 | for i := 0; i < n; i++ { 8 | tmp = append(tmp, b[i]) 9 | } 10 | 11 | j := 0 12 | for i := n; i < len(b); i++ { 13 | b[j] = b[i] 14 | j++ 15 | } 16 | 17 | x := 0 18 | for i := len(b) - n; i < len(b); i++ { 19 | b[i] = tmp[x] 20 | x++ 21 | } 22 | return string(b) 23 | } 24 | 25 | func reverseLeftWords2(s string, n int) string { 26 | 27 | b := []byte(s) 28 | 29 | reverse(b[0:n]) 30 | reverse(b[n:]) 31 | reverse(b) 32 | 33 | return string(b) 34 | } 35 | 36 | func reverse(a []byte) { 37 | for i := 0; i < len(a)/2; i++ { 38 | a[i], a[len(a)-i-1] = a[len(a)-i-1], a[i] 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /queue/queue.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | func enQueue() { 4 | 5 | } 6 | 7 | func deQueue() { 8 | 9 | } 10 | 11 | func empty() { 12 | 13 | } 14 | 15 | func query() { 16 | 17 | } 18 | 19 | func main() { 20 | 21 | } 22 | -------------------------------------------------------------------------------- /sectionMerge.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "sort" 6 | ) 7 | 8 | // Interval Definition for an interval. 9 | type Interval struct { 10 | Start int 11 | End int 12 | } 13 | 14 | func merge(its []Interval) []Interval { 15 | // LeetCode 56题 https://leetcode-cn.com/problems/merge-intervals/ 16 | if len(its) <= 1 { 17 | return its 18 | } 19 | 20 | sort.Slice(its, func(i int, j int) bool { 21 | return its[i].Start < its[j].Start 22 | }) 23 | 24 | res := make([]Interval, 0, len(its)) 25 | 26 | temp := its[0] 27 | for i := 1; i < len(its); i++ { 28 | if its[i].Start <= temp.End { 29 | temp.End = max(temp.End, its[i].End) 30 | } else { 31 | res = append(res, temp) 32 | temp = its[i] 33 | } 34 | } 35 | res = append(res, temp) 36 | 37 | return res 38 | } 39 | 40 | func max(a, b int) int { 41 | if a > b { 42 | return a 43 | } 44 | return b 45 | } 46 | 47 | func main() { 48 | res := merge([]Interval{ 49 | Interval{8, 10}, 50 | Interval{1, 3}, 51 | Interval{2, 6}, 52 | Interval{15, 18}, 53 | }) 54 | fmt.Println(res) 55 | } 56 | -------------------------------------------------------------------------------- /sort/bubble_sort.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func BubbleSort(nums []int) []int { 6 | if len(nums) < 1 { 7 | return nil 8 | } 9 | 10 | for i := 0; i < len(nums); i++ { 11 | var flag bool 12 | for j := 0; j < len(nums)-i-1; j++ { 13 | if nums[j] > nums[j+1] { 14 | flag = true 15 | nums[j], nums[j+1] = nums[j+1], nums[j] 16 | } 17 | } 18 | 19 | // 已经有序了,提前退出排序 20 | if flag == false { 21 | break 22 | } 23 | } 24 | 25 | return nums 26 | } 27 | 28 | func bubble(nums []int) []int { 29 | if len(nums) < 1 { 30 | return nums 31 | } 32 | 33 | for i := 0; i < len(nums); i++ { 34 | for j := 0; j < len(nums)-i-1; j++ { 35 | if nums[j] > nums[j+1] { 36 | nums[j], nums[j+1] = nums[j+1], nums[j] 37 | } 38 | } 39 | } 40 | 41 | return nums 42 | } 43 | 44 | func main123() { 45 | fmt.Println(BubbleSort([]int{9, 12, 1, 5, 2, 5, 67})) 46 | } 47 | -------------------------------------------------------------------------------- /sort/insert_sort.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func InsertSort(nums []int) []int { 6 | if len(nums) < 1 { 7 | return nil 8 | } 9 | 10 | for i := 1; i < len(nums); i++ { 11 | val := nums[i] 12 | 13 | j := i - 1 14 | for ; j >= 0; j-- { 15 | if nums[j] > val { 16 | nums[j+1] = nums[j] 17 | } else { 18 | break 19 | } 20 | } 21 | nums[j+1] = val 22 | } 23 | 24 | return nums 25 | } 26 | 27 | func insert(nums []int) []int { 28 | 29 | if len(nums) < 1 { 30 | return nums 31 | } 32 | 33 | for i := 1; i < len(nums); i++ { 34 | // 35 | val := nums[i] 36 | 37 | j := i - 1 38 | for ; j >= 0; j-- { 39 | if nums[j] > val { 40 | nums[j+1] = nums[j] 41 | } else { 42 | break 43 | } 44 | } 45 | 46 | nums[j+1] = val 47 | } 48 | 49 | return nums 50 | } 51 | 52 | func main1234() { 53 | fmt.Println(InsertSort([]int{4, 5, 6, 1, 3, 2})) 54 | } 55 | -------------------------------------------------------------------------------- /sort/quick_sort_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "testing" 4 | 5 | func Test_quickSort(t *testing.T) { 6 | type args struct { 7 | a []int 8 | } 9 | tests := []struct { 10 | name string 11 | args args 12 | }{ 13 | { 14 | "test 1", 15 | args{ 16 | []int{2, 0, 1}, 17 | }, 18 | }, 19 | } 20 | for _, tt := range tests { 21 | t.Run(tt.name, func(t *testing.T) { 22 | }) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /sum/prefixSum.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "fmt" 4 | 5 | func prefixSum(a []int, l, r int) int { 6 | var sum []int 7 | sum = append(sum, 0) // 注意不能写成 sum[0]= 0 8 | for i := 1; i < len(a); i++ { 9 | sum = append(sum, sum[i-1]+a[i]) 10 | } 11 | return sum[r] - sum[l-1] 12 | } 13 | 14 | func main() { 15 | a := []int{0, 2, 1, 3, 6, 4} // 下标从1开始, 0位置不参与运算 16 | fmt.Print(prefixSum(a, 2, 4)) 17 | } 18 | -------------------------------------------------------------------------------- /tree.md: -------------------------------------------------------------------------------- 1 | 二叉树题注意点 2 | 3 | 1. 一般需要把问题focus在一层树节点上,然后利用递归解决问题 --------------------------------------------------------------------------------