├── Pattern15 - 01 Knapsack ├── go.sum ├── go.mod ├── Challenge1-Count_of_Subset_Sum │ ├── solution_test.go │ └── solution.go ├── Equal_Subset_Sum_Partition │ ├── solution_test.go │ └── solution.go ├── Subset_Sum │ ├── solution_test.go │ └── solution.go ├── Minimum_Subset_Sum_Difference │ └── solution_test.go ├── Challenge2-Target_Sum │ ├── solution_test.go │ └── solution.go └── 01_Knapsack_Advanced │ └── solution_test.go ├── Miscellaneous ├── go.mod ├── brute-force_test.go ├── max-heap_test.go ├── min-heap_test.go ├── quick-sort_test.go ├── median-of-medians_test.go ├── randomize-quick-sort_test.go ├── min-heap.go ├── quick-sort.go ├── brute-force.go ├── max-heap.go └── randomize-quick-sort.go ├── Pattern02 - Two Pointers ├── go.mod ├── Pair_with_Target_Sum │ ├── solution_hashmap.go │ ├── solution_test.go │ ├── solution_hashmap_test.go │ └── solution.go ├── Remove_Duplicates │ ├── solution_test.go │ ├── similar_problem_test.go │ ├── similar_problem.go │ └── solution.go ├── Triplets_with_Smaller_Sum │ ├── solution_test.go │ └── solution.go ├── Squaring_a_Sorted_Array │ ├── solution_test.go │ └── solution.go ├── Dutch_National_Flag_Problem │ ├── solution_test.go │ └── solution.go ├── Triplet_Sum_Close_to_Target │ ├── solution_test.go │ └── solution.go ├── Challenge3-Minimum_Window_Sort │ └── solution_test.go ├── Triplet_Sum_to_Zero │ └── solution_test.go ├── Subarrays_with_Product_Less_than_a_Target │ └── solution_test.go ├── Challenge2-Comparing_Strings_containing_Backspaces │ └── solution_test.go └── Challenge1-Quadruple_Sum_to_Target │ └── solution_test.go ├── Pattern05 - Cyclic Sort ├── go.mod ├── Find_the_Missing_Number │ ├── solution_test.go │ └── solution.go ├── Cyclic_Sort │ ├── solution_test.go │ └── solution.go ├── Find_all_Duplicate_Number │ ├── solution_test.go │ └── solution.go ├── Find_the_Duplicate_Number │ └── solution_test.go ├── Find_all_Missing_Number │ ├── solution_test.go │ └── solution.go ├── Challenge2-Find_the_Smallest_Missing_Positive_Number │ ├── solution_test.go │ └── solution.go ├── Challenge1-Find_the_Corrupt_Pair │ ├── solution_test.go │ └── solution.go └── Challenge3-Find_the_First_K_Missing_Positive_Numbers │ ├── solution_test.go │ └── solution.go ├── Pattern07 - Tree BFS ├── go.mod ├── Zigzag_Traversal │ ├── reverse_compare_test.go │ ├── reverse_compare.go │ ├── solution_test.go │ └── solution.go ├── Reverse_Level_Order_Traversal │ ├── append_compare.go │ ├── append_compare_test.go │ └── solution_test.go ├── Connect_Level_Order_Siblings │ ├── solution_test.go │ └── solution.go ├── Minimum_Depth_of_a_Binary_Tree │ ├── solution_test.go │ └── solution.go ├── Level_Averages_in_a_Binary_Tree │ ├── solution_test.go │ └── solution.go ├── Challenge2-Right_View_of_a_Binary_Tree │ ├── solution_test.go │ └── solution.go ├── Binary_Tree_Level_Order_Traversal │ ├── solution_test.go │ └── solution.go ├── Level_Order_Successor │ ├── solution_test.go │ └── solution.go └── Challenge1-Connect_All_Level_Order_Siblings │ ├── solution_test.go │ └── solution.go ├── Pattern08 - Tree DFS ├── go.mod ├── Sum_of_Path_Numbers │ ├── solution_test.go │ └── solution.go ├── Binary_Tree_Path_Sum │ ├── solution.go │ └── solution_test.go ├── Count_Paths_for_a_Sum │ ├── solution_test.go │ └── solution.go ├── Path_With_Given_Sequence │ ├── solution_test.go │ └── solution.go ├── All_Paths_for_a_Sum │ ├── solution_test.go │ └── solution.go ├── Challenge1-Tree_Diameter │ ├── solution_test.go │ └── solution.go └── Challenge2-Path_with_Maximum_Sum │ ├── solution_test.go │ └── solution.go ├── Pattern09 - Two Heaps ├── go.mod ├── Find_the_Median_of_a_Number_Stream │ └── solution_test.go ├── Challenge1-Next_Interval │ └── solution_test.go ├── Maximize_Capital │ └── solution_test.go └── Sliding_Window_Median │ └── solution_test.go ├── Pattern10 - Subsets ├── go.mod ├── Subsets │ ├── solution_test.go │ └── solution.go ├── Permutations │ └── solution_test.go ├── Challenge3-Count_of_Structurally_Unique_Binary_Search_Trees │ └── solution_test.go ├── Subsets_with_Duplicates │ ├── solution_test.go │ └── solution.go ├── Challenge1-Evaluate_Expression │ ├── solution_test.go │ └── solution.go ├── String_Permutations_by_changing_case │ └── solution_test.go ├── Unique_Generalized_Abbreviations │ └── solution_test.go └── Balanced_Parentheses │ ├── solution_test.go │ └── solution.go ├── Pattern12 - Bitwise XOR ├── go.mod ├── Single_Number │ ├── solution.go │ └── solution_test.go ├── introduction │ ├── solution_test.go │ └── solution.go ├── Complement_of_Base_10_Number │ ├── solution_test.go │ └── solution.go ├── Two_Single_Numbers │ ├── solution_test.go │ └── solution.go └── Challenge1 │ ├── solution_test.go │ └── solution.go ├── Pattern14 - K-way merge ├── go.mod ├── Kth_Smallest_Number_in_a_Sorted_Matrix │ ├── solution_test.go │ ├── binary_search_solution_test.go │ └── binary_search_solution.go ├── Smallest_Number_Range │ └── solution_test.go ├── Challenge1-K_Pairs_with_Largest_Sums │ └── solution_test.go ├── Kth_Smallest_Number_in_M_Sorted_Lists │ └── solution_test.go └── Merge_K_Sorted_Lists │ └── solution_test.go ├── Pattern01 - Sliding Window ├── go.mod ├── introduction │ ├── brute-force.go │ ├── sliding-window.go │ ├── brute-fore_test.go │ └── sliding-window_test.go ├── No-repeat_Substring │ └── solution_test.go ├── Longest_Substring_with_K_Distinct_Characters │ ├── solution_test.go │ └── solution.go ├── Fruits_into_Baskets │ └── solution_test.go ├── Longest_Substring_with_Same_Letters_after_Replacement │ ├── solution_test.go │ └── solution.go ├── Maximum_Sum_Subarray_of_Size_K │ ├── solution_test.go │ └── solution.go ├── Longest_Subarray_with_Ones_after_Replacement │ ├── solution_test.go │ └── solution.go ├── Challenge2-String_Anagrams │ └── solution_test.go ├── Challenge3-Smallest_Window_containing_Substring │ └── solution_test.go ├── Challenge1-Permutation_in_a_String │ └── solution_test.go ├── Smallest_Subarray_with_a_given_sum │ ├── solution_test.go │ └── solution.go └── Challenge4-Words_Concatenation │ └── solution_test.go ├── Pattern04 - Merge Intervals ├── go.mod ├── Challenge2-Maximum_CPU_Load │ └── solution_test.go ├── Merge_Intervals │ └── solution_test.go ├── Challenge1-Minimum_Meeting_Room │ └── solution_test.go ├── Conflicting_Appointments │ ├── solution_test.go │ └── solution.go ├── Challenge3-Employee_Free_Time │ └── solution_test.go ├── Intervals_Intersection │ ├── solution_test.go │ └── solution.go └── Insert_Interval │ └── solution_test.go ├── Pattern13 - Top K Elements ├── go.mod ├── Kth_Largest_Number_in_a_Stream │ └── solution_test.go ├── Rearrange_String │ └── solution_test.go ├── Challenge3 │ └── solution_test.go ├── Challenge2 │ └── solution_test.go ├── Connect_Ropes │ └── solution_test.go ├── Challenge1 │ └── solution_test.go ├── Frequency_Sort │ └── solution_test.go ├── Sum_of_Elements │ ├── solution_test.go │ └── solution.go ├── Kth_Smallest_Number │ └── solution_test.go ├── K_Closest_Points_to_the_Origin │ └── solution_test.go ├── Top_K_Frequent_Numbers │ ├── solution_test.go │ └── solution.go ├── Maximum_Distinct_Elements │ └── solution_test.go └── Top_K_Numbers │ ├── solution_test.go │ └── solution.go ├── Pattern16 - Topological Sort ├── go.mod ├── All_Tasks_Scheduling_Orders │ └── solution_test.go ├── Alien_Dictionary │ └── solution_test.go ├── Tasks_Scheduling │ └── solution_test.go ├── Tasks_Scheduling_Order │ └── solution_test.go ├── Topological_Sort │ └── solution_test.go ├── Challenge2 │ └── solution_test.go └── Challenge1 │ └── solution_test.go ├── Pattern03 - Fast and Slow pointers ├── go.mod ├── LinkedList_Cycle │ ├── solution.go │ └── similar_problem.go ├── Challenge3-Cycle_in_a_Circular_Array │ └── solution_test.go ├── Middle_of_the_LinkedList │ └── solution.go ├── Happy_Number │ ├── solution_test.go │ └── solution.go ├── Challenge1-Palindrome_LinkedList │ └── solution_test.go └── Start_of_LinkedList_Cycle │ └── solution.go ├── Pattern11 - Modified Binary Search ├── go.mod ├── go.sum ├── Number_Range │ ├── solution_test.go │ └── solution.go ├── Ceiling_of_a_Number │ ├── solution_test.go │ └── solution.go ├── Bitonic_Array_Maximum │ ├── solution_test.go │ └── solution.go ├── Next_Letter │ └── solution_test.go ├── Challenge1-Search_Bitonic_Array │ └── solution_test.go ├── Order-agnostic_Binary_Search │ ├── solution_test.go │ └── solution.go ├── Minimum_Difference_Element │ ├── solution_test.go │ └── solution.go ├── Search_in_a_Sorted_Infinite_Array │ └── solution_test.go ├── Challenge2-Search_in_a_Rotated_Array │ └── solution_test.go └── Challenge3-Rotation_Count │ └── solution_test.go ├── Pattern06 - Reversal of a LinkedList ├── go.mod ├── Reverse_a_LinkedList │ ├── solution.go │ └── solution_test.go ├── Challenge2-Rotate_a_LinkedList │ ├── solution.go │ └── solution_test.go ├── Reverse_a_Sublist │ ├── solution_test.go │ └── solution.go ├── Reverse_every_K-elements_Sublist │ ├── solution_test.go │ └── solution.go └── Challenge1-Reverse_alternating_Kelements_Sublist │ └── solution.go ├── .gitignore ├── README.md ├── .github └── workflows │ └── go.yml └── LICENSE /Pattern15 - 01 Knapsack/go.sum: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /Miscellaneous/go.mod: -------------------------------------------------------------------------------- 1 | module miscellaneous 2 | 3 | go 1.16 4 | -------------------------------------------------------------------------------- /Pattern02 - Two Pointers/go.mod: -------------------------------------------------------------------------------- 1 | module pattern2 2 | 3 | go 1.16 4 | -------------------------------------------------------------------------------- /Pattern05 - Cyclic Sort/go.mod: -------------------------------------------------------------------------------- 1 | module pattern5 2 | 3 | go 1.15 4 | -------------------------------------------------------------------------------- /Pattern07 - Tree BFS/go.mod: -------------------------------------------------------------------------------- 1 | module pattern7 2 | 3 | go 1.15 4 | -------------------------------------------------------------------------------- /Pattern08 - Tree DFS/go.mod: -------------------------------------------------------------------------------- 1 | module pattern8 2 | 3 | go 1.15 4 | -------------------------------------------------------------------------------- /Pattern09 - Two Heaps/go.mod: -------------------------------------------------------------------------------- 1 | module pattern9 2 | 3 | go 1.15 4 | -------------------------------------------------------------------------------- /Pattern10 - Subsets/go.mod: -------------------------------------------------------------------------------- 1 | module pattern10 2 | 3 | go 1.15 4 | -------------------------------------------------------------------------------- /Pattern12 - Bitwise XOR/go.mod: -------------------------------------------------------------------------------- 1 | module pattern12 2 | 3 | go 1.16 4 | -------------------------------------------------------------------------------- /Pattern14 - K-way merge/go.mod: -------------------------------------------------------------------------------- 1 | module pattern14 2 | 3 | go 1.16 4 | -------------------------------------------------------------------------------- /Pattern15 - 01 Knapsack/go.mod: -------------------------------------------------------------------------------- 1 | module pattern15 2 | 3 | go 1.16 4 | -------------------------------------------------------------------------------- /Pattern01 - Sliding Window/go.mod: -------------------------------------------------------------------------------- 1 | module pattern1 2 | 3 | go 1.13 4 | -------------------------------------------------------------------------------- /Pattern04 - Merge Intervals/go.mod: -------------------------------------------------------------------------------- 1 | module pattern4 2 | 3 | go 1.15 4 | -------------------------------------------------------------------------------- /Pattern13 - Top K Elements/go.mod: -------------------------------------------------------------------------------- 1 | module pattern13 2 | 3 | go 1.16 4 | -------------------------------------------------------------------------------- /Pattern16 - Topological Sort/go.mod: -------------------------------------------------------------------------------- 1 | module pattern16 2 | 3 | go 1.16 4 | -------------------------------------------------------------------------------- /Pattern03 - Fast and Slow pointers/go.mod: -------------------------------------------------------------------------------- 1 | module pattern3 2 | 3 | go 1.15 4 | -------------------------------------------------------------------------------- /Pattern11 - Modified Binary Search/go.mod: -------------------------------------------------------------------------------- 1 | module pattern11 2 | 3 | go 1.15 -------------------------------------------------------------------------------- /Pattern06 - Reversal of a LinkedList/go.mod: -------------------------------------------------------------------------------- 1 | module pattern6 2 | 3 | go 1.15 4 | -------------------------------------------------------------------------------- /Pattern11 - Modified Binary Search/go.sum: -------------------------------------------------------------------------------- 1 | golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= 2 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 3 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 4 | -------------------------------------------------------------------------------- /Pattern07 - Tree BFS/Zigzag_Traversal/reverse_compare_test.go: -------------------------------------------------------------------------------- 1 | package Zigzag_Traversal 2 | 3 | import "testing" 4 | 5 | func BenchmarkMethod1(b *testing.B) { 6 | for i := 0; i < b.N; i++ { 7 | method1() 8 | } 9 | } 10 | 11 | func BenchmarkMethod2(b *testing.B) { 12 | for i := 0; i < b.N; i++ { 13 | method2() 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | 8 | # Test binary, built with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool, specifically when used with LiteIDE 12 | *.out 13 | 14 | # Dependency directories (remove the comment below to include it) 15 | # vendor/ 16 | 17 | # idea file 18 | *.iml 19 | .idea -------------------------------------------------------------------------------- /Pattern02 - Two Pointers/Pair_with_Target_Sum/solution_hashmap.go: -------------------------------------------------------------------------------- 1 | package Pair_with_Target_Sum 2 | 3 | func searchByHashMap(arr []int, targetSum int) (int, int) { 4 | var record = make(map[int]int) // int -> index 5 | for i := 0; i < len(arr); i++ { 6 | if _, ok := record[targetSum-arr[i]]; ok { 7 | return record[targetSum-arr[i]], i 8 | } else { 9 | record[arr[i]] = i 10 | } 11 | } 12 | 13 | return -1, -1 14 | } 15 | -------------------------------------------------------------------------------- /Pattern01 - Sliding Window/introduction/brute-force.go: -------------------------------------------------------------------------------- 1 | package introduction 2 | 3 | func findAveragesOfSubArraysByBruteForce(K int, arr []int) []float64 { 4 | results := make([]float64, len(arr)-K+1) 5 | for i := 0; i <= len(arr)-K; i++ { 6 | // 计算下一组K个元素的和 7 | sum := 0 8 | for j := i; j < i+K; j++ { 9 | sum += arr[j] 10 | } 11 | // 计算平均 12 | results[i] = float64(sum) / float64(K) 13 | } 14 | return results 15 | } 16 | -------------------------------------------------------------------------------- /Pattern06 - Reversal of a LinkedList/Reverse_a_LinkedList/solution.go: -------------------------------------------------------------------------------- 1 | package Reverse_a_LinkedList 2 | 3 | type ListNode struct { 4 | Value int 5 | Next *ListNode 6 | } 7 | 8 | func reverse(head *ListNode) *ListNode { 9 | var ( 10 | current = head 11 | previous *ListNode 12 | next *ListNode 13 | ) 14 | 15 | for current != nil { 16 | next = current.Next 17 | current.Next = previous 18 | previous = current 19 | current = next 20 | } 21 | 22 | return previous 23 | } 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Golang-Grokking-the-Coding-Interview-Patterns-for-Coding-Questions 2 | ![build](https://img.shields.io/github/workflow/status/zhiwei-Feng/Golang-Grokking-the-Coding-Interview-Patterns-for-Coding-Questions/Go) 3 | [![codecov](https://codecov.io/gh/zhiwei-Feng/Golang-Grokking-the-Coding-Interview/branch/main/graph/badge.svg?token=RVVYRDXLBE)](https://codecov.io/gh/zhiwei-Feng/Golang-Grokking-the-Coding-Interview) 4 | 5 | Golang version for "Grokking the Coding Interview: Patterns for Coding Questions" 6 | -------------------------------------------------------------------------------- /Pattern12 - Bitwise XOR/Single_Number/solution.go: -------------------------------------------------------------------------------- 1 | package singlenumber 2 | 3 | /* 4 | In a non-empty array of integers, every number appears twice except for one, find that single number. 5 | 6 | Input: 1, 4, 2, 1, 3, 2, 3 7 | Output: 4 8 | 9 | Input: 7, 9, 7 10 | Output: 9 11 | 12 | ref: https://leetcode-cn.com/problems/single-number-ii/ 13 | ref: https://leetcode-cn.com/problems/single-number/ 14 | */ 15 | 16 | func singleNumber(nums []int) int { 17 | x := 0 18 | for _, v := range nums { 19 | x ^= v 20 | } 21 | 22 | return x 23 | } 24 | -------------------------------------------------------------------------------- /Pattern13 - Top K Elements/Kth_Largest_Number_in_a_Stream/solution_test.go: -------------------------------------------------------------------------------- 1 | package kthlargestnumberinastream 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestSolution(t *testing.T) { 8 | model := Constructor(4, []int{3, 1, 5, 12, 2, 11}) 9 | a1 := model.Add(6) 10 | if a1!=5{ 11 | t.Errorf("Constructor() = %v, want %v", a1, 5) 12 | } 13 | a2 := model.Add(13) 14 | if a2!=6{ 15 | t.Errorf("Constructor() = %v, want %v", a2, 6) 16 | } 17 | a3 := model.Add(4) 18 | if a3!=6{ 19 | t.Errorf("Constructor() = %v, want %v", a3, 6) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Pattern02 - Two Pointers/Remove_Duplicates/solution_test.go: -------------------------------------------------------------------------------- 1 | package Remove_Duplicates 2 | 3 | import "testing" 4 | 5 | func Test_remove(t *testing.T) { 6 | type args struct { 7 | arr []int 8 | } 9 | tests := []struct { 10 | name string 11 | args args 12 | want int 13 | }{ 14 | {"case1", args{[]int{2, 3, 3, 3, 6, 9, 9}}, 4}, 15 | {"case2", args{[]int{2, 2, 2, 11}}, 2}, 16 | } 17 | for _, tt := range tests { 18 | t.Run(tt.name, func(t *testing.T) { 19 | if got := remove(tt.args.arr); got != tt.want { 20 | t.Errorf("remove() = %v, want %v", got, tt.want) 21 | } 22 | }) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Pattern10 - Subsets/Subsets/solution_test.go: -------------------------------------------------------------------------------- 1 | package 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 | {"case1", args{[]int{1, 3}}, [][]int{{}, {1}, {3}, {1, 3}}}, 18 | } 19 | for _, tt := range tests { 20 | t.Run(tt.name, func(t *testing.T) { 21 | if got := subsets(tt.args.nums); !reflect.DeepEqual(got, tt.want) { 22 | t.Errorf("subsets() = %v, want %v", got, tt.want) 23 | } 24 | }) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Pattern12 - Bitwise XOR/Single_Number/solution_test.go: -------------------------------------------------------------------------------- 1 | package singlenumber 2 | 3 | import "testing" 4 | 5 | func Test_singleNumber(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 | {"case1", args{[]int{2, 2, 1}}, 1}, 15 | {"case2", args{[]int{4, 1, 2, 1, 2}}, 4}, 16 | } 17 | for _, tt := range tests { 18 | t.Run(tt.name, func(t *testing.T) { 19 | if got := singleNumber(tt.args.nums); got != tt.want { 20 | t.Errorf("singleNumber() = %v, want %v", got, tt.want) 21 | } 22 | }) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Pattern12 - Bitwise XOR/introduction/solution_test.go: -------------------------------------------------------------------------------- 1 | package introduction 2 | 3 | import "testing" 4 | 5 | func Test_missingNumber(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 | {"case1", args{[]int{1, 5, 2, 6, 4}}, 3}, 15 | {"case2", args{[]int{4, 1, 2}}, 3}, 16 | } 17 | for _, tt := range tests { 18 | t.Run(tt.name, func(t *testing.T) { 19 | if got := missingNumber(tt.args.nums); got != tt.want { 20 | t.Errorf("missingNumber() = %v, want %v", got, tt.want) 21 | } 22 | }) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Pattern13 - Top K Elements/Rearrange_String/solution_test.go: -------------------------------------------------------------------------------- 1 | package rearrangestring 2 | 3 | import "testing" 4 | 5 | func Test_reorganizeString(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 | {"case1", args{"aappp"}, "papap"}, 15 | {"case2", args{"aapa"}, ""}, 16 | } 17 | for _, tt := range tests { 18 | t.Run(tt.name, func(t *testing.T) { 19 | if got := reorganizeString(tt.args.s); got != tt.want { 20 | t.Errorf("reorganizeString() = %v, want %v", got, tt.want) 21 | } 22 | }) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Pattern13 - Top K Elements/Challenge3/solution_test.go: -------------------------------------------------------------------------------- 1 | package challenge3 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestConstructor(t *testing.T) { 8 | 9 | fs := Constructor() 10 | fs.Push(5) 11 | fs.Push(7) 12 | fs.Push(5) 13 | fs.Push(7) 14 | fs.Push(4) 15 | fs.Push(5) 16 | x := fs.Pop() 17 | if x != 5 { 18 | t.Errorf("pop %v, want %v", x, 5) 19 | } 20 | x = fs.Pop() 21 | if x != 7 { 22 | t.Errorf("pop %v, want %v", x, 7) 23 | } 24 | x = fs.Pop() 25 | if x != 5 { 26 | t.Errorf("pop %v, want %v", x, 5) 27 | } 28 | x = fs.Pop() 29 | if x != 4 { 30 | t.Errorf("pop %v, want %v", x, 4) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Pattern01 - Sliding Window/No-repeat_Substring/solution_test.go: -------------------------------------------------------------------------------- 1 | package No_repeat_Substring 2 | 3 | import "testing" 4 | 5 | func Test_findLength(t *testing.T) { 6 | type args struct { 7 | str string 8 | } 9 | tests := []struct { 10 | name string 11 | args args 12 | want int 13 | }{ 14 | {"case1", args{"aabccbb"}, 3}, 15 | {"case2", args{"abbbb"}, 2}, 16 | {"case3", args{"abccde"}, 3}, 17 | } 18 | for _, tt := range tests { 19 | t.Run(tt.name, func(t *testing.T) { 20 | if got := findLength(tt.args.str); got != tt.want { 21 | t.Errorf("findLength() = %v, want %v", got, tt.want) 22 | } 23 | }) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Pattern01 - Sliding Window/introduction/sliding-window.go: -------------------------------------------------------------------------------- 1 | package introduction 2 | 3 | func findAveragesOfSubArraysBySlidingWindow(K int, arr []int) []float64 { 4 | results := make([]float64, len(arr)-K+1) 5 | windowSum := 0 6 | windowStart := 0 7 | for windowEnd := 0; windowEnd < len(arr); windowEnd++ { 8 | // 把下个元素加上 9 | windowSum += arr[windowEnd] 10 | // 滑动窗口,特别地,如果没有达到K个则不滑动 11 | if windowEnd >= K-1 { 12 | // 当前windowSum计算了整个窗口的和 13 | results[windowStart] = float64(windowSum) / float64(K) 14 | // 当前窗口计算完后,移动窗口需要先减去原来窗口头部的元素 15 | windowSum -= arr[windowStart] 16 | windowStart++ 17 | } 18 | } 19 | return results 20 | } 21 | -------------------------------------------------------------------------------- /Pattern03 - Fast and Slow pointers/LinkedList_Cycle/solution.go: -------------------------------------------------------------------------------- 1 | package LinkedList_Cycle 2 | 3 | /* 4 | Given the head of a Singly LinkedList, write a function to determine if the LinkedList has a cycle in it or not. 5 | */ 6 | 7 | type ListNode struct { 8 | Value int 9 | Next *ListNode 10 | } 11 | 12 | func hasCycle(head *ListNode) bool { 13 | // 同时出发 14 | var ( 15 | slow = head 16 | fast = head 17 | ) 18 | 19 | for fast != nil && fast.Next != nil { 20 | // fast走两步,slow走一步,这样两者的距离每次缩小1个位置(有环) 21 | fast = fast.Next.Next 22 | slow = slow.Next 23 | if slow == fast { 24 | return true 25 | } 26 | } 27 | 28 | return false 29 | } 30 | -------------------------------------------------------------------------------- /Pattern10 - Subsets/Permutations/solution_test.go: -------------------------------------------------------------------------------- 1 | package Permutations 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 | {"case1", args{[]int{1, 2, 3}}, [][]int{{1, 2, 3}, {1, 3, 2}, {2, 1, 3}, {2, 3, 1}, {3, 1, 2}, {3, 2, 1}}}, 18 | } 19 | for _, tt := range tests { 20 | t.Run(tt.name, func(t *testing.T) { 21 | if got := permute(tt.args.nums); !reflect.DeepEqual(got, tt.want) { 22 | t.Errorf("permute() = %v, want %v", got, tt.want) 23 | } 24 | }) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Pattern07 - Tree BFS/Zigzag_Traversal/reverse_compare.go: -------------------------------------------------------------------------------- 1 | package Zigzag_Traversal 2 | 3 | func method1() { 4 | var input = make([]int, 0, 100) 5 | for i := 0; i < len(input); i++ { 6 | input = append(input, i) 7 | } 8 | // method1 9 | for i := 0; i < len(input)/2; i++ { 10 | j := len(input) - 1 - i 11 | input[i], input[j] = input[j], input[i] 12 | } 13 | } 14 | 15 | func method2() { 16 | var input = make([]int, 0, 100) 17 | for i := 0; i < len(input); i++ { 18 | input = append(input, i) 19 | } 20 | // method2 21 | tmp := input 22 | input = make([]int, 0, 100) 23 | for i := len(tmp) - 1; i >= 0; i-- { 24 | input = append(input, tmp[i]) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Pattern12 - Bitwise XOR/Complement_of_Base_10_Number/solution_test.go: -------------------------------------------------------------------------------- 1 | package complementofbase10number 2 | 3 | import "testing" 4 | 5 | func Test_bitwiseComplement(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 | {"case1", args{5}, 2}, 15 | {"case2", args{7}, 0}, 16 | {"case3", args{10}, 5}, 17 | {"case4", args{0}, 1}, 18 | } 19 | for _, tt := range tests { 20 | t.Run(tt.name, func(t *testing.T) { 21 | if got := bitwiseComplement(tt.args.n); got != tt.want { 22 | t.Errorf("bitwiseComplement() = %v, want %v", got, tt.want) 23 | } 24 | }) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Pattern13 - Top K Elements/Challenge2/solution_test.go: -------------------------------------------------------------------------------- 1 | package challenge2 2 | 3 | import "testing" 4 | 5 | func Test_leastInterval(t *testing.T) { 6 | type args struct { 7 | tasks []byte 8 | k int 9 | } 10 | tests := []struct { 11 | name string 12 | args args 13 | want int 14 | }{ 15 | {"case1", args{[]byte{'a', 'a', 'a', 'b', 'c', 'c'}, 2}, 7}, 16 | {"case2", args{[]byte{'a', 'b', 'a'}, 3}, 5}, 17 | } 18 | for _, tt := range tests { 19 | t.Run(tt.name, func(t *testing.T) { 20 | if got := leastInterval(tt.args.tasks, tt.args.k); got != tt.want { 21 | t.Errorf("leastInterval() = %v, want %v", got, tt.want) 22 | } 23 | }) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Pattern11 - Modified Binary Search/Number_Range/solution_test.go: -------------------------------------------------------------------------------- 1 | package numberrange 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 | {"case1", args{[]int{5, 7, 7, 8, 8, 10}, 8}, []int{3, 4}}, 19 | } 20 | for _, tt := range tests { 21 | t.Run(tt.name, func(t *testing.T) { 22 | if got := searchRange(tt.args.nums, tt.args.target); !reflect.DeepEqual(got, tt.want) { 23 | t.Errorf("searchRange() = %v, want %v", got, tt.want) 24 | } 25 | }) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Pattern13 - Top K Elements/Connect_Ropes/solution_test.go: -------------------------------------------------------------------------------- 1 | package connectropes 2 | 3 | import "testing" 4 | 5 | func Test_connectSticks(t *testing.T) { 6 | type args struct { 7 | sticks []int 8 | } 9 | tests := []struct { 10 | name string 11 | args args 12 | want int 13 | }{ 14 | {"case1", args{[]int{1, 3, 11, 5}}, 33}, 15 | {"case2", args{[]int{3, 4, 5, 6}}, 36}, 16 | {"case3", args{[]int{1, 3, 11, 5, 2}}, 42}, 17 | } 18 | for _, tt := range tests { 19 | t.Run(tt.name, func(t *testing.T) { 20 | if got := connectSticks(tt.args.sticks); got != tt.want { 21 | t.Errorf("connectSticks() = %v, want %v", got, tt.want) 22 | } 23 | }) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Pattern02 - Two Pointers/Remove_Duplicates/similar_problem_test.go: -------------------------------------------------------------------------------- 1 | package Remove_Duplicates 2 | 3 | import "testing" 4 | 5 | func Test_removeKey(t *testing.T) { 6 | type args struct { 7 | arr []int 8 | targetKey int 9 | } 10 | tests := []struct { 11 | name string 12 | args args 13 | want int 14 | }{ 15 | {"case1", args{[]int{3, 2, 3, 6, 3, 10, 9, 3}, 3}, 4}, 16 | {"case2", args{[]int{2, 11, 2, 2, 1}, 2}, 2}, 17 | } 18 | for _, tt := range tests { 19 | t.Run(tt.name, func(t *testing.T) { 20 | if got := removeKey(tt.args.arr, tt.args.targetKey); got != tt.want { 21 | t.Errorf("removeKey() = %v, want %v", got, tt.want) 22 | } 23 | }) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Pattern02 - Two Pointers/Triplets_with_Smaller_Sum/solution_test.go: -------------------------------------------------------------------------------- 1 | package Triplets_with_Smaller_Sum 2 | 3 | import "testing" 4 | 5 | func Test_searchTriplets(t *testing.T) { 6 | type args struct { 7 | arr []int 8 | target int 9 | } 10 | tests := []struct { 11 | name string 12 | args args 13 | want int 14 | }{ 15 | {"case1", args{[]int{-1, 0, 2, 3}, 3}, 2}, 16 | {"case2", args{[]int{-1, 4, 2, 1, 3}, 5}, 4}, 17 | } 18 | for _, tt := range tests { 19 | t.Run(tt.name, func(t *testing.T) { 20 | if got := searchTriplets(tt.args.arr, tt.args.target); got != tt.want { 21 | t.Errorf("searchTriplets() = %v, want %v", got, tt.want) 22 | } 23 | }) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Pattern13 - Top K Elements/Challenge1/solution_test.go: -------------------------------------------------------------------------------- 1 | package challenge1 2 | 3 | import "testing" 4 | 5 | func Test_rearrangeString(t *testing.T) { 6 | type args struct { 7 | s string 8 | k int 9 | } 10 | tests := []struct { 11 | name string 12 | args args 13 | want string 14 | }{ 15 | {"case1", args{"aabbcc", 3}, "abcabc"}, 16 | {"case2", args{"aaabc", 3}, ""}, 17 | {"case3", args{"aaadbbcc", 2}, "abacabcd"}, 18 | } 19 | for _, tt := range tests { 20 | t.Run(tt.name, func(t *testing.T) { 21 | if got := rearrangeString(tt.args.s, tt.args.k); len(got) != len(tt.want) { 22 | t.Errorf("rearrangeString() = %v, want %v", got, tt.want) 23 | } 24 | }) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Pattern15 - 01 Knapsack/Challenge1-Count_of_Subset_Sum/solution_test.go: -------------------------------------------------------------------------------- 1 | package challenge1countofsubsetsum 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func Test_countSubsets(t *testing.T) { 8 | type args struct { 9 | nums []int 10 | sum int 11 | } 12 | tests := []struct { 13 | name string 14 | args args 15 | want int 16 | }{ 17 | {"case1", args{[]int{1, 1, 2, 3}, 4}, 3}, 18 | {"case2", args{[]int{1, 2, 7, 1, 5}, 9}, 3}, 19 | } 20 | for _, tt := range tests { 21 | t.Run(tt.name, func(t *testing.T) { 22 | if got := countSubsets(tt.args.nums, tt.args.sum); got != tt.want { 23 | t.Errorf("canPartition() = %v, want %v", got, tt.want) 24 | } 25 | }) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Pattern15 - 01 Knapsack/Equal_Subset_Sum_Partition/solution_test.go: -------------------------------------------------------------------------------- 1 | package equalsubsetsumpartition 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 | {"case1", args{[]int{1, 2, 3, 4}}, true}, 15 | {"case2", args{[]int{1, 1, 3, 4, 7}}, true}, 16 | {"case3", args{[]int{2, 3, 4, 6}}, false}, 17 | } 18 | for _, tt := range tests { 19 | t.Run(tt.name, func(t *testing.T) { 20 | if got := canPartition(tt.args.nums); got != tt.want { 21 | t.Errorf("canPartition() = %v, want %v", got, tt.want) 22 | } 23 | }) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Pattern16 - Topological Sort/All_Tasks_Scheduling_Orders/solution_test.go: -------------------------------------------------------------------------------- 1 | package All_Tasks_Scheduling_Orders 2 | 3 | import "testing" 4 | 5 | func Test_printOrders(t *testing.T) { 6 | type args struct { 7 | tasks int 8 | prerequisites [][]int 9 | } 10 | tests := []struct { 11 | name string 12 | args args 13 | }{ 14 | {"case1", args{3, [][]int{{0, 1}, {1, 2}}}}, 15 | {"case2", args{4, [][]int{{3, 2}, {3, 0}, {2, 0}, {2, 1}}}}, 16 | {"case3", args{6, [][]int{{2, 5}, {0, 5}, {0, 4}, {1, 4}, {3, 2}, {1, 3}}}}, 17 | } 18 | for _, tt := range tests { 19 | t.Run(tt.name, func(t *testing.T) { 20 | printOrders(tt.args.tasks, tt.args.prerequisites) 21 | }) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Pattern10 - Subsets/Challenge3-Count_of_Structurally_Unique_Binary_Search_Trees/solution_test.go: -------------------------------------------------------------------------------- 1 | package Challenge3_Count_of_Structurally_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 | {"case1", args{2}, 2}, 15 | {"case2", args{3}, 5}, 16 | {"case3", args{1}, 1}, 17 | {"case4", args{4}, 14}, 18 | } 19 | for _, tt := range tests { 20 | t.Run(tt.name, func(t *testing.T) { 21 | if got := numTrees(tt.args.n); got != tt.want { 22 | t.Errorf("numTrees() = %v, want %v", got, tt.want) 23 | } 24 | }) 25 | } 26 | } -------------------------------------------------------------------------------- /Pattern15 - 01 Knapsack/Subset_Sum/solution_test.go: -------------------------------------------------------------------------------- 1 | package subsetsum 2 | 3 | import "testing" 4 | 5 | func Test_canPartition(t *testing.T) { 6 | type args struct { 7 | num []int 8 | sum int 9 | } 10 | tests := []struct { 11 | name string 12 | args args 13 | want bool 14 | }{ 15 | {"case1", args{[]int{1, 2, 3, 7}, 6}, true}, 16 | {"case2", args{[]int{1, 2, 7, 1, 5}, 10}, true}, 17 | {"case3", args{[]int{1, 3, 4, 8}, 6}, false}, 18 | } 19 | for _, tt := range tests { 20 | t.Run(tt.name, func(t *testing.T) { 21 | if got := canPartition(tt.args.num, tt.args.sum); got != tt.want { 22 | t.Errorf("canPartition() = %v, want %v", got, tt.want) 23 | } 24 | }) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Pattern05 - Cyclic Sort/Find_the_Missing_Number/solution_test.go: -------------------------------------------------------------------------------- 1 | package Find_the_Missing_Number 2 | 3 | import "testing" 4 | 5 | func Test_findMissingNumber(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 | {"case1", args{[]int{4, 0, 3, 1}}, 2}, 15 | {"case2", args{[]int{8, 3, 5, 2, 4, 6, 0, 1}}, 7}, 16 | {"case3", args{[]int{1, 3, 2, 0}}, 4}, 17 | } 18 | for _, tt := range tests { 19 | t.Run(tt.name, func(t *testing.T) { 20 | if got := findMissingNumber(tt.args.nums); got != tt.want { 21 | t.Errorf("findMissingNumber() = %v, want %v", got, tt.want) 22 | } 23 | }) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Pattern15 - 01 Knapsack/Minimum_Subset_Sum_Difference/solution_test.go: -------------------------------------------------------------------------------- 1 | package minimumsubsetsumdifference 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func Test_canPartition(t *testing.T) { 8 | type args struct { 9 | nums []int 10 | } 11 | tests := []struct { 12 | name string 13 | args args 14 | want int 15 | }{ 16 | {"case1", args{[]int{1, 2, 3, 9}}, 3}, 17 | {"case2", args{[]int{1, 2, 7, 1, 5}}, 0}, 18 | {"case3", args{[]int{1, 3, 100, 4}}, 92}, 19 | } 20 | for _, tt := range tests { 21 | t.Run(tt.name, func(t *testing.T) { 22 | if got := canPartition(tt.args.nums); got != tt.want { 23 | t.Errorf("canPartition() = %v, want %v", got, tt.want) 24 | } 25 | }) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Pattern13 - Top K Elements/Frequency_Sort/solution_test.go: -------------------------------------------------------------------------------- 1 | package frequencysort 2 | 3 | import "testing" 4 | 5 | func Test_frequencySort(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 | {"case1", args{"tree"}, []string{"eert", "eetr"}}, 15 | {"case2", args{"cccaaa"}, []string{"cccaaa", "aaaccc"}}, 16 | } 17 | for _, tt := range tests { 18 | t.Run(tt.name, func(t *testing.T) { 19 | got := frequencySort(tt.args.s) 20 | for _, v := range tt.want { 21 | if v == got { 22 | return 23 | } 24 | } 25 | t.Errorf("frequencySort() = %v, want %v", got, tt.want) 26 | }) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Pattern13 - Top K Elements/Sum_of_Elements/solution_test.go: -------------------------------------------------------------------------------- 1 | package sumofelements 2 | 3 | import "testing" 4 | 5 | func Test_findSumOfElements(t *testing.T) { 6 | type args struct { 7 | nums []int 8 | k1 int 9 | k2 int 10 | } 11 | tests := []struct { 12 | name string 13 | args args 14 | want int 15 | }{ 16 | {"case1", args{[]int{1, 3, 12, 5, 15, 11}, 3, 6}, 23}, 17 | {"case2", args{[]int{3, 5, 8, 7}, 1, 4}, 12}, 18 | } 19 | for _, tt := range tests { 20 | t.Run(tt.name, func(t *testing.T) { 21 | if got := findSumOfElements(tt.args.nums, tt.args.k1, tt.args.k2); got != tt.want { 22 | t.Errorf("findSumOfElements() = %v, want %v", got, tt.want) 23 | } 24 | }) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Pattern14 - K-way merge/Kth_Smallest_Number_in_a_Sorted_Matrix/solution_test.go: -------------------------------------------------------------------------------- 1 | package kthsmallestnumberinasortedmatrix 2 | 3 | import "testing" 4 | 5 | func Test_kthSmallest(t *testing.T) { 6 | type args struct { 7 | matrix [][]int 8 | k int 9 | } 10 | tests := []struct { 11 | name string 12 | args args 13 | want int 14 | }{ 15 | {"case1", args{[][]int{{1, 5, 9}, {10, 11, 13}, {12, 13, 15}}, 8}, 13}, 16 | {"case2", args{[][]int{}, 1}, -1}, 17 | } 18 | for _, tt := range tests { 19 | t.Run(tt.name, func(t *testing.T) { 20 | if got := kthSmallest(tt.args.matrix, tt.args.k); got != tt.want { 21 | t.Errorf("kthSmallest() = %v, want %v", got, tt.want) 22 | } 23 | }) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Pattern01 - Sliding Window/Longest_Substring_with_K_Distinct_Characters/solution_test.go: -------------------------------------------------------------------------------- 1 | package Longest_Substring_with_K_Distinct_Characters 2 | 3 | import "testing" 4 | 5 | func Test_findLength(t *testing.T) { 6 | type args struct { 7 | str string 8 | k int 9 | } 10 | tests := []struct { 11 | name string 12 | args args 13 | want int 14 | }{ 15 | {"case1", args{"araaci", 2}, 4}, 16 | {"case2", args{"araaci", 1}, 2}, 17 | {"case3", args{"cbbebi", 3}, 5}, 18 | } 19 | for _, tt := range tests { 20 | t.Run(tt.name, func(t *testing.T) { 21 | if got := findLength(tt.args.str, tt.args.k); got != tt.want { 22 | t.Errorf("findLength() = %v, want %v", got, tt.want) 23 | } 24 | }) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Pattern02 - Two Pointers/Squaring_a_Sorted_Array/solution_test.go: -------------------------------------------------------------------------------- 1 | package Squaring_a_Sorted_Array 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_makeSquares(t *testing.T) { 9 | type args struct { 10 | arr []int 11 | } 12 | tests := []struct { 13 | name string 14 | args args 15 | want []int 16 | }{ 17 | {"case1", args{[]int{-2, -1, 0, 2, 3}}, []int{0, 1, 4, 4, 9}}, 18 | {"case2", args{[]int{-3, -1, 0, 1, 2}}, []int{0, 1, 1, 4, 9}}, 19 | } 20 | for _, tt := range tests { 21 | t.Run(tt.name, func(t *testing.T) { 22 | if got := makeSquares(tt.args.arr); !reflect.DeepEqual(got, tt.want) { 23 | t.Errorf("makeSquares() = %v, want %v", got, tt.want) 24 | } 25 | }) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Pattern01 - Sliding Window/Fruits_into_Baskets/solution_test.go: -------------------------------------------------------------------------------- 1 | package Fruits_into_Baskets 2 | 3 | import "testing" 4 | 5 | func Test_findLength(t *testing.T) { 6 | type args struct { 7 | arr []byte 8 | } 9 | tests := []struct { 10 | name string 11 | args args 12 | want int 13 | }{ 14 | {"case1", args{arr: []byte{'A', 'B', 'C', 'A', 'C'}}, 3}, 15 | {"case2", args{arr: []byte{'A', 'B', 'C', 'B', 'B', 'C'}}, 5}, 16 | {"case3", args{arr: []byte{'A', 'R', 'A', 'A', 'C', 'I'}}, 4}, 17 | } 18 | for _, tt := range tests { 19 | t.Run(tt.name, func(t *testing.T) { 20 | if got := findLength(tt.args.arr); got != tt.want { 21 | t.Errorf("findLength() = %v, want %v", got, tt.want) 22 | } 23 | }) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Pattern02 - Two Pointers/Dutch_National_Flag_Problem/solution_test.go: -------------------------------------------------------------------------------- 1 | package Dutch_National_Flag_Problem 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_sort(t *testing.T) { 9 | type args struct { 10 | arr []int 11 | } 12 | tests := []struct { 13 | name string 14 | args args 15 | want []int 16 | }{ 17 | {"case1", args{[]int{1, 0, 2, 1, 0}}, []int{0, 0, 1, 1, 2}}, 18 | {"case2", args{[]int{2, 2, 0, 1, 2, 0}}, []int{0, 0, 1, 2, 2, 2}}, 19 | } 20 | for _, tt := range tests { 21 | t.Run(tt.name, func(t *testing.T) { 22 | sort(tt.args.arr) 23 | if !reflect.DeepEqual(tt.args.arr, tt.want) { 24 | t.Errorf("sort() = %v, want %v", tt.args.arr, tt.want) 25 | } 26 | }) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Pattern05 - Cyclic Sort/Cyclic_Sort/solution_test.go: -------------------------------------------------------------------------------- 1 | package Cyclic_Sort 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | func Test_sort(t *testing.T) { 9 | type args struct { 10 | nums []int 11 | } 12 | tests := []struct { 13 | name string 14 | args args 15 | }{ 16 | {"case1", args{[]int{3, 1, 5, 4, 2}}}, 17 | {"case2", args{[]int{2, 6, 4, 3, 1, 5}}}, 18 | {"case3", args{[]int{1, 5, 6, 4, 3, 2}}}, 19 | } 20 | for _, tt := range tests { 21 | t.Run(tt.name, func(t *testing.T) { 22 | sort(tt.args.nums) 23 | for i, v := range tt.args.nums { 24 | if i+1 != v { 25 | t.Errorf("want %d, but got %d", i, v) 26 | break 27 | } 28 | } 29 | fmt.Println(tt.args.nums) 30 | }) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Pattern09 - Two Heaps/Find_the_Median_of_a_Number_Stream/solution_test.go: -------------------------------------------------------------------------------- 1 | package Find_the_Median_of_a_Number_Stream 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestConstructor(t *testing.T) { 8 | medianOfAStream := Constructor() 9 | medianOfAStream.AddNum(3) 10 | medianOfAStream.AddNum(1) 11 | if medianOfAStream.FindMedian() != 2.0 { 12 | t.Errorf("want 2.0, but got %f", medianOfAStream.FindMedian()) 13 | } 14 | medianOfAStream.AddNum(5) 15 | if medianOfAStream.FindMedian() != 3.0 { 16 | t.Errorf("want 3.0, but got %f", medianOfAStream.FindMedian()) 17 | } 18 | medianOfAStream.AddNum(4) 19 | if medianOfAStream.FindMedian() != 3.5 { 20 | t.Errorf("want 3.5, but got %f", medianOfAStream.FindMedian()) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Pattern14 - K-way merge/Kth_Smallest_Number_in_a_Sorted_Matrix/binary_search_solution_test.go: -------------------------------------------------------------------------------- 1 | package kthsmallestnumberinasortedmatrix 2 | 3 | import "testing" 4 | 5 | func Test_kthSmallestByBinarySearch(t *testing.T) { 6 | type args struct { 7 | matrix [][]int 8 | k int 9 | } 10 | tests := []struct { 11 | name string 12 | args args 13 | want int 14 | }{ 15 | {"case1", args{[][]int{{1, 5, 9}, {10, 11, 13}, {12, 13, 15}}, 8}, 13}, 16 | } 17 | 18 | for _, tt := range tests { 19 | t.Run(tt.name, func(t *testing.T) { 20 | if got := kthSmallestByBinarySearch(tt.args.matrix, tt.args.k); got != tt.want { 21 | t.Errorf("kthSmallestByBinarySearch() = %v, want %v", got, tt.want) 22 | } 23 | }) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Pattern01 - Sliding Window/Longest_Substring_with_Same_Letters_after_Replacement/solution_test.go: -------------------------------------------------------------------------------- 1 | package Longest_Substring_with_Same_Letters_after_Replacement 2 | 3 | import "testing" 4 | 5 | func Test_findLength(t *testing.T) { 6 | type args struct { 7 | str string 8 | k int 9 | } 10 | tests := []struct { 11 | name string 12 | args args 13 | want int 14 | }{ 15 | {"case1", args{"aabccbb", 2}, 5}, 16 | {"case2", args{"abbcb", 1}, 4}, 17 | {"case3", args{"abccde", 1}, 3}, 18 | } 19 | for _, tt := range tests { 20 | t.Run(tt.name, func(t *testing.T) { 21 | if got := findLength(tt.args.str, tt.args.k); got != tt.want { 22 | t.Errorf("findLength() = %v, want %v", got, tt.want) 23 | } 24 | }) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Pattern01 - Sliding Window/Maximum_Sum_Subarray_of_Size_K/solution_test.go: -------------------------------------------------------------------------------- 1 | package Maximum_Sum_Subarray_of_Size_K 2 | 3 | import "testing" 4 | 5 | func Test_findMaxSumSubArray(t *testing.T) { 6 | type args struct { 7 | k int 8 | arr []int 9 | } 10 | tests := []struct { 11 | name string 12 | args args 13 | want int 14 | }{ 15 | {name: "case1", args: args{3, []int{2, 1, 5, 1, 3, 2}}, want: 9}, 16 | {name: "case2", args: args{2, []int{2, 3, 4, 1, 5}}, want: 7}, 17 | } 18 | for _, tt := range tests { 19 | t.Run(tt.name, func(t *testing.T) { 20 | if got := findMaxSumSubArray(tt.args.k, tt.args.arr); got != tt.want { 21 | t.Errorf("findMaxSumSubArray() = %v, want %v", got, tt.want) 22 | } 23 | }) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Pattern13 - Top K Elements/Kth_Smallest_Number/solution_test.go: -------------------------------------------------------------------------------- 1 | package kthsmallestnumber 2 | 3 | import "testing" 4 | 5 | func Test_findKthSmallest(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 | {"case1", args{[]int{1, 5, 12, 2, 11, 5}, 3}, 5}, 16 | {"case2", args{[]int{1, 5, 12, 2, 11, 5}, 4}, 5}, 17 | {"case3", args{[]int{5, 12, 11, -1, 12}, 3}, 11}, 18 | } 19 | for _, tt := range tests { 20 | t.Run(tt.name, func(t *testing.T) { 21 | if got := findKthSmallest(tt.args.nums, tt.args.k); got != tt.want { 22 | t.Errorf("findKthSmallest() = %v, want %v", got, tt.want) 23 | } 24 | }) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Pattern16 - Topological Sort/Alien_Dictionary/solution_test.go: -------------------------------------------------------------------------------- 1 | package Alien_Dictionary 2 | 3 | import "testing" 4 | 5 | func Test_findOrder(t *testing.T) { 6 | type args struct { 7 | words []string 8 | } 9 | tests := []struct { 10 | name string 11 | args args 12 | want string 13 | }{ 14 | {"case1", args{[]string{"ba", "bc", "ac", "cab"}}, "bac"}, 15 | {"case2", args{[]string{"cab", "aaa", "aab"}}, "cab"}, 16 | {"case3", args{[]string{"ywx", "wz", "xww", "xz", "zyy", "zwz"}}, "ywxz"}, 17 | } 18 | for _, tt := range tests { 19 | t.Run(tt.name, func(t *testing.T) { 20 | if got := findOrder(tt.args.words); got != tt.want { 21 | t.Errorf("findOrder() = %v, want %v", got, tt.want) 22 | } 23 | }) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Pattern01 - Sliding Window/Longest_Subarray_with_Ones_after_Replacement/solution_test.go: -------------------------------------------------------------------------------- 1 | package Longest_Subarray_with_Ones_after_Replacement 2 | 3 | import "testing" 4 | 5 | func Test_findLength(t *testing.T) { 6 | type args struct { 7 | arr []int 8 | k int 9 | } 10 | tests := []struct { 11 | name string 12 | args args 13 | want int 14 | }{ 15 | {"case1", args{[]int{0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1}, 2}, 6}, 16 | {"case2", args{[]int{0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1}, 3}, 9}, 17 | } 18 | for _, tt := range tests { 19 | t.Run(tt.name, func(t *testing.T) { 20 | if got := findLength(tt.args.arr, tt.args.k); got != tt.want { 21 | t.Errorf("findLength() = %v, want %v", got, tt.want) 22 | } 23 | }) 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Pattern02 - Two Pointers/Triplet_Sum_Close_to_Target/solution_test.go: -------------------------------------------------------------------------------- 1 | package Triplet_Sum_Close_to_Target 2 | 3 | import "testing" 4 | 5 | func Test_searchTriplet(t *testing.T) { 6 | type args struct { 7 | arr []int 8 | targetSum int 9 | } 10 | tests := []struct { 11 | name string 12 | args args 13 | want int 14 | }{ 15 | {"case1", args{[]int{-2, 0, 1, 2}, 2}, 1}, 16 | {"case2", args{[]int{-3, -1, 1, 2}, 1}, 0}, 17 | {"case3", args{[]int{1, 0, 1, 1}, 100}, 3}, 18 | } 19 | for _, tt := range tests { 20 | t.Run(tt.name, func(t *testing.T) { 21 | if got := searchTriplet(tt.args.arr, tt.args.targetSum); got != tt.want { 22 | t.Errorf("searchTriplet() = %v, want %v", got, tt.want) 23 | } 24 | }) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Pattern14 - K-way merge/Smallest_Number_Range/solution_test.go: -------------------------------------------------------------------------------- 1 | package smallestnumberrange 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_smallestRange(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 | {"case1", args{[][]int{{1, 5, 8}, {4, 12}, {7, 8, 10}}}, []int{4, 7}}, 18 | {"case2", args{[][]int{{1, 9}, {4, 12}, {7, 10, 16}}}, []int{9, 12}}, 19 | } 20 | for _, tt := range tests { 21 | t.Run(tt.name, func(t *testing.T) { 22 | if got := smallestRange(tt.args.nums); !reflect.DeepEqual(got, tt.want) { 23 | t.Errorf("smallestRange() = %v, want %v", got, tt.want) 24 | } 25 | }) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Pattern05 - Cyclic Sort/Find_all_Duplicate_Number/solution_test.go: -------------------------------------------------------------------------------- 1 | package Find_all_Duplicate_Number 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_findAllDuplicateNumbers(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 | {"case1", args{[]int{3, 4, 4, 5, 5}}, []int{5, 4}}, 18 | {"case2", args{[]int{5, 4, 7, 2, 3, 5, 3}}, []int{3, 5}}, 19 | } 20 | for _, tt := range tests { 21 | t.Run(tt.name, func(t *testing.T) { 22 | if got := findAllDuplicateNumbers(tt.args.nums); !reflect.DeepEqual(got, tt.want) { 23 | t.Errorf("findAllDuplicateNumbers() = %v, want %v", got, tt.want) 24 | } 25 | }) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Pattern11 - Modified Binary Search/Ceiling_of_a_Number/solution_test.go: -------------------------------------------------------------------------------- 1 | package Ceiling_of_a_Number 2 | 3 | import "testing" 4 | 5 | func Test_SearchCeilingOfANumber(t *testing.T) { 6 | type args struct { 7 | arr []int 8 | key int 9 | } 10 | 11 | tests := []struct { 12 | name string 13 | args args 14 | want int 15 | }{ 16 | {"case1", args{[]int{4, 6, 10}, 6}, 1}, 17 | {"case2", args{[]int{1, 3, 8, 10, 15}, 12}, 4}, 18 | {"case3", args{[]int{4, 6, 10}, 17}, -1}, 19 | {"case4", args{[]int{4, 6, 10}, -1}, 0}, 20 | } 21 | 22 | for _, tt := range tests { 23 | if got := searchCeilingOfANumber(tt.args.arr, tt.args.key); got != tt.want { 24 | t.Errorf("searchCeilingOfANumber() = %v, but want %v", got, tt.want) 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /Pattern08 - Tree DFS/Sum_of_Path_Numbers/solution_test.go: -------------------------------------------------------------------------------- 1 | package Sum_of_Path_Numbers 2 | 3 | import "testing" 4 | 5 | func Test_sumNumbers(t *testing.T) { 6 | type args struct { 7 | root *TreeNode 8 | } 9 | 10 | head1 := &TreeNode{1, nil, nil} 11 | head1.Left = &TreeNode{7, nil, nil} 12 | head1.Right = &TreeNode{9, &TreeNode{Val: 2}, &TreeNode{Val: 9}} 13 | 14 | tests := []struct { 15 | name string 16 | args args 17 | want int 18 | }{ 19 | {"case1", args{head1}, 408}, 20 | {"case2", args{nil}, 0}, 21 | } 22 | for _, tt := range tests { 23 | t.Run(tt.name, func(t *testing.T) { 24 | if got := sumNumbers(tt.args.root); got != tt.want { 25 | t.Errorf("sumNumbers() = %v, want %v", got, tt.want) 26 | } 27 | }) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Pattern05 - Cyclic Sort/Find_the_Duplicate_Number/solution_test.go: -------------------------------------------------------------------------------- 1 | package Find_the_Duplicate_Number 2 | 3 | import "testing" 4 | 5 | func Test_findDuplicateNumber(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 | {"case1", args{[]int{1, 4, 4, 3, 2}}, 4}, 15 | {"case2", args{[]int{2, 1, 3, 3, 5, 4}}, 3}, 16 | {"case3", args{[]int{2, 4, 1, 4, 4}}, 4}, 17 | //{"case4", args{[]int{2, 4, 3, 1}}, -1}, 18 | } 19 | for _, tt := range tests { 20 | t.Run(tt.name, func(t *testing.T) { 21 | if got := findDuplicateNumber(tt.args.nums); got != tt.want { 22 | t.Errorf("findDuplicateNumber() = %v, want %v", got, tt.want) 23 | } 24 | }) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Pattern07 - Tree BFS/Reverse_Level_Order_Traversal/append_compare.go: -------------------------------------------------------------------------------- 1 | package Reverse_Level_Order_Traversal 2 | 3 | func method1() { 4 | result := make([][]int, 0) 5 | for i := 0; i < 100; i++ { 6 | item := make([]int, 0) 7 | for j := 0; j < 10; j++ { 8 | item = append(item, i*j) 9 | } 10 | join := [][]int{item} 11 | result = append(join, result...) 12 | } 13 | } 14 | 15 | func method2() { 16 | result := make([][]int, 0) 17 | for i := 0; i < 100; i++ { 18 | item := make([]int, 0) 19 | for j := 0; j < 10; j++ { 20 | item = append(item, i*j) 21 | } 22 | result = append(result, item) 23 | } 24 | tmp := result 25 | result = make([][]int, 0) 26 | for i := len(tmp) - 1; i >= 0; i-- { 27 | result = append(result, tmp[i]) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Pattern11 - Modified Binary Search/Bitonic_Array_Maximum/solution_test.go: -------------------------------------------------------------------------------- 1 | package bitonicarraymaximum 2 | 3 | import "testing" 4 | 5 | func Test_findMax(t *testing.T) { 6 | type args struct { 7 | arr []int 8 | } 9 | tests := []struct { 10 | name string 11 | args args 12 | want int 13 | }{ 14 | {"case1", args{[]int{1, 3, 8, 12, 4, 2}}, 12}, 15 | {"case2", args{[]int{3, 8, 3, 1}}, 8}, 16 | {"case3", args{[]int{1, 3, 8, 12}}, 12}, 17 | {"case4", args{[]int{10, 9, 8}}, 10}, 18 | {"case5", args{[]int{3, 8, 3}}, 8}, 19 | } 20 | for _, tt := range tests { 21 | t.Run(tt.name, func(t *testing.T) { 22 | if got := findMax(tt.args.arr); got != tt.want { 23 | t.Errorf("findMax() = %v, want %v", got, tt.want) 24 | } 25 | }) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Pattern14 - K-way merge/Challenge1-K_Pairs_with_Largest_Sums/solution_test.go: -------------------------------------------------------------------------------- 1 | package kpairswithlargestsums 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_kLargestPairs(t *testing.T) { 9 | type args struct { 10 | nums1 []int 11 | nums2 []int 12 | k int 13 | } 14 | tests := []struct { 15 | name string 16 | args args 17 | want [][]int 18 | }{ 19 | {"case1", args{[]int{9, 8, 2}, []int{6, 3, 1}, 3}, [][]int{{9, 3}, {9, 6}, {8, 6}}}, 20 | } 21 | for _, tt := range tests { 22 | t.Run(tt.name, func(t *testing.T) { 23 | if got := kLargestPairs(tt.args.nums1, tt.args.nums2, tt.args.k); !reflect.DeepEqual(got, tt.want) { 24 | t.Errorf("kLargestPairs() = %v, want %v", got, tt.want) 25 | } 26 | }) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Pattern01 - Sliding Window/Challenge2-String_Anagrams/solution_test.go: -------------------------------------------------------------------------------- 1 | package Challenge2_String_Anagrams 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_findStringAnagrams(t *testing.T) { 9 | type args struct { 10 | str string 11 | pattern string 12 | } 13 | tests := []struct { 14 | name string 15 | args args 16 | want []int 17 | }{ 18 | {"case1", args{"ppqp", "pq"}, []int{1, 2}}, 19 | {"case2", args{"abbcabc", "abc"}, []int{2, 3, 4}}, 20 | } 21 | for _, tt := range tests { 22 | t.Run(tt.name, func(t *testing.T) { 23 | if got := findStringAnagrams(tt.args.str, tt.args.pattern); !reflect.DeepEqual(got, tt.want) { 24 | t.Errorf("findStringAnagrams() = %v, want %v", got, tt.want) 25 | } 26 | }) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Pattern05 - Cyclic Sort/Find_all_Missing_Number/solution_test.go: -------------------------------------------------------------------------------- 1 | package Find_all_Missing_Number 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_findNumbers(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 | {"case1", args{[]int{2, 3, 1, 8, 2, 3, 5, 1}}, []int{4, 6, 7}}, 18 | {"case2", args{[]int{2, 4, 1, 2}}, []int{3}}, 19 | {"case3", args{[]int{2, 3, 2, 1}}, []int{4}}, 20 | } 21 | for _, tt := range tests { 22 | t.Run(tt.name, func(t *testing.T) { 23 | if got := findNumbers(tt.args.nums); !reflect.DeepEqual(got, tt.want) { 24 | t.Errorf("findNumbers() = %v, want %v", got, tt.want) 25 | } 26 | }) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Pattern08 - Tree DFS/Binary_Tree_Path_Sum/solution.go: -------------------------------------------------------------------------------- 1 | package Binary_Tree_Path_Sum 2 | 3 | /* 4 | Given a binary tree and a number ‘S’, find if the tree has a path from root-to-leaf such that the sum of all the node values of that path equals ‘S’. 5 | */ 6 | 7 | type TreeNode struct { 8 | Val int 9 | Left, Right *TreeNode 10 | } 11 | 12 | func hasPathSum(root *TreeNode, targetSum int) bool { 13 | if root == nil { 14 | return false 15 | } 16 | 17 | // 因为每一次向下遍历,targetSum都会减去遍历后的节点值,因此如果存在一条这样的path,那么遍历到该path的叶子节点时 18 | // 其targetSum一定会等于叶子节点的值 19 | if root.Val == targetSum && root.Left == nil && root.Right == nil { 20 | return true 21 | } 22 | return hasPathSum(root.Left, targetSum-root.Val) || hasPathSum(root.Right, targetSum-root.Val) 23 | } 24 | -------------------------------------------------------------------------------- /Pattern03 - Fast and Slow pointers/Challenge3-Cycle_in_a_Circular_Array/solution_test.go: -------------------------------------------------------------------------------- 1 | package Challenge3_Cycle_in_a_Circular_Array 2 | 3 | import "testing" 4 | 5 | func Test_loopExists(t *testing.T) { 6 | type args struct { 7 | arr []int 8 | } 9 | tests := []struct { 10 | name string 11 | args args 12 | want bool 13 | }{ 14 | {"case1", args{[]int{1, 2, -1, 2, 2}}, true}, 15 | {"case2", args{[]int{2, 2, -1, 2}}, true}, 16 | {"case3", args{[]int{2, 1, -1, -2}}, false}, 17 | {"case4", args{[]int{2, 1, 4, -2}}, false}, 18 | } 19 | for _, tt := range tests { 20 | t.Run(tt.name, func(t *testing.T) { 21 | if got := loopExists(tt.args.arr); got != tt.want { 22 | t.Errorf("loopExists() = %v, want %v", got, tt.want) 23 | } 24 | }) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Miscellaneous/brute-force_test.go: -------------------------------------------------------------------------------- 1 | package Miscellaneous 2 | 3 | import "testing" 4 | 5 | func Test_findKthSmallestNumber(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 | {"case1", args{[]int{1, 5, 12, 2, 11, 5}, 3}, 5}, 16 | {"case2", args{[]int{1, 5, 12, 2, 11, 5}, 4}, 5}, 17 | {"case3", args{[]int{5, 12, 11, -1, 12}, 3}, 11}, 18 | {"case4", args{[]int{5, 12, 11, -1, 12}, 6}, -1}, 19 | } 20 | for _, tt := range tests { 21 | t.Run(tt.name, func(t *testing.T) { 22 | if got := findKthSmallestNumber(tt.args.nums, tt.args.k); got != tt.want { 23 | t.Errorf("findKthSmallestNumber() = %v, want %v", got, tt.want) 24 | } 25 | }) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Pattern01 - Sliding Window/Challenge3-Smallest_Window_containing_Substring/solution_test.go: -------------------------------------------------------------------------------- 1 | package Challenge3_Smallest_Window_containing_Substring 2 | 3 | import "testing" 4 | 5 | func Test_findSubstring(t *testing.T) { 6 | type args struct { 7 | str string 8 | pattern string 9 | } 10 | tests := []struct { 11 | name string 12 | args args 13 | want string 14 | }{ 15 | {"case1", args{"aabdec", "abc"}, "abdec"}, 16 | {"case2", args{"abdbca", "abc"}, "bca"}, 17 | {"case3", args{"adcad", "abc"}, ""}, 18 | } 19 | for _, tt := range tests { 20 | t.Run(tt.name, func(t *testing.T) { 21 | if got := findSubstring(tt.args.str, tt.args.pattern); got != tt.want { 22 | t.Errorf("findSubstring() = %v, want %v", got, tt.want) 23 | } 24 | }) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Pattern05 - Cyclic Sort/Challenge2-Find_the_Smallest_Missing_Positive_Number/solution_test.go: -------------------------------------------------------------------------------- 1 | package Challenge2_Find_the_Smallest_Missing_Positive_Number 2 | 3 | import "testing" 4 | 5 | func Test_findNumber(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 | {"case1", args{[]int{-3, 1, 5, 4, 2}}, 3}, 15 | {"case2", args{[]int{3, -2, 0, 1, 2}}, 4}, 16 | {"case3", args{[]int{3, 2, 5, 1}}, 4}, 17 | {"case4", args{[]int{3, 2, 4, 1}}, 5}, 18 | } 19 | for _, tt := range tests { 20 | t.Run(tt.name, func(t *testing.T) { 21 | if got := findNumber(tt.args.nums); got != tt.want { 22 | t.Errorf("findNumber() = %v, want %v", got, tt.want) 23 | } 24 | }) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Pattern14 - K-way merge/Kth_Smallest_Number_in_M_Sorted_Lists/solution_test.go: -------------------------------------------------------------------------------- 1 | package kthsmallestnumberinmsortedlists 2 | 3 | import "testing" 4 | 5 | func Test_kthSmallest(t *testing.T) { 6 | type args struct { 7 | matrix [][]int 8 | k int 9 | } 10 | tests := []struct { 11 | name string 12 | args args 13 | want int 14 | }{ 15 | {"case1", args{[][]int{{2, 6, 8}, {3, 6, 7}, {1, 3, 4}}, 5}, 4}, 16 | {"case2", args{[][]int{{5, 8, 9}, {1, 7}}, 3}, 7}, 17 | {"case3", args{[][]int{{1, 3}, {2, 4}}, 5}, -1}, 18 | } 19 | for _, tt := range tests { 20 | t.Run(tt.name, func(t *testing.T) { 21 | if got := kthSmallest(tt.args.matrix, tt.args.k); got != tt.want { 22 | t.Errorf("kthSmallest() = %v, want %v", got, tt.want) 23 | } 24 | }) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Pattern05 - Cyclic Sort/Challenge1-Find_the_Corrupt_Pair/solution_test.go: -------------------------------------------------------------------------------- 1 | package Challenge1_Find_the_Corrupt_Pair 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_findNumbers(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 | {"case1", args{[]int{3, 1, 2, 5, 2}}, []int{2, 4}}, 18 | {"case2", args{[]int{3, 1, 2, 3, 6, 4}}, []int{3, 5}}, 19 | {"case3", args{[]int{3, 1, 2, 4}}, []int{-1, -1}}, 20 | } 21 | for _, tt := range tests { 22 | t.Run(tt.name, func(t *testing.T) { 23 | if got := findNumbers(tt.args.nums); !reflect.DeepEqual(got, tt.want) { 24 | t.Errorf("findNumbers() = %v, want %v", got, tt.want) 25 | } 26 | }) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Pattern13 - Top K Elements/K_Closest_Points_to_the_Origin/solution_test.go: -------------------------------------------------------------------------------- 1 | package kclosestpointstotheorigin 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_kClosest(t *testing.T) { 9 | type args struct { 10 | points [][]int 11 | k int 12 | } 13 | tests := []struct { 14 | name string 15 | args args 16 | want [][]int 17 | }{ 18 | {"case1", args{[][]int{{1, 3}, {-2, 2}}, 1}, [][]int{{-2, 2}}}, 19 | {"case2", args{[][]int{{1, 3}, {3, 4}, {2, -1}}, 2}, [][]int{{1, 3}, {2, -1}}}, 20 | } 21 | for _, tt := range tests { 22 | t.Run(tt.name, func(t *testing.T) { 23 | if got := kClosest(tt.args.points, tt.args.k); !reflect.DeepEqual(got, tt.want) { 24 | t.Errorf("kClosest() = %v, want %v", got, tt.want) 25 | } 26 | }) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Pattern01 - Sliding Window/introduction/brute-fore_test.go: -------------------------------------------------------------------------------- 1 | package introduction 2 | 3 | import "testing" 4 | 5 | func TestFindAveragesOfSubArraysByBruteForce(t *testing.T) { 6 | arr := []int{1, 3, 2, 6, -1, 4, 1, 8, 2} 7 | results := findAveragesOfSubArraysByBruteForce(5, arr) 8 | expected := []float64{2.2, 2.8, 2.4, 3.6, 2.8} 9 | if len(results) != len(expected) { 10 | t.Errorf("Averages of subarrays of size K(5): %d, answer is %f, expect is %f", arr, results, expected) 11 | } else { 12 | eq := true 13 | for i := 0; i < len(results); i++ { 14 | if results[i] != expected[i] { 15 | eq = false 16 | break 17 | } 18 | } 19 | if !eq { 20 | t.Errorf("Averages of subarrays of size K(5): %d, answer is %f, expect is %f", arr, results, expected) 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Pattern02 - Two Pointers/Challenge3-Minimum_Window_Sort/solution_test.go: -------------------------------------------------------------------------------- 1 | package Challenge3_Minimum_Window_Sort 2 | 3 | import "testing" 4 | 5 | func Test_sort(t *testing.T) { 6 | type args struct { 7 | arr []int 8 | } 9 | tests := []struct { 10 | name string 11 | args args 12 | want int 13 | }{ 14 | {"case1", args{[]int{1, 2, 5, 3, 7, 10, 9, 12}}, 5}, 15 | {"case2", args{[]int{1, 3, 2, 0, -1, 7, 10}}, 5}, 16 | {"case3", args{[]int{1, 2, 3}}, 0}, 17 | {"case4", args{[]int{3, 2, 1}}, 3}, 18 | {"case4", args{[]int{1, 3, 2, 0, -1, 0, 7, 10}}, 6}, 19 | } 20 | for _, tt := range tests { 21 | t.Run(tt.name, func(t *testing.T) { 22 | if got := sort(tt.args.arr); got != tt.want { 23 | t.Errorf("sort() = %v, want %v", got, tt.want) 24 | } 25 | }) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Pattern05 - Cyclic Sort/Cyclic_Sort/solution.go: -------------------------------------------------------------------------------- 1 | package Cyclic_Sort 2 | 3 | /* 4 | We are given an array containing ‘n’ objects. 5 | Each object, when created, was assigned a unique number from 1 to ‘n’ based on their creation sequence 6 | 7 | Write a function to sort the objects in-place on their creation sequence number in O(n)O(n) and without any extra space. 8 | 9 | Input: [3, 1, 5, 4, 2] 10 | Output: [1, 2, 3, 4, 5] 11 | 12 | Input: [2, 6, 4, 3, 1, 5] 13 | Output: [1, 2, 3, 4, 5, 6] 14 | 15 | Input: [1, 5, 6, 4, 3, 2] 16 | Output: [1, 2, 3, 4, 5, 6] 17 | */ 18 | 19 | func sort(nums []int) { 20 | var i = 0 21 | for i < len(nums) { 22 | j := nums[i] - 1 23 | if nums[i] != nums[j] { 24 | nums[i], nums[j] = nums[j], nums[i] 25 | } else { 26 | i++ 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Pattern15 - 01 Knapsack/Challenge2-Target_Sum/solution_test.go: -------------------------------------------------------------------------------- 1 | package Challenge2_Target_Sum 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func Test_findTargetSumWays(t *testing.T) { 8 | type args struct { 9 | nums []int 10 | target int 11 | } 12 | tests := []struct { 13 | name string 14 | args args 15 | want int 16 | }{ 17 | {"case1", args{[]int{1, 1, 2, 3}, 1}, 3}, 18 | {"case2", args{[]int{1, 2, 7, 1}, 9}, 2}, 19 | {"case3", args{[]int{1, 2, 3, 4}, 20}, 0}, 20 | {"case4", args{[]int{1, 2, 3, 4}, 3}, 0}, 21 | } 22 | for _, tt := range tests { 23 | t.Run(tt.name, func(t *testing.T) { 24 | if got := findTargetSumWays(tt.args.nums, tt.args.target); got != tt.want { 25 | t.Errorf("canPartition() = %v, want %v", got, tt.want) 26 | } 27 | }) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Pattern02 - Two Pointers/Triplet_Sum_to_Zero/solution_test.go: -------------------------------------------------------------------------------- 1 | package Triplet_Sum_to_Zero 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_searchTriplets(t *testing.T) { 9 | type args struct { 10 | arr []int 11 | } 12 | tests := []struct { 13 | name string 14 | args args 15 | want [][3]int 16 | }{ 17 | {"case1", args{[]int{-3, 0, 1, 2, -1, 1, -2}}, [][3]int{{-3, 1, 2}, {-2, 0, 2}, 18 | {-2, 1, 1}, {-1, 0, 1}}}, 19 | {"case2", args{[]int{-5, 2, -1, -2, 3}}, [][3]int{{-5, 2, 3}, {-2, -1, 3}}}, 20 | } 21 | for _, tt := range tests { 22 | t.Run(tt.name, func(t *testing.T) { 23 | if got := searchTriplets(tt.args.arr); !reflect.DeepEqual(got, tt.want) { 24 | t.Errorf("searchTriplets() = %v, want %v", got, tt.want) 25 | } 26 | }) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Pattern01 - Sliding Window/introduction/sliding-window_test.go: -------------------------------------------------------------------------------- 1 | package introduction 2 | 3 | import "testing" 4 | 5 | func TestFindAveragesOfSubArraysBySlidingWindow(t *testing.T) { 6 | arr := []int{1, 3, 2, 6, -1, 4, 1, 8, 2} 7 | results := findAveragesOfSubArraysBySlidingWindow(5, arr) 8 | expected := []float64{2.2, 2.8, 2.4, 3.6, 2.8} 9 | if len(results) != len(expected) { 10 | t.Errorf("Averages of subarrays of size K(5): %d, answer is %f, expect is %f", arr, results, expected) 11 | } else { 12 | eq := true 13 | for i := 0; i < len(results); i++ { 14 | if results[i] != expected[i] { 15 | eq = false 16 | break 17 | } 18 | } 19 | if !eq { 20 | t.Errorf("Averages of subarrays of size K(5): %d, answer is %f, expect is %f", arr, results, expected) 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Pattern02 - Two Pointers/Remove_Duplicates/similar_problem.go: -------------------------------------------------------------------------------- 1 | package Remove_Duplicates 2 | 3 | /* 4 | Given an unsorted array of numbers and a target ‘key’, 5 | remove all instances of ‘key’ in-place and return the new length of the array. 6 | 7 | 8 | Input: [3, 2, 3, 6, 3, 10, 9, 3], Key=3 9 | Output: 4 10 | Explanation: The first four elements after removing every 'Key' will be [2, 6, 10, 9]. 11 | 12 | Input: [2, 11, 2, 2, 1], Key=2 13 | Output: 2 14 | Explanation: The first two elements after removing every 'Key' will be [11, 1]. 15 | */ 16 | 17 | func removeKey(arr []int, targetKey int) int { 18 | lastInd := -1 19 | for i := 0; i < len(arr); i++ { 20 | if arr[i] == targetKey { 21 | continue 22 | } 23 | lastInd++ 24 | arr[lastInd] = arr[i] 25 | } 26 | return lastInd + 1 27 | } 28 | -------------------------------------------------------------------------------- /Pattern13 - Top K Elements/Top_K_Frequent_Numbers/solution_test.go: -------------------------------------------------------------------------------- 1 | package topkfrequentnumbers 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func Test_topKFrequent(t *testing.T) { 8 | type args struct { 9 | nums []int 10 | k int 11 | } 12 | tests := []struct { 13 | name string 14 | args args 15 | want []int 16 | }{ 17 | {"case1", args{[]int{1, 1, 1, 2, 2, 3}, 2}, []int{1, 2}}, 18 | } 19 | for _, tt := range tests { 20 | t.Run(tt.name, func(t *testing.T) { 21 | got := topKFrequent(tt.args.nums, tt.args.k) 22 | m := make(map[int]int) 23 | for _, v := range got { 24 | m[v]++ 25 | } 26 | for _, v := range tt.want { 27 | delete(m, v) 28 | } 29 | if len(m) != 0 { 30 | t.Errorf("topKFrequent() = %v, want %v", got, tt.want) 31 | } 32 | }) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Miscellaneous/max-heap_test.go: -------------------------------------------------------------------------------- 1 | package Miscellaneous 2 | 3 | import "testing" 4 | 5 | func Test_findKthSmallestNumberUsingMaxHeap(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 | {"case1", args{[]int{1, 5, 12, 2, 11, 5}, 3}, 5}, 16 | {"case2", args{[]int{1, 5, 12, 2, 11, 5}, 4}, 5}, 17 | {"case3", args{[]int{5, 12, 11, -1, 12}, 3}, 11}, 18 | {"case4", args{[]int{5, 12, 11, -1, 12}, 6}, -1}, 19 | } 20 | for _, tt := range tests { 21 | t.Run(tt.name, func(t *testing.T) { 22 | if got := findKthSmallestNumberUsingMaxHeap(tt.args.nums, tt.args.k); got != tt.want { 23 | t.Errorf("findKthSmallestNumberUsingMaxHeap() = %v, want %v", got, tt.want) 24 | } 25 | }) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Miscellaneous/min-heap_test.go: -------------------------------------------------------------------------------- 1 | package Miscellaneous 2 | 3 | import "testing" 4 | 5 | func Test_findKthSmallestNumberUsingMinHeap(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 | {"case1", args{[]int{1, 5, 12, 2, 11, 5}, 3}, 5}, 16 | {"case2", args{[]int{1, 5, 12, 2, 11, 5}, 4}, 5}, 17 | {"case3", args{[]int{5, 12, 11, -1, 12}, 3}, 11}, 18 | {"case4", args{[]int{5, 12, 11, -1, 12}, 6}, -1}, 19 | } 20 | for _, tt := range tests { 21 | t.Run(tt.name, func(t *testing.T) { 22 | if got := findKthSmallestNumberUsingMinHeap(tt.args.nums, tt.args.k); got != tt.want { 23 | t.Errorf("findKthSmallestNumberUsingMinHeap() = %v, want %v", got, tt.want) 24 | } 25 | }) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Pattern01 - Sliding Window/Challenge1-Permutation_in_a_String/solution_test.go: -------------------------------------------------------------------------------- 1 | package Challenge1_Permutation_in_a_String 2 | 3 | import "testing" 4 | 5 | func Test_findPermutation(t *testing.T) { 6 | type args struct { 7 | str string 8 | pattern string 9 | } 10 | tests := []struct { 11 | name string 12 | args args 13 | want bool 14 | }{ 15 | {"case1", args{"oidbcaf", "abc"}, true}, 16 | {"case2", args{"odicf", "dc"}, false}, 17 | {"case3", args{"bcdxabcdy", "bcdyabcdx"}, true}, 18 | {"case4", args{"aaacb", "abc"}, true}, 19 | } 20 | for _, tt := range tests { 21 | t.Run(tt.name, func(t *testing.T) { 22 | if got := findPermutation(tt.args.str, tt.args.pattern); got != tt.want { 23 | t.Errorf("findPermutation() = %v, want %v", got, tt.want) 24 | } 25 | }) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Pattern01 - Sliding Window/Smallest_Subarray_with_a_given_sum/solution_test.go: -------------------------------------------------------------------------------- 1 | package Smallest_Subarray_with_a_given_sum 2 | 3 | import "testing" 4 | 5 | func Test_findMinSubArray(t *testing.T) { 6 | type args struct { 7 | S int 8 | arr []int 9 | } 10 | tests := []struct { 11 | name string 12 | args args 13 | want int 14 | }{ 15 | {name: "case1", args: args{7, []int{2, 1, 5, 2, 3, 2}}, want: 2}, 16 | {name: "case2", args: args{7, []int{2, 1, 5, 2, 8}}, want: 1}, 17 | {name: "case3", args: args{8, []int{3, 4, 1, 1, 6}}, want: 3}, 18 | } 19 | for _, tt := range tests { 20 | t.Run(tt.name, func(t *testing.T) { 21 | if got := findMinSubArray(tt.args.S, tt.args.arr); got != tt.want { 22 | t.Errorf("findMinSubArray() = %v, want %v", got, tt.want) 23 | } 24 | }) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Miscellaneous/quick-sort_test.go: -------------------------------------------------------------------------------- 1 | package Miscellaneous 2 | 3 | import "testing" 4 | 5 | func Test_findKthSmallestNumberUsingQuickSort(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 | {"case1", args{[]int{1, 5, 12, 2, 11, 5}, 3}, 5}, 16 | {"case2", args{[]int{1, 5, 12, 2, 11, 5}, 4}, 5}, 17 | {"case3", args{[]int{5, 12, 11, -1, 12}, 3}, 11}, 18 | {"case4", args{[]int{5, 12, 11, -1, 12}, 6}, -1}, 19 | } 20 | for _, tt := range tests { 21 | t.Run(tt.name, func(t *testing.T) { 22 | if got := findKthSmallestNumberUsingQuickSort(tt.args.nums, tt.args.k); got != tt.want { 23 | t.Errorf("findKthSmallestNumberUsingQuickSort() = %v, want %v", got, tt.want) 24 | } 25 | }) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Pattern01 - Sliding Window/Challenge4-Words_Concatenation/solution_test.go: -------------------------------------------------------------------------------- 1 | package Challenge4_Words_Concatenation 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_findWordConcatenation(t *testing.T) { 9 | type args struct { 10 | str string 11 | words []string 12 | } 13 | tests := []struct { 14 | name string 15 | args args 16 | want []int 17 | }{ 18 | {"case1", args{"catfoxcat", []string{"cat", "fox"}}, []int{0, 3}}, 19 | {"case2", args{"catcatfoxfox", []string{"cat", "fox"}}, []int{3}}, 20 | } 21 | for _, tt := range tests { 22 | t.Run(tt.name, func(t *testing.T) { 23 | if got := findWordConcatenation(tt.args.str, tt.args.words); !reflect.DeepEqual(got, tt.want) { 24 | t.Errorf("findWordConcatenation() = %v, want %v", got, tt.want) 25 | } 26 | }) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Pattern10 - Subsets/Subsets/solution.go: -------------------------------------------------------------------------------- 1 | package Subsets 2 | 3 | import "math" 4 | 5 | /* 6 | Given a set with distinct elements, find all of its distinct subsets. 7 | 8 | Input: [1, 3] 9 | Output: [], [1], [3], [1,3] 10 | 11 | Input: [1, 5, 3] 12 | Output: [], [1], [5], [3], [1,5], [1,3], [5,3], [1,5,3] 13 | 14 | ref: https://leetcode-cn.com/problems/Subsets/ 15 | */ 16 | 17 | func subsets(nums []int) [][]int { 18 | var results = make([][]int, int(math.Pow(2, float64(len(nums))))) 19 | results[0] = []int{} 20 | i := 1 21 | for _, currentNum := range nums { 22 | for _, subset := range results[:i] { 23 | newSubset := make([]int, len(subset)+1) 24 | copy(newSubset, subset) 25 | newSubset[len(subset)] = currentNum 26 | results[i] = newSubset 27 | i++ 28 | } 29 | } 30 | 31 | return results 32 | } 33 | -------------------------------------------------------------------------------- /Pattern08 - Tree DFS/Binary_Tree_Path_Sum/solution_test.go: -------------------------------------------------------------------------------- 1 | package Binary_Tree_Path_Sum 2 | 3 | import "testing" 4 | 5 | func Test_hasPathSum(t *testing.T) { 6 | type args struct { 7 | root *TreeNode 8 | targetSum int 9 | } 10 | 11 | head1 := &TreeNode{12, nil, nil} 12 | head1.Left = &TreeNode{7, &TreeNode{Val: 9}, nil} 13 | head1.Right = &TreeNode{1, &TreeNode{Val: 10}, &TreeNode{Val: 5}} 14 | 15 | tests := []struct { 16 | name string 17 | args args 18 | want bool 19 | }{ 20 | {"case1", args{nil, 1}, false}, 21 | {"case2", args{head1, 23}, true}, 22 | } 23 | for _, tt := range tests { 24 | t.Run(tt.name, func(t *testing.T) { 25 | if got := hasPathSum(tt.args.root, tt.args.targetSum); got != tt.want { 26 | t.Errorf("hasPathSum() = %v, want %v", got, tt.want) 27 | } 28 | }) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Pattern16 - Topological Sort/Tasks_Scheduling/solution_test.go: -------------------------------------------------------------------------------- 1 | package Tasks_Scheduling 2 | 3 | import "testing" 4 | 5 | func Test_isSchedulingPossible(t *testing.T) { 6 | type args struct { 7 | tasks int 8 | prerequisites [][]int 9 | } 10 | tests := []struct { 11 | name string 12 | args args 13 | want bool 14 | }{ 15 | {"case1", args{3, [][]int{{0, 1}, {1, 2}}}, true}, 16 | {"case2", args{3, [][]int{{0, 1}, {1, 2}, {2, 0}}}, false}, 17 | {"case3", args{6, [][]int{{2, 5}, {0, 5}, {0, 4}, {1, 4}, {3, 2}, {1, 3}}}, true}, 18 | } 19 | for _, tt := range tests { 20 | t.Run(tt.name, func(t *testing.T) { 21 | if got := isSchedulingPossible(tt.args.tasks, tt.args.prerequisites); got != tt.want { 22 | t.Errorf("isSchedulingPossible() = %v, want %v", got, tt.want) 23 | } 24 | }) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /Pattern07 - Tree BFS/Reverse_Level_Order_Traversal/append_compare_test.go: -------------------------------------------------------------------------------- 1 | package Reverse_Level_Order_Traversal 2 | 3 | import "testing" 4 | 5 | func Test_method2(t *testing.T) { 6 | tests := []struct { 7 | name string 8 | }{ 9 | {"case1"}, 10 | } 11 | for _, tt := range tests { 12 | t.Run(tt.name, func(t *testing.T) { 13 | method1() 14 | }) 15 | } 16 | } 17 | 18 | func Test_methond1(t *testing.T) { 19 | tests := []struct { 20 | name string 21 | }{ 22 | {"case1"}, 23 | } 24 | for _, tt := range tests { 25 | t.Run(tt.name, func(t *testing.T) { 26 | method2() 27 | }) 28 | } 29 | } 30 | 31 | func BenchmarkMethod1(b *testing.B) { 32 | for i := 0; i < b.N; i++ { 33 | method1() 34 | } 35 | } 36 | 37 | func BenchmarkMethod2(b *testing.B) { 38 | for i := 0; i < b.N; i++ { 39 | method2() 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Pattern10 - Subsets/Subsets_with_Duplicates/solution_test.go: -------------------------------------------------------------------------------- 1 | package Subsets_with_Duplicates 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_subsetsWithDup(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 | {"case1", args{[]int{1, 3, 3}}, [][]int{{}, {1}, {3}, {1, 3}, {3, 3}, {1, 3, 3}}}, 18 | {"case2", args{[]int{1, 5, 3, 3}}, [][]int{{}, {1}, {3}, {1, 3}, {3, 3}, {1, 3, 3}, {5}, {1, 5}, {3, 5}, {1, 3, 5}, {3, 3, 5}, {1, 3, 3, 5}}}, 19 | } 20 | for _, tt := range tests { 21 | t.Run(tt.name, func(t *testing.T) { 22 | if got := subsetsWithDup(tt.args.nums); !reflect.DeepEqual(got, tt.want) { 23 | t.Errorf("subsetsWithDup() = %v, want %v", got, tt.want) 24 | } 25 | }) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Pattern11 - Modified Binary Search/Next_Letter/solution_test.go: -------------------------------------------------------------------------------- 1 | package nextletter 2 | 3 | import "testing" 4 | 5 | func Test_nextGreatestLetter(t *testing.T) { 6 | type args struct { 7 | letters []byte 8 | target byte 9 | } 10 | tests := []struct { 11 | name string 12 | args args 13 | want byte 14 | }{ 15 | {"case1", args{[]byte{'a', 'c', 'f', 'h'}, 'f'}, 'h'}, 16 | {"case2", args{[]byte{'a', 'c', 'f', 'h'}, 'b'}, 'c'}, 17 | {"case3", args{[]byte{'a', 'c', 'f', 'h'}, 'm'}, 'a'}, 18 | {"case3", args{[]byte{'a', 'c', 'f', 'h'}, 'h'}, 'a'}, 19 | } 20 | for _, tt := range tests { 21 | t.Run(tt.name, func(t *testing.T) { 22 | if got := nextGreatestLetter(tt.args.letters, tt.args.target); got != tt.want { 23 | t.Errorf("nextGreatestLetter() = %v, want %v", got, tt.want) 24 | } 25 | }) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Pattern12 - Bitwise XOR/Two_Single_Numbers/solution_test.go: -------------------------------------------------------------------------------- 1 | package twosinglenumbers 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func Test_singleNumber(t *testing.T) { 8 | type args struct { 9 | nums []int 10 | } 11 | tests := []struct { 12 | name string 13 | args args 14 | want []int 15 | }{ 16 | {"case1", args{[]int{1, 4, 2, 1, 3, 5, 6, 2, 3, 5}}, []int{4, 6}}, 17 | {"case2", args{[]int{2, 1, 3, 2}}, []int{1, 3}}, 18 | } 19 | for _, tt := range tests { 20 | t.Run(tt.name, func(t *testing.T) { 21 | got := singleNumber(tt.args.nums) 22 | m := make(map[int]int) 23 | for _, v := range got { 24 | m[v] = 1 25 | } 26 | for _, v := range tt.want { 27 | delete(m, v) 28 | } 29 | if len(m) != 0 { 30 | t.Errorf("singleNumber() = %v, want %v", got, tt.want) 31 | } 32 | }) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Pattern03 - Fast and Slow pointers/Middle_of_the_LinkedList/solution.go: -------------------------------------------------------------------------------- 1 | package Middle_of_the_LinkedList 2 | 3 | /* 4 | Given the head of a Singly LinkedList, write a method to return the middle node of the LinkedList. 5 | If the total number of nodes in the LinkedList is even, return the second middle node. 6 | 7 | Input: 1 -> 2 -> 3 -> 4 -> 5 -> null 8 | Output: 3 9 | 10 | Input: 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> null 11 | Output: 4 12 | 13 | Input: 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> null 14 | Output: 4 15 | */ 16 | 17 | type ListNode struct { 18 | Value int 19 | Next *ListNode 20 | } 21 | 22 | func findMiddle(head *ListNode) *ListNode { 23 | var ( 24 | fast = head 25 | slow = head 26 | ) 27 | 28 | for fast != nil && fast.Next != nil { 29 | fast = fast.Next.Next 30 | slow = slow.Next 31 | } 32 | 33 | return slow 34 | } 35 | -------------------------------------------------------------------------------- /Miscellaneous/median-of-medians_test.go: -------------------------------------------------------------------------------- 1 | package Miscellaneous 2 | 3 | import "testing" 4 | 5 | func Test_findKthSmallestNumberUsingMedianOfMedians(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 | {"case1", args{[]int{1, 5, 12, 2, 11, 5}, 3}, 5}, 16 | {"case2", args{[]int{1, 5, 12, 2, 11, 5}, 4}, 5}, 17 | {"case3", args{[]int{5, 12, 11, -1, 12}, 3}, 11}, 18 | {"case4", args{[]int{5, 12, 11, -1, 12}, 6}, -1}, 19 | } 20 | for _, tt := range tests { 21 | t.Run(tt.name, func(t *testing.T) { 22 | if got := findKthSmallestNumberUsingMedianOfMedians(tt.args.nums, tt.args.k); got != tt.want { 23 | t.Errorf("findKthSmallestNumberUsingMedianOfMedians() = %v, want %v", got, tt.want) 24 | } 25 | }) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Pattern03 - Fast and Slow pointers/LinkedList_Cycle/similar_problem.go: -------------------------------------------------------------------------------- 1 | package LinkedList_Cycle 2 | 3 | /* 4 | Given the head of a LinkedList with a cycle, find the length of the cycle. 5 | */ 6 | 7 | func findCycleLength(head *ListNode) int { 8 | var ( 9 | slow = head 10 | fast = head 11 | ) 12 | 13 | for fast != nil && fast.Next != nil { 14 | fast = fast.Next.Next 15 | slow = slow.Next 16 | if slow == fast { 17 | // 计算长度 18 | return calculateCircleLength(slow) 19 | } 20 | } 21 | 22 | return 0 23 | } 24 | 25 | func calculateCircleLength(slow *ListNode) int { 26 | // slow in a circle 27 | var ( 28 | current = slow 29 | length = 0 30 | ) 31 | // first step 32 | current = current.Next 33 | length++ 34 | for current != slow { 35 | current = current.Next 36 | length++ 37 | } 38 | 39 | return length 40 | } 41 | -------------------------------------------------------------------------------- /Pattern04 - Merge Intervals/Challenge2-Maximum_CPU_Load/solution_test.go: -------------------------------------------------------------------------------- 1 | package Challenge2_Maximum_CPU_Load 2 | 3 | import "testing" 4 | 5 | func Test_findMaxCPULoad(t *testing.T) { 6 | type args struct { 7 | jobs []Job 8 | } 9 | tests := []struct { 10 | name string 11 | args args 12 | want int 13 | }{ 14 | {"case1", args{[]Job{{1, 4, 3}, {2, 5, 4}, {7, 9, 6}}}, 7}, 15 | {"case2", args{[]Job{{6, 7, 10}, {2, 4, 11}, {8, 12, 15}}}, 15}, 16 | {"case3", args{[]Job{{1, 4, 2}, {2, 4, 1}, {3, 6, 5}}}, 8}, 17 | {"case4", args{[]Job{}}, 0}, 18 | {"case5", args{[]Job{{1, 4, 3}}}, 3}, 19 | } 20 | for _, tt := range tests { 21 | t.Run(tt.name, func(t *testing.T) { 22 | if got := findMaxCPULoad(tt.args.jobs); got != tt.want { 23 | t.Errorf("findMaxCPULoad() = %v, want %v", got, tt.want) 24 | } 25 | }) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Pattern07 - Tree BFS/Connect_Level_Order_Siblings/solution_test.go: -------------------------------------------------------------------------------- 1 | package Connect_Level_Order_Siblings 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_connect(t *testing.T) { 9 | type args struct { 10 | root *Node 11 | } 12 | 13 | head1 := &Node{Val: 1} 14 | head1.Left = &Node{Val: 2, Left: &Node{Val: 4}, Right: &Node{Val: 5}} 15 | head1.Right = &Node{Val: 3, Left: &Node{Val: 6}, Right: &Node{Val: 7}} 16 | 17 | tests := []struct { 18 | name string 19 | args args 20 | want *Node 21 | }{ 22 | {"case1", args{head1}, head1}, 23 | {"case2", args{nil}, nil}, 24 | } 25 | for _, tt := range tests { 26 | t.Run(tt.name, func(t *testing.T) { 27 | if got := connect(tt.args.root); !reflect.DeepEqual(got, tt.want) { 28 | t.Errorf("connect() = %v, want %v", got, tt.want) 29 | } 30 | }) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Miscellaneous/randomize-quick-sort_test.go: -------------------------------------------------------------------------------- 1 | package Miscellaneous 2 | 3 | import "testing" 4 | 5 | func Test_findKthSmallestNumberUsingRandomQuickSort(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 | {"case1", args{[]int{1, 5, 12, 2, 11, 5}, 3}, 5}, 16 | {"case2", args{[]int{1, 5, 12, 2, 11, 5}, 4}, 5}, 17 | {"case3", args{[]int{5, 12, 11, -1, 12}, 3}, 11}, 18 | {"case4", args{[]int{5, 12, 11, -1, 12}, 6}, -1}, 19 | } 20 | for _, tt := range tests { 21 | t.Run(tt.name, func(t *testing.T) { 22 | if got := findKthSmallestNumberUsingRandomQuickSort(tt.args.nums, tt.args.k); got != tt.want { 23 | t.Errorf("findKthSmallestNumberUsingRandomQuickSort() = %v, want %v", got, tt.want) 24 | } 25 | }) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Pattern13 - Top K Elements/Maximum_Distinct_Elements/solution_test.go: -------------------------------------------------------------------------------- 1 | package maximumdistinctelements 2 | 3 | import "testing" 4 | 5 | func Test_findMaximumDistinctElements(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 | {"case1", args{[]int{7, 3, 5, 8, 5, 3, 3}, 2}, 3}, 16 | {"case2", args{[]int{3, 5, 12, 11, 12}, 3}, 2}, 17 | {"case3", args{[]int{1, 2, 3, 3, 3, 3, 4, 4, 5, 5, 5}, 2}, 3}, 18 | {"case4", args{[]int{12, 3, 4, 4, 4}, 10}, 0}, 19 | } 20 | for _, tt := range tests { 21 | t.Run(tt.name, func(t *testing.T) { 22 | if got := findMaximumDistinctElements(tt.args.nums, tt.args.k); got != tt.want { 23 | t.Errorf("findMaximumDistinctElements() = %v, want %v", got, tt.want) 24 | } 25 | }) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Pattern05 - Cyclic Sort/Challenge3-Find_the_First_K_Missing_Positive_Numbers/solution_test.go: -------------------------------------------------------------------------------- 1 | package Challenge3_Find_the_First_K_Missing_Positive_Numbers 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_findNumbers(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 | {"case1", args{[]int{3, -1, 4, 5, 5}, 3}, []int{1, 2, 6}}, 19 | {"case2", args{[]int{2, 3, 4}, 3}, []int{1, 5, 6}}, 20 | {"case3", args{[]int{-2, -3, 4}, 2}, []int{1, 2}}, 21 | } 22 | for _, tt := range tests { 23 | t.Run(tt.name, func(t *testing.T) { 24 | if got := findNumbers(tt.args.nums, tt.args.k); !reflect.DeepEqual(got, tt.want) { 25 | t.Errorf("findNumbers() = %v, want %v", got, tt.want) 26 | } 27 | }) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Pattern07 - Tree BFS/Minimum_Depth_of_a_Binary_Tree/solution_test.go: -------------------------------------------------------------------------------- 1 | package Minimum_Depth_of_a_Binary_Tree 2 | 3 | import "testing" 4 | 5 | func Test_minDepth(t *testing.T) { 6 | type args struct { 7 | root *TreeNode 8 | } 9 | 10 | head1 := &TreeNode{Val: 3} 11 | head1.Left = &TreeNode{Val: 9} 12 | head1.Right = &TreeNode{Val: 20, Left: &TreeNode{Val: 15}, Right: &TreeNode{Val: 7}} 13 | 14 | head2 := &TreeNode{Val: 1} 15 | head2.Left = &TreeNode{Val: 2} 16 | 17 | tests := []struct { 18 | name string 19 | args args 20 | want int 21 | }{ 22 | {"case1", args{head1}, 2}, 23 | {"case2", args{nil}, 0}, 24 | } 25 | for _, tt := range tests { 26 | t.Run(tt.name, func(t *testing.T) { 27 | if got := minDepth(tt.args.root); got != tt.want { 28 | t.Errorf("minDepth() = %v, want %v", got, tt.want) 29 | } 30 | }) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Pattern02 - Two Pointers/Subarrays_with_Product_Less_than_a_Target/solution_test.go: -------------------------------------------------------------------------------- 1 | package Subarrays_with_Product_Less_than_a_Target 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_findSubarrays(t *testing.T) { 9 | type args struct { 10 | arr []int 11 | target int 12 | } 13 | tests := []struct { 14 | name string 15 | args args 16 | want [][]int 17 | }{ 18 | {"case1", args{[]int{2, 5, 3, 10}, 30}, [][]int{{2}, {5}, {2, 5}, {3}, {5, 3}, {10}}}, 19 | {"case2", args{[]int{8, 2, 6, 5}, 50}, [][]int{{8}, {2}, {8, 2}, {6}, {2, 6}, {5}, {6, 5}}}, 20 | } 21 | for _, tt := range tests { 22 | t.Run(tt.name, func(t *testing.T) { 23 | if got := findSubarrays(tt.args.arr, tt.args.target); !reflect.DeepEqual(got, tt.want) { 24 | t.Errorf("findSubarrays() = %v, want %v", got, tt.want) 25 | } 26 | }) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Pattern02 - Two Pointers/Pair_with_Target_Sum/solution_test.go: -------------------------------------------------------------------------------- 1 | package Pair_with_Target_Sum 2 | 3 | import "testing" 4 | 5 | func Test_search(t *testing.T) { 6 | type args struct { 7 | arr []int 8 | targetSum int 9 | } 10 | tests := []struct { 11 | name string 12 | args args 13 | want int 14 | want1 int 15 | }{ 16 | {"case1", args{[]int{1, 2, 3, 4, 6}, 6}, 1, 3}, 17 | {"case2", args{[]int{2, 5, 9, 11}, 11}, 0, 2}, 18 | {"case3", args{[]int{2, 5, 9, 11}, 10}, -1, -1}, 19 | } 20 | for _, tt := range tests { 21 | t.Run(tt.name, func(t *testing.T) { 22 | got, got1 := search(tt.args.arr, tt.args.targetSum) 23 | if got != tt.want { 24 | t.Errorf("search() got = %v, want %v", got, tt.want) 25 | } 26 | if got1 != tt.want1 { 27 | t.Errorf("search() got1 = %v, want %v", got1, tt.want1) 28 | } 29 | }) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Pattern07 - Tree BFS/Zigzag_Traversal/solution_test.go: -------------------------------------------------------------------------------- 1 | package Zigzag_Traversal 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_zigzagLevelOrder(t *testing.T) { 9 | type args struct { 10 | root *TreeNode 11 | } 12 | 13 | head1 := &TreeNode{Val: 3} 14 | head1.Left = &TreeNode{Val: 9} 15 | head1.Right = &TreeNode{Val: 20, Left: &TreeNode{Val: 15}, Right: &TreeNode{Val: 7}} 16 | 17 | tests := []struct { 18 | name string 19 | args args 20 | want [][]int 21 | }{ 22 | {"case1", args{head1}, [][]int{{3}, {20, 9}, {15, 7}}}, 23 | {"case2", args{nil}, [][]int{}}, 24 | } 25 | for _, tt := range tests { 26 | t.Run(tt.name, func(t *testing.T) { 27 | if got := zigzagLevelOrder(tt.args.root); !reflect.DeepEqual(got, tt.want) { 28 | t.Errorf("zigzagLevelOrder() = %v, want %v", got, tt.want) 29 | } 30 | }) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Pattern08 - Tree DFS/Count_Paths_for_a_Sum/solution_test.go: -------------------------------------------------------------------------------- 1 | package Count_Paths_for_a_Sum 2 | 3 | import "testing" 4 | 5 | func Test_pathSum(t *testing.T) { 6 | type args struct { 7 | root *TreeNode 8 | targetSum int 9 | } 10 | 11 | head1 := &TreeNode{10, nil, nil} 12 | head1.Left = &TreeNode{5, &TreeNode{3, &TreeNode{Val: 3}, &TreeNode{Val: -2}}, &TreeNode{2, nil, &TreeNode{Val: 1}}} 13 | head1.Right = &TreeNode{-3, nil, &TreeNode{Val: 11}} 14 | 15 | tests := []struct { 16 | name string 17 | args args 18 | want int 19 | }{ 20 | {"case1", args{head1, 8}, 3}, 21 | {"case2", args{nil, 8}, 0}, 22 | } 23 | for _, tt := range tests { 24 | t.Run(tt.name, func(t *testing.T) { 25 | if got := pathSum(tt.args.root, tt.args.targetSum); got != tt.want { 26 | t.Errorf("pathSum() = %v, want %v", got, tt.want) 27 | } 28 | }) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Pattern11 - Modified Binary Search/Challenge1-Search_Bitonic_Array/solution_test.go: -------------------------------------------------------------------------------- 1 | package challenge1searchbitonicarray 2 | 3 | import "testing" 4 | 5 | func Test_search(t *testing.T) { 6 | type args struct { 7 | arr []int 8 | key int 9 | } 10 | tests := []struct { 11 | name string 12 | args args 13 | want int 14 | }{ 15 | {"case1", args{[]int{1, 3, 8, 4, 3}, 4}, 3}, 16 | {"case2", args{[]int{3, 8, 3, 1}, 8}, 1}, 17 | {"case3", args{[]int{1, 3, 8, 12}, 12}, 3}, 18 | {"case4", args{[]int{10, 9, 8}, 10}, 0}, 19 | {"case5", args{[]int{10, 9, 8}, 7}, -1}, 20 | {"case6", args{[]int{1, 3, 8, 12}, 1}, 0}, 21 | } 22 | for _, tt := range tests { 23 | t.Run(tt.name, func(t *testing.T) { 24 | if got := search(tt.args.arr, tt.args.key); got != tt.want { 25 | t.Errorf("search() = %v, want %v", got, tt.want) 26 | } 27 | }) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Pattern13 - Top K Elements/Top_K_Numbers/solution_test.go: -------------------------------------------------------------------------------- 1 | package topknumbers 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func Test_getLeastNumbers(t *testing.T) { 8 | type args struct { 9 | nums []int 10 | k int 11 | } 12 | tests := []struct { 13 | name string 14 | args args 15 | want []int 16 | }{ 17 | {"case1", args{[]int{3, 1, 5, 12, 2, 11}, 3}, []int{5, 12, 11}}, 18 | {"case2", args{[]int{5, 12, 11, -1, 12}, 3}, []int{12, 11, 12}}, 19 | } 20 | for _, tt := range tests { 21 | t.Run(tt.name, func(t *testing.T) { 22 | got := getLargestNumbers(tt.args.nums, tt.args.k) 23 | m := make(map[int]int) 24 | for _, v := range got { 25 | m[v] = v 26 | } 27 | for _, v := range tt.want { 28 | delete(m, v) 29 | } 30 | if len(m) != 0 { 31 | t.Errorf("topKFrequent() = %v, want %v", got, tt.want) 32 | } 33 | }) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Pattern02 - Two Pointers/Remove_Duplicates/solution.go: -------------------------------------------------------------------------------- 1 | package Remove_Duplicates 2 | 3 | /* 4 | Given an array of sorted numbers, remove all duplicates from it. 5 | You should not use any extra space; after removing the duplicates in-place return the length of the subarray 6 | that has no duplicate in it. 7 | 8 | 9 | Input: [2, 3, 3, 3, 6, 9, 9] 10 | Output: 4 11 | Explanation: The first four elements after removing the duplicates will be [2, 3, 6, 9]. 12 | 13 | 14 | Input: [2, 2, 2, 11] 15 | Output: 2 16 | Explanation: The first two elements after removing the duplicates will be [2, 11]. 17 | */ 18 | 19 | func remove(arr []int) int { 20 | // 因为有序,所以重复数字是连着的 21 | newInd := 0 22 | for curInd := 1; curInd < len(arr); curInd++ { 23 | if arr[curInd] == arr[newInd] { 24 | continue 25 | } 26 | newInd++ 27 | arr[newInd] = arr[curInd] 28 | } 29 | return newInd + 1 30 | } 31 | -------------------------------------------------------------------------------- /Pattern09 - Two Heaps/Challenge1-Next_Interval/solution_test.go: -------------------------------------------------------------------------------- 1 | package Challenge1_Next_Interval 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_findRightInterval(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 | {"case1", args{[][]int{{1, 3}, {2, 4}, {4, 5}}}, []int{2, 2, -1}}, 18 | {"case2", args{[][]int{{2, 3}, {3, 4}, {5, 6}}}, []int{1, 2, -1}}, 19 | {"case3", args{[][]int{{3, 4}, {1, 5}, {4, 6}}}, []int{2, -1, -1}}, 20 | {"case4", args{[][]int{}}, []int{}}, 21 | } 22 | for _, tt := range tests { 23 | t.Run(tt.name, func(t *testing.T) { 24 | if got := findRightInterval(tt.args.intervals); !reflect.DeepEqual(got, tt.want) { 25 | t.Errorf("findRightInterval() = %v, want %v", got, tt.want) 26 | } 27 | }) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Pattern05 - Cyclic Sort/Find_all_Duplicate_Number/solution.go: -------------------------------------------------------------------------------- 1 | package Find_all_Duplicate_Number 2 | 3 | /* 4 | We are given an unsorted array containing ‘n’ numbers taken from the range 1 to ‘n’. 5 | The array has some numbers appearing twice, 6 | find all these duplicate numbers without using any extra space. 7 | 8 | Input: [3, 4, 4, 5, 5] 9 | Output: [4, 5] 10 | 11 | Input: [5, 4, 7, 2, 3, 5, 3] 12 | Output: [3, 5] 13 | */ 14 | 15 | func findAllDuplicateNumbers(nums []int) []int { 16 | var i = 0 17 | var duplicated = make([]int, 0, len(nums)) 18 | for i < len(nums) { 19 | j := nums[i] - 1 20 | if nums[i] != nums[j] { 21 | nums[i], nums[j] = nums[j], nums[i] 22 | } else { 23 | i++ 24 | } 25 | } 26 | 27 | for i = 0; i < len(nums); i++ { 28 | if nums[i] != i+1 { 29 | duplicated = append(duplicated, nums[i]) 30 | } 31 | } 32 | 33 | return duplicated 34 | } 35 | -------------------------------------------------------------------------------- /Pattern07 - Tree BFS/Level_Averages_in_a_Binary_Tree/solution_test.go: -------------------------------------------------------------------------------- 1 | package Level_Averages_in_a_Binary_Tree 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_averageOfLevels(t *testing.T) { 9 | type args struct { 10 | root *TreeNode 11 | } 12 | 13 | head1 := &TreeNode{Val: 3} 14 | head1.Left = &TreeNode{Val: 9} 15 | head1.Right = &TreeNode{Val: 20, Left: &TreeNode{Val: 15}, Right: &TreeNode{Val: 7}} 16 | 17 | tests := []struct { 18 | name string 19 | args args 20 | want []float64 21 | }{ 22 | {"case1", args{head1}, []float64{3, 14.5, 11}}, 23 | {"case2", args{nil}, []float64{}}, 24 | } 25 | for _, tt := range tests { 26 | t.Run(tt.name, func(t *testing.T) { 27 | if got := averageOfLevels(tt.args.root); !reflect.DeepEqual(got, tt.want) { 28 | t.Errorf("averageOfLevels() = %v, want %v", got, tt.want) 29 | } 30 | }) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Pattern11 - Modified Binary Search/Order-agnostic_Binary_Search/solution_test.go: -------------------------------------------------------------------------------- 1 | package orderagnosticbinarysearch 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func Test_search(t *testing.T) { 8 | type args struct { 9 | arr []int 10 | key int 11 | } 12 | 13 | tests := []struct { 14 | name string 15 | args args 16 | want int 17 | }{ 18 | {"case1", args{[]int{4, 6, 10}, 10}, 2}, 19 | {"case2", args{[]int{1, 2, 3, 4, 5, 6, 7}, 5}, 4}, 20 | {"case3", args{[]int{10, 6, 4}, 10}, 0}, 21 | {"case4", args{[]int{10, 6, 4}, 4}, 2}, 22 | {"case5", args{[]int{4}, 4}, 0}, 23 | {"case6", args{[]int{10, 6, 4}, 3}, -1}, 24 | } 25 | 26 | for _, tt := range tests { 27 | t.Run(tt.name, func(t *testing.T) { 28 | got := search(tt.args.arr, tt.args.key) 29 | if got != tt.want { 30 | t.Errorf("search() = %v, want %v\n", got, tt.want) 31 | } 32 | }) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Pattern16 - Topological Sort/Tasks_Scheduling_Order/solution_test.go: -------------------------------------------------------------------------------- 1 | package Tasks_Scheduling_Order 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_findOrder(t *testing.T) { 9 | type args struct { 10 | tasks int 11 | prerequisites [][]int 12 | } 13 | tests := []struct { 14 | name string 15 | args args 16 | want []int 17 | }{ 18 | {"case1", args{3, [][]int{{0, 1}, {1, 2}}}, []int{0, 1, 2}}, 19 | {"case2", args{3, [][]int{{0, 1}, {1, 2}, {2, 0}}}, []int{}}, 20 | {"case3", args{6, [][]int{{2, 5}, {0, 5}, {0, 4}, {1, 4}, {3, 2}, {1, 3}}}, []int{0, 1, 4, 3, 2, 5}}, 21 | } 22 | for _, tt := range tests { 23 | t.Run(tt.name, func(t *testing.T) { 24 | if got := findOrder(tt.args.tasks, tt.args.prerequisites); !reflect.DeepEqual(got, tt.want) { 25 | t.Errorf("findOrder() = %v, want %v", got, tt.want) 26 | } 27 | }) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Pattern02 - Two Pointers/Challenge2-Comparing_Strings_containing_Backspaces/solution_test.go: -------------------------------------------------------------------------------- 1 | package Challenge2_Comparing_Strings_containing_Backspaces 2 | 3 | import "testing" 4 | 5 | func Test_compare(t *testing.T) { 6 | type args struct { 7 | str1 string 8 | str2 string 9 | } 10 | tests := []struct { 11 | name string 12 | args args 13 | want bool 14 | }{ 15 | {"case1", args{"xy#z", "xzz#"}, true}, 16 | {"case2", args{"xy#z", "xyz#"}, false}, 17 | {"case3", args{"xp#", "xyz##"}, true}, 18 | {"case4", args{"xywrrmp", "xywrrmu#p"}, true}, 19 | {"case5", args{"xy##z", "z"}, true}, 20 | {"case5", args{"xy##z", "z#"}, false}, 21 | } 22 | for _, tt := range tests { 23 | t.Run(tt.name, func(t *testing.T) { 24 | if got := compare(tt.args.str1, tt.args.str2); got != tt.want { 25 | t.Errorf("compare() = %v, want %v", got, tt.want) 26 | } 27 | }) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Pattern04 - Merge Intervals/Merge_Intervals/solution_test.go: -------------------------------------------------------------------------------- 1 | package Merge_Intervals 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_merge(t *testing.T) { 9 | type args struct { 10 | intervals []Interval 11 | } 12 | tests := []struct { 13 | name string 14 | args args 15 | want []Interval 16 | }{ 17 | {"case1", args{[]Interval{{1, 4}, {2, 5}, {7, 9}}}, []Interval{{1, 5}, {7, 9}}}, 18 | {"case2", args{[]Interval{{6, 7}, {2, 4}, {5, 9}}}, []Interval{{2, 4}, {5, 9}}}, 19 | {"case3", args{[]Interval{{1, 4}, {2, 6}, {3, 5}}}, []Interval{{1, 6}}}, 20 | {"case4", args{[]Interval{{1, 4}}}, []Interval{{1, 4}}}, 21 | } 22 | for _, tt := range tests { 23 | t.Run(tt.name, func(t *testing.T) { 24 | if got := merge(tt.args.intervals); !reflect.DeepEqual(got, tt.want) { 25 | t.Errorf("merge() = %v, want %v", got, tt.want) 26 | } 27 | }) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Pattern12 - Bitwise XOR/Challenge1/solution_test.go: -------------------------------------------------------------------------------- 1 | package challenge1 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_flipAndInvertImage(t *testing.T) { 9 | type args struct { 10 | image [][]int 11 | } 12 | tests := []struct { 13 | name string 14 | args args 15 | want [][]int 16 | }{ 17 | {"case1", args{[][]int{}}, [][]int{}}, 18 | {"case2", args{[][]int{{1, 0, 1}, {1, 1, 1}, {0, 1, 1}}}, [][]int{{0, 1, 0}, {0, 0, 0}, {0, 0, 1}}}, 19 | {"case3", args{[][]int{{1, 1, 0, 0}, {1, 0, 0, 1}, {0, 1, 1, 1}, {1, 0, 1, 0}}}, [][]int{{1, 1, 0, 0}, {0, 1, 1, 0}, {0, 0, 0, 1}, {1, 0, 1, 0}}}, 20 | } 21 | for _, tt := range tests { 22 | t.Run(tt.name, func(t *testing.T) { 23 | if got := flipAndInvertImage(tt.args.image); !reflect.DeepEqual(got, tt.want) { 24 | t.Errorf("flipAndInvertImage() = %v, want %v", got, tt.want) 25 | } 26 | }) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Pattern04 - Merge Intervals/Challenge1-Minimum_Meeting_Room/solution_test.go: -------------------------------------------------------------------------------- 1 | package Challenge1_Minimum_Meeting_Room 2 | 3 | import "testing" 4 | 5 | func Test_findMinimumMeetingRooms(t *testing.T) { 6 | type args struct { 7 | meetings []Meeting 8 | } 9 | tests := []struct { 10 | name string 11 | args args 12 | want int 13 | }{ 14 | {"case1", args{[]Meeting{{1, 4}, {2, 5}, {7, 9}}}, 2}, 15 | {"case2", args{[]Meeting{{6, 7}, {2, 4}, {8, 12}}}, 1}, 16 | {"case3", args{[]Meeting{{1, 4}, {2, 3}, {3, 6}}}, 2}, 17 | {"case4", args{[]Meeting{{4, 5}, {2, 3}, {2, 4}, {3, 5}}}, 2}, 18 | {"case5", args{[]Meeting{}}, 0}, 19 | } 20 | for _, tt := range tests { 21 | t.Run(tt.name, func(t *testing.T) { 22 | if got := findMinimumMeetingRooms(tt.args.meetings); got != tt.want { 23 | t.Errorf("findMinimumMeetingRooms() = %v, want %v", got, tt.want) 24 | } 25 | }) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Pattern12 - Bitwise XOR/Two_Single_Numbers/solution.go: -------------------------------------------------------------------------------- 1 | package twosinglenumbers 2 | 3 | /* 4 | In a non-empty array of numbers, every number appears exactly twice except two numbers that appear only once. 5 | Find the two numbers that appear only once. 6 | 7 | Input: [1, 4, 2, 1, 3, 5, 6, 2, 3, 5] 8 | Output: [4, 6] 9 | 10 | Input: [2, 1, 3, 2] 11 | Output: [1, 3] 12 | 13 | ref: https://leetcode-cn.com/problems/single-number-iii/ 14 | */ 15 | 16 | func singleNumber(nums []int) []int { 17 | n1xn2 := 0 18 | for _, v := range nums { 19 | n1xn2 ^= v 20 | } 21 | 22 | rightMostSetBit := 1 23 | for rightMostSetBit&n1xn2 == 0 { 24 | rightMostSetBit = rightMostSetBit << 1 25 | } 26 | 27 | num1 := 0 28 | num2 := 0 29 | for _, v := range nums { 30 | if v&rightMostSetBit != 0 { 31 | num1 ^= v 32 | } else { 33 | num2 ^= v 34 | } 35 | } 36 | 37 | return []int{num1, num2} 38 | } 39 | -------------------------------------------------------------------------------- /Pattern08 - Tree DFS/Path_With_Given_Sequence/solution_test.go: -------------------------------------------------------------------------------- 1 | package Path_With_Given_Sequence 2 | 3 | import "testing" 4 | 5 | func Test_isValidSequence(t *testing.T) { 6 | type args struct { 7 | root *TreeNode 8 | arr []int 9 | } 10 | 11 | head1 := &TreeNode{1, nil, nil} 12 | head1.Left = &TreeNode{7, nil, nil} 13 | head1.Right = &TreeNode{9, &TreeNode{Val: 2}, &TreeNode{Val: 9}} 14 | 15 | tests := []struct { 16 | name string 17 | args args 18 | want bool 19 | }{ 20 | {"case1", args{head1, []int{1, 9, 9}}, true}, 21 | {"case2", args{head1, []int{1, 9, 9, 0}}, false}, 22 | {"case3", args{nil, []int{1, 9, 9}}, false}, 23 | } 24 | for _, tt := range tests { 25 | t.Run(tt.name, func(t *testing.T) { 26 | if got := isValidSequence(tt.args.root, tt.args.arr); got != tt.want { 27 | t.Errorf("isValidSequence() = %v, want %v", got, tt.want) 28 | } 29 | }) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Pattern11 - Modified Binary Search/Minimum_Difference_Element/solution_test.go: -------------------------------------------------------------------------------- 1 | package minimumdifferenceelement 2 | 3 | import "testing" 4 | 5 | func Test_searchMinDiffElement(t *testing.T) { 6 | type args struct { 7 | arr []int 8 | key int 9 | } 10 | tests := []struct { 11 | name string 12 | args args 13 | want int 14 | }{ 15 | {"case1", args{[]int{4, 6, 10}, 7}, 6}, 16 | {"case2", args{[]int{4, 6, 10}, 4}, 4}, 17 | {"case3", args{[]int{1, 3, 8, 10, 15}, 12}, 10}, 18 | {"case4", args{[]int{4, 6, 10}, 17}, 10}, 19 | {"case5", args{[]int{4, 6, 10}, 3}, 4}, 20 | {"case6", args{[]int{1, 3, 8, 10, 15}, 13}, 15}, 21 | } 22 | for _, tt := range tests { 23 | t.Run(tt.name, func(t *testing.T) { 24 | if got := searchMinDiffElement(tt.args.arr, tt.args.key); got != tt.want { 25 | t.Errorf("searchMinDiffElement() = %v, want %v", got, tt.want) 26 | } 27 | }) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Pattern02 - Two Pointers/Pair_with_Target_Sum/solution_hashmap_test.go: -------------------------------------------------------------------------------- 1 | package Pair_with_Target_Sum 2 | 3 | import "testing" 4 | 5 | func Test_searchByHashMap(t *testing.T) { 6 | type args struct { 7 | arr []int 8 | targetSum int 9 | } 10 | tests := []struct { 11 | name string 12 | args args 13 | want int 14 | want1 int 15 | }{ 16 | {"case1", args{[]int{1, 2, 3, 4, 6}, 6}, 1, 3}, 17 | {"case2", args{[]int{2, 5, 9, 11}, 11}, 0, 2}, 18 | {"case3", args{[]int{2, 5, 9, 11}, 10}, -1, -1}, 19 | } 20 | for _, tt := range tests { 21 | t.Run(tt.name, func(t *testing.T) { 22 | got, got1 := searchByHashMap(tt.args.arr, tt.args.targetSum) 23 | if got != tt.want { 24 | t.Errorf("searchByHashMap() got = %v, want %v", got, tt.want) 25 | } 26 | if got1 != tt.want1 { 27 | t.Errorf("searchByHashMap() got1 = %v, want %v", got1, tt.want1) 28 | } 29 | }) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Pattern06 - Reversal of a LinkedList/Challenge2-Rotate_a_LinkedList/solution.go: -------------------------------------------------------------------------------- 1 | package Challenge2_Rotate_a_LinkedList 2 | 3 | /* 4 | Given the head of a Singly LinkedList and a number ‘k’, rotate the LinkedList to the right by ‘k’ nodes. 5 | */ 6 | 7 | type ListNode struct { 8 | Value int 9 | Next *ListNode 10 | } 11 | 12 | func rotate(head *ListNode, k int) *ListNode { 13 | // 2N -> O(N) 14 | if head == nil || head.Next == nil || k <= 0 { 15 | return head 16 | } 17 | 18 | var ( 19 | lastNode = head 20 | length = 1 21 | ) 22 | 23 | for lastNode.Next != nil { 24 | length++ 25 | lastNode = lastNode.Next 26 | } 27 | lastNode.Next = head 28 | 29 | k = length - (k % length) 30 | lastNodeOfTail := head 31 | for i := 0; i < k-1; i++ { 32 | lastNodeOfTail = lastNodeOfTail.Next 33 | } 34 | 35 | head = lastNodeOfTail.Next 36 | lastNodeOfTail.Next = nil 37 | 38 | return head 39 | } 40 | -------------------------------------------------------------------------------- /Pattern07 - Tree BFS/Challenge2-Right_View_of_a_Binary_Tree/solution_test.go: -------------------------------------------------------------------------------- 1 | package Challenge2_Right_View_of_a_Binary_Tree 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_rightSideView(t *testing.T) { 9 | type args struct { 10 | root *TreeNode 11 | } 12 | 13 | head1 := &TreeNode{12, nil, nil} 14 | head1.Left = &TreeNode{7, &TreeNode{9, &TreeNode{Val: 3}, nil}, nil} 15 | head1.Right = &TreeNode{1, &TreeNode{Val: 10}, &TreeNode{Val: 5}} 16 | 17 | tests := []struct { 18 | name string 19 | args args 20 | want []int 21 | }{ 22 | {"case1", args{nil}, []int{}}, 23 | {"case2", args{head1}, []int{12, 1, 5, 3}}, 24 | } 25 | for _, tt := range tests { 26 | t.Run(tt.name, func(t *testing.T) { 27 | if got := rightSideView(tt.args.root); !reflect.DeepEqual(got, tt.want) { 28 | t.Errorf("rightSideView() = %v, want %v", got, tt.want) 29 | } 30 | }) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Pattern07 - Tree BFS/Binary_Tree_Level_Order_Traversal/solution_test.go: -------------------------------------------------------------------------------- 1 | package Binary_Tree_Level_Order_Traversal 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_levelOrder(t *testing.T) { 9 | type args struct { 10 | head *TreeNode 11 | } 12 | 13 | var head1 *TreeNode 14 | 15 | head2 := &TreeNode{Val: 3} 16 | head2.Left = &TreeNode{Val: 9} 17 | head2.Right = &TreeNode{Val: 20, Left: &TreeNode{Val: 15}, Right: &TreeNode{Val: 7}} 18 | 19 | tests := []struct { 20 | name string 21 | args args 22 | want [][]int 23 | }{ 24 | {"case1", args{head1}, [][]int{}}, 25 | {"case2", args{head2}, [][]int{{3}, {9, 20}, {15, 7}}}, 26 | } 27 | for _, tt := range tests { 28 | t.Run(tt.name, func(t *testing.T) { 29 | if got := levelOrder(tt.args.head); !reflect.DeepEqual(got, tt.want) { 30 | t.Errorf("levelOrder() = %v, want %v", got, tt.want) 31 | } 32 | }) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Pattern07 - Tree BFS/Reverse_Level_Order_Traversal/solution_test.go: -------------------------------------------------------------------------------- 1 | package Reverse_Level_Order_Traversal 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_levelOrderBottom(t *testing.T) { 9 | type args struct { 10 | root *TreeNode 11 | } 12 | 13 | var head1 *TreeNode 14 | 15 | head2 := &TreeNode{Val: 3} 16 | head2.Left = &TreeNode{Val: 9} 17 | head2.Right = &TreeNode{Val: 20, Left: &TreeNode{Val: 15}, Right: &TreeNode{Val: 7}} 18 | 19 | tests := []struct { 20 | name string 21 | args args 22 | want [][]int 23 | }{ 24 | {"case1", args{head1}, [][]int{}}, 25 | {"case2", args{head2}, [][]int{{15, 7}, {9, 20}, {3}}}, 26 | } 27 | for _, tt := range tests { 28 | t.Run(tt.name, func(t *testing.T) { 29 | if got := levelOrderBottom(tt.args.root); !reflect.DeepEqual(got, tt.want) { 30 | t.Errorf("levelOrderBottom() = %v, want %v", got, tt.want) 31 | } 32 | }) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Pattern06 - Reversal of a LinkedList/Reverse_a_Sublist/solution_test.go: -------------------------------------------------------------------------------- 1 | package Reverse_a_Sublist 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_reverseBetween(t *testing.T) { 9 | type args struct { 10 | head *ListNode 11 | left int 12 | right int 13 | } 14 | 15 | head := &ListNode{Val: 1} 16 | head.Next = &ListNode{Val: 2} 17 | head.Next.Next = &ListNode{Val: 3} 18 | head.Next.Next.Next = &ListNode{Val: 4} 19 | head.Next.Next.Next.Next = &ListNode{Val: 5} 20 | 21 | tests := []struct { 22 | name string 23 | args args 24 | want *ListNode 25 | }{ 26 | {"case1", args{head, 2, 4}, head}, 27 | } 28 | for _, tt := range tests { 29 | t.Run(tt.name, func(t *testing.T) { 30 | if got := reverseBetween(tt.args.head, tt.args.left, tt.args.right); !reflect.DeepEqual(got, tt.want) { 31 | t.Errorf("reverseBetween() = %v, want %v", got, tt.want) 32 | } 33 | }) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Pattern06 - Reversal of a LinkedList/Reverse_every_K-elements_Sublist/solution_test.go: -------------------------------------------------------------------------------- 1 | package Reverse_every_K_elements_Sublist 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_reverse(t *testing.T) { 9 | type args struct { 10 | head *ListNode 11 | k int 12 | } 13 | 14 | head1 := &ListNode{Value: 1} 15 | head1.Next = &ListNode{Value: 2} 16 | node3 := &ListNode{Value: 3} 17 | head1.Next.Next = node3 18 | head1.Next.Next.Next = &ListNode{Value: 4} 19 | head1.Next.Next.Next.Next = &ListNode{Value: 5} 20 | 21 | tests := []struct { 22 | name string 23 | args args 24 | want *ListNode 25 | }{ 26 | {"case1", args{head1, 3}, node3}, 27 | } 28 | for _, tt := range tests { 29 | t.Run(tt.name, func(t *testing.T) { 30 | if got := reverse(tt.args.head, tt.args.k); !reflect.DeepEqual(got, tt.want) { 31 | t.Errorf("reverse() = %v, want %v", got, tt.want) 32 | } 33 | }) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Pattern09 - Two Heaps/Maximize_Capital/solution_test.go: -------------------------------------------------------------------------------- 1 | package Maximize_Capital 2 | 3 | import "testing" 4 | 5 | func Test_findMaximizedCapital(t *testing.T) { 6 | type args struct { 7 | k int 8 | w int 9 | profits []int 10 | capital []int 11 | } 12 | tests := []struct { 13 | name string 14 | args args 15 | want int 16 | }{ 17 | {"case1", args{ 18 | k: 10, 19 | w: 0, 20 | profits: []int{1, 2, 3}, 21 | capital: []int{0, 1, 2}, 22 | }, 6}, 23 | {"case2", args{ 24 | k: 2, 25 | w: 0, 26 | profits: []int{1, 2, 3}, 27 | capital: []int{0, 1, 1}, 28 | }, 4}, 29 | } 30 | for _, tt := range tests { 31 | t.Run(tt.name, func(t *testing.T) { 32 | if got := findMaximizedCapital(tt.args.k, tt.args.w, tt.args.profits, tt.args.capital); got != tt.want { 33 | t.Errorf("findMaximizedCapital() = %v, want %v", got, tt.want) 34 | } 35 | }) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Pattern11 - Modified Binary Search/Search_in_a_Sorted_Infinite_Array/solution_test.go: -------------------------------------------------------------------------------- 1 | package searchinasortedinfinitearray 2 | 3 | import "testing" 4 | 5 | func Test_search(t *testing.T) { 6 | type args struct { 7 | reader ArrayReader 8 | target int 9 | } 10 | tests := []struct { 11 | name string 12 | args args 13 | want int 14 | }{ 15 | {"case1", args{ArrayReader{[]int{4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30}}, 16}, 6}, 16 | {"case2", args{ArrayReader{[]int{4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30}}, 11}, -1}, 17 | {"case3", args{ArrayReader{[]int{1, 3, 8, 10, 15}}, 15}, 4}, 18 | {"case4", args{ArrayReader{[]int{1, 3, 8, 10, 15}}, 200}, -1}, 19 | } 20 | for _, tt := range tests { 21 | t.Run(tt.name, func(t *testing.T) { 22 | if got := search(tt.args.reader, tt.args.target); got != tt.want { 23 | t.Errorf("search() = %v, want %v", got, tt.want) 24 | } 25 | }) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Pattern12 - Bitwise XOR/introduction/solution.go: -------------------------------------------------------------------------------- 1 | package introduction 2 | 3 | /* 4 | Given an array of n-1n−1 integers in the range from 11 to nn, find the one number that is missing from the array. 5 | 6 | Input: 1, 5, 2, 6, 4 7 | Answer: 3 8 | 9 | Following are some important properties of XOR to remember: 10 | 11 | Taking XOR of a number with itself returns 0, e.g., 12 | 13 | 1 ^ 1 = 0 14 | 29 ^ 29 = 0 15 | Taking XOR of a number with 0 returns the same number, e.g., 16 | 17 | 1 ^ 0 = 1 18 | 31 ^ 0 = 31 19 | XOR is Associative & Commutative, which means: 20 | 21 | (a ^ b) ^ c = a ^ (b ^ c) 22 | a ^ b = b ^ a 23 | 24 | ref: https://leetcode-cn.com/problems/missing-number 25 | */ 26 | 27 | func missingNumber(nums []int) int { 28 | n := len(nums) + 1 29 | x1 := 1 30 | for i := 2; i <= n; i++ { 31 | x1 ^= i 32 | } 33 | x2 := nums[0] 34 | for i := 1; i < len(nums); i++ { 35 | x2 ^= nums[i] 36 | } 37 | return x1 ^ x2 38 | } 39 | -------------------------------------------------------------------------------- /Pattern16 - Topological Sort/Topological_Sort/solution_test.go: -------------------------------------------------------------------------------- 1 | package Topological_Sort 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_topologicSort(t *testing.T) { 9 | type args struct { 10 | vertices int 11 | edges [][]int 12 | } 13 | tests := []struct { 14 | name string 15 | args args 16 | want []int 17 | }{ 18 | {"case1", args{4, [][]int{{3, 2}, {3, 0}, {2, 0}, {2, 1}}}, []int{3, 2, 0, 1}}, 19 | {"case2", args{0, [][]int{}}, []int{}}, 20 | {"case3", args{5, [][]int{{4, 2}, {4, 3}, {2, 0}, {2, 1}, {3, 1}}}, []int{4, 2, 3, 0, 1}}, 21 | {"case4", args{5, [][]int{{4, 2}, {4, 3}, {2, 0}, {2, 1}, {3, 1}, {1, 3}}}, []int{}}, 22 | } 23 | for _, tt := range tests { 24 | t.Run(tt.name, func(t *testing.T) { 25 | if got := topologicSort(tt.args.vertices, tt.args.edges); !reflect.DeepEqual(got, tt.want) { 26 | t.Errorf("topologicSort() = %v, want %v", got, tt.want) 27 | } 28 | }) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Pattern09 - Two Heaps/Sliding_Window_Median/solution_test.go: -------------------------------------------------------------------------------- 1 | package Sliding_Window_Median 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_medianSlidingWindow(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 []float64 17 | }{ 18 | {"case1", args{[]int{1, 3, -1, -3, 5, 3, 6, 7}, 3}, []float64{1.0, -1.0, -1.0, 3.0, 5.0, 6.0}}, 19 | {"case2", args{[]int{}, 3}, []float64{}}, 20 | {"case3", args{[]int{2147483647, 1, 2, 3, 4, 5, 6, 7, 2147483647}, 2}, []float64{1073741824.00000, 1.50000, 2.50000, 3.50000, 4.50000, 5.50000, 6.50000, 1073741827.00000}}, 21 | } 22 | for _, tt := range tests { 23 | t.Run(tt.name, func(t *testing.T) { 24 | if got := medianSlidingWindow(tt.args.nums, tt.args.k); !reflect.DeepEqual(got, tt.want) { 25 | t.Errorf("medianSlidingWindow() = %v, want %v", got, tt.want) 26 | } 27 | }) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Miscellaneous/min-heap.go: -------------------------------------------------------------------------------- 1 | package Miscellaneous 2 | 3 | import "container/heap" 4 | 5 | // 6 | // time complexity: O(klogn + n) 7 | // space complexity: O(n) 8 | // 9 | func findKthSmallestNumberUsingMinHeap(nums []int, k int) int { 10 | if k > len(nums) { 11 | return -1 12 | } 13 | var minHeap MinHeap 14 | heap.Init(&minHeap) 15 | 16 | for i := 0; i < len(nums); i++ { 17 | heap.Push(&minHeap, nums[i]) 18 | } 19 | 20 | for i := 0; i < k-1; i++ { 21 | heap.Pop(&minHeap) 22 | } 23 | 24 | return minHeap[0] 25 | } 26 | 27 | type MinHeap []int 28 | 29 | func (h MinHeap) Len() int { return len(h) } 30 | func (h MinHeap) Less(i, j int) bool { return h[i] < h[j] } 31 | func (h MinHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] } 32 | func (h *MinHeap) Push(x interface{}) { *h = append(*h, x.(int)) } 33 | func (h *MinHeap) Pop() interface{} { 34 | old := *h 35 | n := len(old) 36 | x := old[n-1] 37 | *h = old[:n-1] 38 | return x 39 | } 40 | -------------------------------------------------------------------------------- /Miscellaneous/quick-sort.go: -------------------------------------------------------------------------------- 1 | package Miscellaneous 2 | 3 | // 4 | // coverage time complexity: O(n), worst O(n^2) 5 | // space complexity: O(n) 6 | // 7 | func findKthSmallestNumberUsingQuickSort(nums []int, k int) int { 8 | if k > len(nums) { 9 | return -1 10 | } 11 | return partitionRec(nums, k, 0, len(nums)-1) 12 | } 13 | 14 | func partitionRec(nums []int, k, start, end int) int { 15 | p := partition(nums, start, end) 16 | if p == k-1 { 17 | return nums[p] 18 | } 19 | if p > k-1 { 20 | return partitionRec(nums, k, start, p-1) 21 | } 22 | return partitionRec(nums, k, p+1, end) 23 | } 24 | 25 | func partition(nums []int, low, high int) int { 26 | if low == high { 27 | return low 28 | } 29 | 30 | pivot := nums[high] 31 | i := low - 1 32 | for j := low; j < high; j++ { 33 | if nums[j] < pivot { 34 | i++ 35 | nums[i], nums[j] = nums[j], nums[i] 36 | } 37 | } 38 | nums[i+1], nums[high] = nums[high], nums[i+1] 39 | return i + 1 40 | } 41 | -------------------------------------------------------------------------------- /Pattern15 - 01 Knapsack/Subset_Sum/solution.go: -------------------------------------------------------------------------------- 1 | package subsetsum 2 | 3 | /* 4 | * Given a set of positive numbers, determine if a subset exists whose sum is equal to a given number ‘S’. 5 | 6 | Input: {1, 2, 3, 7}, S=6 7 | Output: True 8 | The given set has a subset whose sum is '6': {1, 2, 3} 9 | 10 | Input: {1, 2, 7, 1, 5}, S=10 11 | Output: True 12 | The given set has a subset whose sum is '10': {1, 2, 7} 13 | 14 | Input: {1, 3, 4, 8}, S=6 15 | Output: False 16 | The given set does not have any subset whose sum is equal to '6'. 17 | 18 | */ 19 | 20 | func canPartition(num []int, sum int) bool { 21 | // dp[i][j] 前i个数是否可以得到j 22 | n := len(num) 23 | var dp = make([]bool, sum+1) 24 | dp[0] = true 25 | for s := 1; s <= sum; s++ { 26 | dp[s] = num[0] == s 27 | } 28 | 29 | for i := 1; i < n; i++ { 30 | for s := sum; s >= 0; s-- { 31 | if !dp[s] && s >= num[i] { 32 | dp[s] = dp[s-num[i]] 33 | } 34 | } 35 | } 36 | 37 | return dp[sum] 38 | } 39 | -------------------------------------------------------------------------------- /Pattern05 - Cyclic Sort/Challenge2-Find_the_Smallest_Missing_Positive_Number/solution.go: -------------------------------------------------------------------------------- 1 | package Challenge2_Find_the_Smallest_Missing_Positive_Number 2 | 3 | /* 4 | Given an unsorted array containing numbers, find the smallest missing positive number in it. 5 | 6 | Input: [-3, 1, 5, 4, 2] 7 | Output: 3 8 | Explanation: The smallest missing positive number is '3' 9 | 10 | Input: [3, -2, 0, 1, 2] 11 | Output: 4 12 | 13 | Input: [3, 2, 5, 1] 14 | Output: 4 15 | */ 16 | 17 | func findNumber(nums []int) int { 18 | var i = 0 19 | for i < len(nums) { 20 | // 只对 1..n的值进行cyclic sort,确保其在正确的位置上 21 | // 比如1在index 0上,这样排序后,遍历数组,只需要判断第一个value!=index+1的位置就好 22 | j := nums[i] - 1 23 | if nums[i] > 0 && nums[i] <= len(nums) && nums[i] != nums[j] { 24 | nums[i], nums[j] = nums[j], nums[i] 25 | } else { 26 | i++ 27 | } 28 | } 29 | 30 | for i = 0; i < len(nums); i++ { 31 | if nums[i] != i+1 { 32 | return i + 1 33 | } 34 | } 35 | 36 | return len(nums) + 1 37 | } 38 | -------------------------------------------------------------------------------- /Pattern05 - Cyclic Sort/Find_all_Missing_Number/solution.go: -------------------------------------------------------------------------------- 1 | package Find_all_Missing_Number 2 | 3 | /* 4 | We are given an unsorted array containing numbers taken from the range 1 to ‘n’. The array can have duplicates, 5 | which means some numbers will be missing. Find all those missing numbers. 6 | 7 | Input: [2, 3, 1, 8, 2, 3, 5, 1] 8 | Output: 4, 6, 7 9 | Explanation: The array should have all numbers from 1 to 8, due to duplicates 4, 6, and 7 are missing. 10 | 11 | Input: [2, 4, 1, 2] 12 | Output: 3 13 | 14 | Input: [2, 3, 2, 1] 15 | Output: 4 16 | */ 17 | 18 | func findNumbers(nums []int) []int { 19 | var i = 0 20 | var results = make([]int, 0, len(nums)) 21 | for i < len(nums) { 22 | j := nums[i] - 1 23 | if nums[i] != nums[j] { 24 | nums[i], nums[j] = nums[j], nums[i] 25 | } else { 26 | i++ 27 | } 28 | } 29 | 30 | for i = 0; i < len(nums); i++ { 31 | if nums[i] != i+1 { 32 | results = append(results, i+1) 33 | } 34 | } 35 | return results 36 | } 37 | -------------------------------------------------------------------------------- /Pattern08 - Tree DFS/Sum_of_Path_Numbers/solution.go: -------------------------------------------------------------------------------- 1 | package Sum_of_Path_Numbers 2 | 3 | /* 4 | Given a binary tree where each node can only have a digit (0-9) value, each root-to-leaf path will represent a number. 5 | Find the total sum of all the numbers represented by all paths. 6 | 7 | leetcode ref: https://leetcode-cn.com/problems/sum-root-to-leaf-numbers 8 | */ 9 | 10 | type TreeNode struct { 11 | Val int 12 | Left, Right *TreeNode 13 | } 14 | 15 | func sumNumbers(root *TreeNode) int { 16 | allSum := 0 17 | var dfs func(*TreeNode, int) 18 | dfs = func(root *TreeNode, path int) { 19 | if root == nil { 20 | return 21 | } 22 | path = 10*path + root.Val 23 | if root.Left == nil && root.Right == nil { 24 | // leaf node 25 | allSum += path 26 | } else { 27 | if root.Left != nil { 28 | dfs(root.Left, path) 29 | } 30 | if root.Right != nil { 31 | dfs(root.Right, path) 32 | } 33 | } 34 | } 35 | dfs(root, 0) 36 | return allSum 37 | } 38 | -------------------------------------------------------------------------------- /Pattern06 - Reversal of a LinkedList/Reverse_a_LinkedList/solution_test.go: -------------------------------------------------------------------------------- 1 | package Reverse_a_LinkedList 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | "testing" 7 | ) 8 | 9 | func Test_reverse(t *testing.T) { 10 | type args struct { 11 | head *ListNode 12 | } 13 | 14 | head := &ListNode{Value: 2} 15 | head.Next = &ListNode{Value: 4} 16 | head.Next.Next = &ListNode{Value: 6} 17 | head.Next.Next.Next = &ListNode{Value: 8} 18 | tail := &ListNode{Value: 10} 19 | head.Next.Next.Next.Next = tail 20 | 21 | tests := []struct { 22 | name string 23 | args args 24 | want *ListNode 25 | }{ 26 | {"case1", args{head: head}, tail}, 27 | } 28 | for _, tt := range tests { 29 | t.Run(tt.name, func(t *testing.T) { 30 | if got := reverse(tt.args.head); !reflect.DeepEqual(got, tt.want) { 31 | t.Errorf("reverse() = %v, want %v", got, tt.want) 32 | } else { 33 | for p := got; p != nil; p = p.Next { 34 | fmt.Printf("%d ", p.Value) 35 | } 36 | } 37 | }) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Pattern02 - Two Pointers/Challenge1-Quadruple_Sum_to_Target/solution_test.go: -------------------------------------------------------------------------------- 1 | package Challenge1_Quadruple_Sum_to_Target 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_searchQuadruplets(t *testing.T) { 9 | type args struct { 10 | arr []int 11 | target int 12 | } 13 | tests := []struct { 14 | name string 15 | args args 16 | want [][4]int 17 | }{ 18 | {"case1", args{[]int{4, 1, 2, -1, 1, -3}, 1}, [][4]int{{-3, -1, 1, 4}, {-3, 1, 1, 2}}}, 19 | {"case2", args{[]int{2, 0, -1, 1, -2, 2}, 2}, [][4]int{{-2, 0, 2, 2}, {-1, 0, 1, 2}}}, 20 | {"case3", args{[]int{2, 0, -1, 1, -2, 2, 3, 3, -2}, 2}, [][4]int{{-2, -2, 3, 3}, {-2, -1, 2, 3}, {-2, 0, 1, 3}, {-2, 0, 2, 2}, {-1, 0, 1, 2}}}, 21 | } 22 | for _, tt := range tests { 23 | t.Run(tt.name, func(t *testing.T) { 24 | if got := searchQuadruplets(tt.args.arr, tt.args.target); !reflect.DeepEqual(got, tt.want) { 25 | t.Errorf("searchQuadruplets() = %v, want %v", got, tt.want) 26 | } 27 | }) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Pattern08 - Tree DFS/All_Paths_for_a_Sum/solution_test.go: -------------------------------------------------------------------------------- 1 | package All_Paths_for_a_Sum 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_pathSum(t *testing.T) { 9 | type args struct { 10 | root *TreeNode 11 | targetSum int 12 | } 13 | 14 | head1 := &TreeNode{Val: 5} 15 | head1.Left = &TreeNode{Val: 4} 16 | head1.Left.Left = &TreeNode{11, &TreeNode{Val: 7}, &TreeNode{Val: 2}} 17 | head1.Right = &TreeNode{Val: 8} 18 | head1.Right.Left = &TreeNode{Val: 13} 19 | head1.Right.Right = &TreeNode{4, &TreeNode{Val: 5}, &TreeNode{Val: 1}} 20 | 21 | tests := []struct { 22 | name string 23 | args args 24 | want [][]int 25 | }{ 26 | {"case1", args{head1, 22}, [][]int{{5, 4, 11, 2}, {5, 8, 4, 5}}}, 27 | } 28 | for _, tt := range tests { 29 | t.Run(tt.name, func(t *testing.T) { 30 | if got := pathSum(tt.args.root, tt.args.targetSum); !reflect.DeepEqual(got, tt.want) { 31 | t.Errorf("pathSum() = %v, want %v", got, tt.want) 32 | } 33 | }) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Pattern14 - K-way merge/Merge_K_Sorted_Lists/solution_test.go: -------------------------------------------------------------------------------- 1 | package mergeksortedlists 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_mergeKLists(t *testing.T) { 9 | type args struct { 10 | lists []*ListNode 11 | } 12 | 13 | link1 := &ListNode{5, nil} 14 | link1.Next = &ListNode{8, nil} 15 | link1.Next.Next = &ListNode{9, nil} 16 | 17 | link2 := &ListNode{1, nil} 18 | link2.Next = &ListNode{7, nil} 19 | 20 | tests := []struct { 21 | name string 22 | args args 23 | want []int 24 | }{ 25 | {"case1", args{[]*ListNode{link1, link2}}, []int{1, 5, 7, 8, 9}}, 26 | } 27 | for _, tt := range tests { 28 | t.Run(tt.name, func(t *testing.T) { 29 | got := mergeKLists(tt.args.lists) 30 | gotArr := make([]int, 0) 31 | for got != nil { 32 | gotArr = append(gotArr, got.Val) 33 | got = got.Next 34 | } 35 | 36 | if !reflect.DeepEqual(gotArr, tt.want) { 37 | t.Errorf("mergeKLists() = %v, want %v", gotArr, tt.want) 38 | } 39 | }) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Pattern02 - Two Pointers/Pair_with_Target_Sum/solution.go: -------------------------------------------------------------------------------- 1 | package Pair_with_Target_Sum 2 | 3 | /* 4 | Given an array of sorted numbers and a target sum, find a pair in the array whose sum is equal to the given target. 5 | 6 | Write a function to return the indices of the two numbers (i.e. the pair) such that they add up to the given target. 7 | 8 | 9 | Input: [1, 2, 3, 4, 6], target=6 10 | Output: [1, 3] 11 | Explanation: The numbers at index 1 and 3 add up to 6: 2+4=6 12 | 13 | Input: [2, 5, 9, 11], target=11 14 | Output: [0, 2] 15 | Explanation: The numbers at index 0 and 2 add up to 11: 2+9=11 16 | */ 17 | 18 | func search(arr []int, targetSum int) (int, int) { 19 | var ( 20 | left = 0 21 | right = len(arr) - 1 22 | ) 23 | 24 | for left < right { 25 | currentSum := arr[left] + arr[right] 26 | 27 | if currentSum == targetSum { 28 | return left, right 29 | } 30 | 31 | if currentSum > targetSum { 32 | right-- 33 | } else { 34 | left++ 35 | } 36 | } 37 | 38 | return -1, -1 39 | } 40 | -------------------------------------------------------------------------------- /Pattern02 - Two Pointers/Squaring_a_Sorted_Array/solution.go: -------------------------------------------------------------------------------- 1 | package Squaring_a_Sorted_Array 2 | 3 | /* 4 | Given a sorted array, create a new array containing squares of all the numbers of the input array in the sorted order. 5 | 6 | Input: [-2, -1, 0, 2, 3] 7 | Output: [0, 1, 4, 4, 9] 8 | 9 | Input: [-3, -1, 0, 1, 2] 10 | Output: [0, 1, 1, 4, 9] 11 | */ 12 | 13 | func square(x int) int { 14 | return x * x 15 | } 16 | 17 | func makeSquares(arr []int) []int { 18 | var ( 19 | left = 0 20 | right = len(arr) - 1 21 | results = make([]int, len(arr)) 22 | currentHighestIndex = len(arr) - 1 23 | ) 24 | 25 | for left <= right { 26 | leftSquare := square(arr[left]) 27 | rightSquare := square(arr[right]) 28 | if leftSquare < rightSquare { 29 | results[currentHighestIndex] = rightSquare 30 | right-- 31 | } else { 32 | results[currentHighestIndex] = leftSquare 33 | left++ 34 | } 35 | currentHighestIndex-- 36 | } 37 | 38 | return results 39 | } 40 | -------------------------------------------------------------------------------- /Pattern07 - Tree BFS/Level_Order_Successor/solution_test.go: -------------------------------------------------------------------------------- 1 | package Level_Order_Successor 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_findSuccessor(t *testing.T) { 9 | type args struct { 10 | root *TreeNode 11 | key int 12 | } 13 | 14 | head1 := &TreeNode{Val: 12} 15 | node7 := &TreeNode{Val: 7, Left: &TreeNode{Val: 9}} 16 | head1.Left = node7 17 | node1 := &TreeNode{Val: 1, Left: &TreeNode{Val: 10}, Right: &TreeNode{Val: 5}} 18 | head1.Right = node1 19 | 20 | tests := []struct { 21 | name string 22 | args args 23 | want *TreeNode 24 | }{ 25 | {"case1", args{head1, 12}, node7}, 26 | {"case2", args{head1, 7}, node1}, 27 | {"case2", args{head1, 5}, nil}, 28 | {"case3", args{nil, 7}, nil}, 29 | } 30 | for _, tt := range tests { 31 | t.Run(tt.name, func(t *testing.T) { 32 | if got := findSuccessor(tt.args.root, tt.args.key); !reflect.DeepEqual(got, tt.want) { 33 | t.Errorf("findSuccessor() = %v, want %v", got, tt.want) 34 | } 35 | }) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /.github/workflows/go.yml: -------------------------------------------------------------------------------- 1 | name: Go 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | pull_request: 7 | branches: [ main ] 8 | 9 | env: 10 | GO111MODULE: auto 11 | 12 | jobs: 13 | 14 | build: 15 | runs-on: ubuntu-latest 16 | steps: 17 | - uses: actions/checkout@master 18 | 19 | - name: Set up Go 20 | uses: actions/setup-go@v2 21 | with: 22 | go-version: 1.16 23 | 24 | - name: Get 25 | run: go get -d -v ./... 26 | 27 | - name: Build 28 | run: go build -v ./... 29 | 30 | - name: Test 31 | run: go test ./... -race -coverprofile=coverage.txt -covermode=atomic -v 32 | 33 | - name: Codecov 34 | uses: codecov/codecov-action@v1 35 | with: 36 | token: ${{ secrets.CODECOV_TOKEN }} 37 | 38 | 39 | # - name: Upload Codecov 40 | # uses: codecov/codecov-action@v1 41 | # with: 42 | # token: ${{ secrets.CODECOV_TOKEN }} 43 | # verbose: true 44 | # fail_ci_if_error: true 45 | -------------------------------------------------------------------------------- /Pattern02 - Two Pointers/Dutch_National_Flag_Problem/solution.go: -------------------------------------------------------------------------------- 1 | package Dutch_National_Flag_Problem 2 | 3 | /* 4 | Given an array containing 0s, 1s and 2s, sort the array in-place. You should treat numbers of the array as objects, 5 | hence, we can’t count 0s, 1s, and 2s to recreate the array. 6 | 7 | The flag of the Netherlands consists of three colors: red, white and blue; 8 | and since our input array also consists of three different numbers that is why it is called Dutch National Flag problem. 9 | 10 | Input: [1, 0, 2, 1, 0] 11 | Output: [0 0 1 1 2] 12 | 13 | Input: [2, 2, 0, 1, 2, 0] 14 | Output: [0 0 1 2 2 2 ] 15 | */ 16 | 17 | func sort(arr []int) { 18 | var ( 19 | low = 0 20 | high = len(arr) - 1 21 | ) 22 | 23 | for i := 0; i <= high; { 24 | if arr[i] == 0 { 25 | arr[i], arr[low] = arr[low], arr[i] 26 | i++ 27 | low++ 28 | } else if arr[i] == 1 { 29 | i++ 30 | } else { 31 | arr[i], arr[high] = arr[high], arr[i] 32 | // 注意不能i++,因为有可能换过来的是0 33 | high-- 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Pattern04 - Merge Intervals/Conflicting_Appointments/solution_test.go: -------------------------------------------------------------------------------- 1 | package Conflicting_Appointments 2 | 3 | import "testing" 4 | 5 | func Test_canAttendAllAppointments(t *testing.T) { 6 | type args struct { 7 | intervals []Interval 8 | } 9 | tests := []struct { 10 | name string 11 | args args 12 | want bool 13 | }{ 14 | {"case1", args{intervals: []Interval{{1, 4}, {2, 5}, {7, 9}}}, false}, 15 | {"case2", args{intervals: []Interval{{6, 7}, {2, 4}, {8, 12}}}, true}, 16 | {"case3", args{intervals: []Interval{{4, 5}, {2, 3}, {3, 6}}}, false}, 17 | {"case4", args{intervals: []Interval{{4, 5}, {2, 3}, {5, 6}}}, true}, 18 | {"case5", args{intervals: []Interval{}}, true}, 19 | {"case6", args{intervals: []Interval{{1, 4}}}, true}, 20 | } 21 | for _, tt := range tests { 22 | t.Run(tt.name, func(t *testing.T) { 23 | if got := canAttendAllAppointments(tt.args.intervals); got != tt.want { 24 | t.Errorf("canAttendAllAppointments() = %v, want %v", got, tt.want) 25 | } 26 | }) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Miscellaneous/brute-force.go: -------------------------------------------------------------------------------- 1 | // Package Miscellaneous 2 | /* 3 | Kth Smallest Number: 4 | Given an unsorted array of numbers, find Kth smallest number in it. 5 | Please note that it is the Kth smallest number in the sorted order, not the Kth distinct element. 6 | 7 | Input: [1, 5, 12, 2, 11, 5], K = 3 8 | Output: 5 9 | Explanation: The 3rd smallest number is '5', as the first two smaller numbers are [1, 2]. 10 | 11 | Input: [1, 5, 12, 2, 11, 5], K = 4 12 | Output: 5 13 | Explanation: The 4th smallest number is '5', as the first three smaller numbers are 14 | [1, 2, 5]. 15 | 16 | Input: [5, 12, 11, -1, 12], K = 3 17 | Output: 11 18 | Explanation: The 3rd smallest number is '11', as the first two small numbers are [5, -1]. 19 | */ 20 | package Miscellaneous 21 | 22 | import "sort" 23 | 24 | // 25 | // time complexity: O(nlogn) 26 | // space complexity: O(1)/O(n) 27 | // 28 | func findKthSmallestNumber(nums []int, k int) int { 29 | if k > len(nums) { 30 | return -1 31 | } 32 | sort.Ints(nums) 33 | return nums[k-1] 34 | } 35 | -------------------------------------------------------------------------------- /Pattern01 - Sliding Window/Maximum_Sum_Subarray_of_Size_K/solution.go: -------------------------------------------------------------------------------- 1 | package Maximum_Sum_Subarray_of_Size_K 2 | 3 | /* 4 | Given an array of positive numbers and a positive number k, 5 | find the maximum sum of any contiguous subarray of size k. 6 | 7 | Input: [2, 1, 5, 1, 3, 2], k=3 8 | Output: 9 9 | Explanation: Subarray with maximum sum is [5, 1, 3]. 10 | 11 | Input: [2, 3, 4, 1, 5], k=2 12 | Output: 7 13 | Explanation: Subarray with maximum sum is [3, 4]. 14 | */ 15 | 16 | func max(x, y int) int { 17 | if x > y { 18 | return x 19 | } else { 20 | return y 21 | } 22 | } 23 | 24 | func findMaxSumSubArray(k int, arr []int) int { 25 | // use sliding window approach 26 | var ( 27 | maxSum = 0 28 | windowSum = 0 29 | windowStart = 0 30 | ) 31 | 32 | for windowEnd := 0; windowEnd < len(arr); windowEnd++ { 33 | windowSum += arr[windowEnd] 34 | if windowEnd >= k-1 { 35 | maxSum = max(maxSum, windowSum) 36 | windowSum -= arr[windowStart] 37 | windowStart++ 38 | } 39 | } 40 | return maxSum 41 | } 42 | -------------------------------------------------------------------------------- /Pattern07 - Tree BFS/Challenge1-Connect_All_Level_Order_Siblings/solution_test.go: -------------------------------------------------------------------------------- 1 | package Challenge1_Connect_All_Level_Order_Siblings 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | "testing" 7 | ) 8 | 9 | func Test_connect(t *testing.T) { 10 | type args struct { 11 | root *Node 12 | } 13 | 14 | head1 := &Node{Val: 1} 15 | head1.Left = &Node{Val: 2, Left: &Node{Val: 4}, Right: &Node{Val: 5}} 16 | head1.Right = &Node{Val: 3, Left: &Node{Val: 6}, Right: &Node{Val: 7}} 17 | 18 | tests := []struct { 19 | name string 20 | args args 21 | want *Node 22 | }{ 23 | {"case1", args{nil}, nil}, 24 | {"case2", args{head1}, head1}, 25 | } 26 | for _, tt := range tests { 27 | t.Run(tt.name, func(t *testing.T) { 28 | if got := connect(tt.args.root); !reflect.DeepEqual(got, tt.want) { 29 | t.Errorf("connect() = %v, want %v", got, tt.want) 30 | } else { 31 | p := tt.want 32 | for p != nil { 33 | fmt.Printf("%d ", p.Val) 34 | p = p.Next 35 | } 36 | fmt.Println() 37 | } 38 | }) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Pattern07 - Tree BFS/Connect_Level_Order_Siblings/solution.go: -------------------------------------------------------------------------------- 1 | package Connect_Level_Order_Siblings 2 | 3 | /* 4 | Given a binary tree, connect each node with its level order successor. 5 | The last node of each level should point to a null node. 6 | */ 7 | 8 | type Node struct { 9 | Val int 10 | Left, Right *Node 11 | Next *Node 12 | } 13 | 14 | func connect(root *Node) *Node { 15 | if root == nil { 16 | return root 17 | } 18 | var queue []*Node 19 | queue = append(queue, root) 20 | for len(queue) > 0 { 21 | levelSize := len(queue) 22 | var previousNode *Node 23 | //p := make([]*Node, 0) 24 | for i := 0; i < levelSize; i++ { 25 | curNode := queue[0] 26 | queue = queue[1:] 27 | if previousNode != nil { 28 | previousNode.Next = curNode 29 | } 30 | previousNode = curNode 31 | if curNode.Left != nil { 32 | queue = append(queue, curNode.Left) 33 | } 34 | if curNode.Right != nil { 35 | queue = append(queue, curNode.Right) 36 | } 37 | } 38 | } 39 | return root 40 | } 41 | -------------------------------------------------------------------------------- /Miscellaneous/max-heap.go: -------------------------------------------------------------------------------- 1 | package Miscellaneous 2 | 3 | import "container/heap" 4 | 5 | // 6 | // time complexity: O(klogk + (n-k)log(k)) 7 | // space complexity: O(k) 8 | // 9 | func findKthSmallestNumberUsingMaxHeap(nums []int, k int) int { 10 | if k > len(nums) { 11 | return -1 12 | } 13 | var maxheap MaxHeap 14 | heap.Init(&maxheap) 15 | 16 | for i := 0; i < k; i++ { 17 | heap.Push(&maxheap, nums[i]) 18 | } 19 | 20 | for i := k; i < len(nums); i++ { 21 | if nums[i] < maxheap[0] { 22 | heap.Pop(&maxheap) 23 | heap.Push(&maxheap, nums[i]) 24 | } 25 | } 26 | 27 | return maxheap[0] 28 | } 29 | 30 | type MaxHeap []int 31 | 32 | func (h MaxHeap) Len() int { return len(h) } 33 | func (h MaxHeap) Less(i, j int) bool { return h[i] > h[j] } 34 | func (h MaxHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] } 35 | func (h *MaxHeap) Push(x interface{}) { *h = append(*h, x.(int)) } 36 | func (h *MaxHeap) Pop() interface{} { 37 | old := *h 38 | n := len(old) 39 | x := old[n-1] 40 | *h = old[:n-1] 41 | return x 42 | } 43 | -------------------------------------------------------------------------------- /Pattern15 - 01 Knapsack/Challenge1-Count_of_Subset_Sum/solution.go: -------------------------------------------------------------------------------- 1 | package challenge1countofsubsetsum 2 | 3 | /******************************** 4 | Count of Subset Sum 5 | Given a set of positive numbers, find the total number of subsets whose sum is equal to a given number ‘S’. 6 | 7 | Input: {1, 1, 2, 3}, S=4 8 | Output: 3 9 | The given set has '3' subsets whose sum is '4': {1, 1, 2}, {1, 3}, {1, 3} 10 | Note that we have two similar sets {1, 3}, because we have two '1' in our input. 11 | 12 | Input: {1, 2, 7, 1, 5}, S=9 13 | Output: 3 14 | The given set has '3' subsets whose sum is '9': {2, 7}, {1, 7, 1}, {1, 2, 1, 5} 15 | */ 16 | 17 | func countSubsets(nums []int, sum int) int { 18 | //dp[i]表示和为j的个数 19 | n := len(nums) 20 | dp := make([]int, sum+1) 21 | dp[0] = 1 22 | for i := 1; i <= sum; i++ { 23 | if nums[0] == i { 24 | dp[i] = 1 25 | } 26 | } 27 | 28 | for i := 1; i < n; i++ { 29 | for s := sum; s >= 0; s-- { 30 | if s >= nums[i] { 31 | dp[s] += dp[s-nums[i]] 32 | } 33 | } 34 | } 35 | 36 | return dp[sum] 37 | } 38 | -------------------------------------------------------------------------------- /Pattern07 - Tree BFS/Minimum_Depth_of_a_Binary_Tree/solution.go: -------------------------------------------------------------------------------- 1 | package Minimum_Depth_of_a_Binary_Tree 2 | 3 | /* 4 | Find the minimum depth of a binary tree. 5 | The minimum depth is the number of nodes along the shortest path from the root node to the nearest leaf node. 6 | */ 7 | 8 | type TreeNode struct { 9 | Val int 10 | Left, Right *TreeNode 11 | } 12 | 13 | func minDepth(root *TreeNode) int { 14 | if root == nil { 15 | return 0 16 | } 17 | var ( 18 | queue = make([]*TreeNode, 0, 10) 19 | minDepth = 0 20 | ) 21 | 22 | queue = append(queue, root) 23 | for len(queue) > 0 { 24 | levelSize := len(queue) 25 | minDepth++ 26 | for i := 0; i < levelSize; i++ { 27 | curNode := queue[0] 28 | queue = queue[1:] 29 | if curNode.Left == nil && curNode.Right == nil { 30 | return minDepth 31 | } 32 | if curNode.Left != nil { 33 | queue = append(queue, curNode.Left) 34 | } 35 | if curNode.Right != nil { 36 | queue = append(queue, curNode.Right) 37 | } 38 | } 39 | } 40 | 41 | return minDepth 42 | } 43 | -------------------------------------------------------------------------------- /Pattern10 - Subsets/Challenge1-Evaluate_Expression/solution_test.go: -------------------------------------------------------------------------------- 1 | package Challenge1_Evaluate_Expression 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func Test_diffWaysToEvaluateExpression(t *testing.T) { 8 | type args struct { 9 | input string 10 | } 11 | tests := []struct { 12 | name string 13 | args args 14 | want []int 15 | }{ 16 | {"case1", args{"1+2*3"}, []int{7, 9}}, 17 | {"case2", args{"2*3-4-5"}, []int{8, -12, 7, -7, -3}}, 18 | } 19 | for _, tt := range tests { 20 | t.Run(tt.name, func(t *testing.T) { 21 | got := diffWaysToEvaluateExpression(tt.args.input) 22 | want := tt.want 23 | if len(got) != len(want) { 24 | t.Errorf("generateParenthesis() = %v, want %v", got, tt.want) 25 | return 26 | } 27 | 28 | testMap := make(map[int]int) 29 | for _, v := range want { 30 | testMap[v] = 1 31 | } 32 | for _, v := range got { 33 | delete(testMap, v) 34 | } 35 | 36 | if len(testMap) != 0 { 37 | t.Errorf("generateParenthesis() = %v, want %v", got, tt.want) 38 | } 39 | }) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Pattern05 - Cyclic Sort/Challenge1-Find_the_Corrupt_Pair/solution.go: -------------------------------------------------------------------------------- 1 | package Challenge1_Find_the_Corrupt_Pair 2 | 3 | import "fmt" 4 | 5 | /* 6 | We are given an unsorted array containing ‘n’ numbers taken from the range 1 to ‘n’. 7 | The array originally contained all the numbers from 1 to ‘n’, but due to a data error, 8 | one of the numbers got duplicated which also resulted in one number going missing. Find both these numbers. 9 | 10 | Input: [3, 1, 2, 5, 2] 11 | Output: [2, 4] 12 | Explanation: '2' is duplicated and '4' is missing. 13 | 14 | Input: [3, 1, 2, 3, 6, 4] 15 | Output: [3, 5] 16 | Explanation: '3' is duplicated and '5' is missing. 17 | */ 18 | 19 | func findNumbers(nums []int) []int { 20 | var i = 0 21 | for i < len(nums) { 22 | j := nums[i] - 1 23 | if nums[i] != nums[j] { 24 | nums[i], nums[j] = nums[j], nums[i] 25 | } else { 26 | i++ 27 | } 28 | } 29 | fmt.Println(nums) 30 | 31 | for i = 0; i < len(nums); i++ { 32 | if nums[i] != i+1 { 33 | return []int{nums[i], i + 1} 34 | } 35 | } 36 | return []int{-1, -1} 37 | } 38 | -------------------------------------------------------------------------------- /Pattern07 - Tree BFS/Challenge1-Connect_All_Level_Order_Siblings/solution.go: -------------------------------------------------------------------------------- 1 | package Challenge1_Connect_All_Level_Order_Siblings 2 | 3 | /* 4 | Given a binary tree, connect each node with its level order successor. 5 | The last node of each level should point to the first node of the next level. 6 | */ 7 | 8 | type Node struct { 9 | Val int 10 | Left *Node 11 | Right *Node 12 | Next *Node 13 | } 14 | 15 | func connect(root *Node) *Node { 16 | if root == nil { 17 | return nil 18 | } 19 | var ( 20 | queue = make([]*Node, 0) 21 | prevNode *Node 22 | ) 23 | queue = append(queue, root) 24 | for len(queue) > 0 { 25 | levelSize := len(queue) 26 | for i := 0; i < levelSize; i++ { 27 | curNode := queue[0] 28 | queue = queue[1:] 29 | if prevNode != nil { 30 | prevNode.Next = curNode 31 | } 32 | prevNode = curNode 33 | if curNode.Left != nil { 34 | queue = append(queue, curNode.Left) 35 | } 36 | if curNode.Right != nil { 37 | queue = append(queue, curNode.Right) 38 | } 39 | } 40 | } 41 | return root 42 | } 43 | -------------------------------------------------------------------------------- /Pattern07 - Tree BFS/Level_Averages_in_a_Binary_Tree/solution.go: -------------------------------------------------------------------------------- 1 | package Level_Averages_in_a_Binary_Tree 2 | 3 | /* 4 | Given a binary tree, populate an array to represent the averages of all of its levels. 5 | */ 6 | 7 | type TreeNode struct { 8 | Val int 9 | Left, Right *TreeNode 10 | } 11 | 12 | func averageOfLevels(root *TreeNode) []float64 { 13 | if root == nil { 14 | return []float64{} 15 | } 16 | 17 | var ( 18 | result = make([]float64, 0, 10) 19 | queue = make([]*TreeNode, 0, 10) 20 | ) 21 | 22 | queue = append(queue, root) 23 | for len(queue) > 0 { 24 | levelSize := len(queue) 25 | levelSum := 0.0 26 | p := make([]*TreeNode, 0, levelSize*2) 27 | for i := 0; i < levelSize; i++ { 28 | curNode := queue[i] 29 | levelSum += float64(curNode.Val) 30 | if curNode.Left != nil { 31 | p = append(p, curNode.Left) 32 | } 33 | if curNode.Right != nil { 34 | p = append(p, curNode.Right) 35 | } 36 | } 37 | queue = p 38 | result = append(result, levelSum/float64(levelSize)) 39 | } 40 | 41 | return result 42 | } 43 | -------------------------------------------------------------------------------- /Pattern08 - Tree DFS/Count_Paths_for_a_Sum/solution.go: -------------------------------------------------------------------------------- 1 | package Count_Paths_for_a_Sum 2 | 3 | /* 4 | Given a binary tree and a number ‘S’, find all paths in the tree such that the sum of all the node values of each path equals ‘S’. 5 | Please note that the paths can start or end at any node but all paths must follow direction from parent to child (top to bottom). 6 | 7 | ref: https://leetcode-cn.com/problems/path-sum-iii/ 8 | */ 9 | 10 | type TreeNode struct { 11 | Val int 12 | Left, Right *TreeNode 13 | } 14 | 15 | func pathSum(root *TreeNode, targetSum int) int { 16 | var pathSumMap = make(map[int]int) 17 | pathSumMap[0] = 1 18 | return dfs(root, 0, pathSumMap, targetSum) 19 | } 20 | 21 | func dfs(node *TreeNode, acc int, sumMap map[int]int, target int) int { 22 | if node == nil { 23 | return 0 24 | } 25 | var res int 26 | acc += node.Val 27 | res += sumMap[acc-target] 28 | sumMap[acc]++ 29 | 30 | res += dfs(node.Left, acc, sumMap, target) 31 | res += dfs(node.Right, acc, sumMap, target) 32 | 33 | sumMap[acc]-- 34 | 35 | return res 36 | } 37 | -------------------------------------------------------------------------------- /Pattern03 - Fast and Slow pointers/Happy_Number/solution_test.go: -------------------------------------------------------------------------------- 1 | package Happy_Number 2 | 3 | import "testing" 4 | 5 | func Test_squareSum(t *testing.T) { 6 | type args struct { 7 | num int 8 | } 9 | tests := []struct { 10 | name string 11 | args args 12 | want int 13 | }{ 14 | {"case1", args{5}, 25}, 15 | {"case2", args{23}, 13}, 16 | } 17 | for _, tt := range tests { 18 | t.Run(tt.name, func(t *testing.T) { 19 | if got := squareSum(tt.args.num); got != tt.want { 20 | t.Errorf("squareSum() = %v, want %v", got, tt.want) 21 | } 22 | }) 23 | } 24 | } 25 | 26 | func Test_findHappyNumber(t *testing.T) { 27 | type args struct { 28 | num int 29 | } 30 | tests := []struct { 31 | name string 32 | args args 33 | want bool 34 | }{ 35 | {"case1", args{23}, true}, 36 | {"case2", args{12}, false}, 37 | } 38 | for _, tt := range tests { 39 | t.Run(tt.name, func(t *testing.T) { 40 | if got := findHappyNumber(tt.args.num); got != tt.want { 41 | t.Errorf("findHappyNumber() = %v, want %v", got, tt.want) 42 | } 43 | }) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Pattern04 - Merge Intervals/Challenge3-Employee_Free_Time/solution_test.go: -------------------------------------------------------------------------------- 1 | package Challenge3_Employee_Free_Time 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_findEmployeeFreeTime(t *testing.T) { 9 | type args struct { 10 | schedule [][]Interval 11 | } 12 | tests := []struct { 13 | name string 14 | args args 15 | want []Interval 16 | }{ 17 | {"case1", args{[][]Interval{ 18 | {{1, 3}, {5, 6}}, 19 | {{2, 3}, {6, 8}}, 20 | }}, []Interval{{3, 5}}}, 21 | {"case2", args{[][]Interval{ 22 | {{1, 3}, {9, 12}}, 23 | {{2, 4}}, 24 | {{6, 8}}, 25 | }}, []Interval{{4, 6}, {8, 9}}}, 26 | {"case3", args{[][]Interval{ 27 | {{1, 3}}, 28 | {{2, 4}}, 29 | {{3, 5}, {7, 9}}, 30 | }}, []Interval{{5, 7}}}, 31 | {"case4", args{[][]Interval{}}, []Interval{}}, 32 | } 33 | for _, tt := range tests { 34 | t.Run(tt.name, func(t *testing.T) { 35 | if got := findEmployeeFreeTime(tt.args.schedule); !reflect.DeepEqual(got, tt.want) { 36 | t.Errorf("findEmployeeFreeTime() = %v, want %v", got, tt.want) 37 | } 38 | }) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Pattern07 - Tree BFS/Level_Order_Successor/solution.go: -------------------------------------------------------------------------------- 1 | package Level_Order_Successor 2 | 3 | /* 4 | Given a binary tree and a node, find the level order successor of the given node in the tree. 5 | The level order successor is the node that appears right after the given node in the level order traversal. 6 | */ 7 | 8 | type TreeNode struct { 9 | Val int 10 | Left, Right *TreeNode 11 | } 12 | 13 | func findSuccessor(root *TreeNode, key int) *TreeNode { 14 | if root == nil { 15 | return nil 16 | } 17 | var queue = make([]*TreeNode, 0) 18 | var hit = false 19 | queue = append(queue, root) 20 | for len(queue) > 0 { 21 | levelSize := len(queue) 22 | for i := 0; i < levelSize; i++ { 23 | curNode := queue[0] 24 | queue = queue[1:] 25 | if hit { 26 | return curNode 27 | } 28 | if curNode.Val == key { 29 | hit = true 30 | } 31 | if curNode.Left != nil { 32 | queue = append(queue, curNode.Left) 33 | } 34 | if curNode.Right != nil { 35 | queue = append(queue, curNode.Right) 36 | } 37 | } 38 | } 39 | 40 | return nil 41 | } 42 | -------------------------------------------------------------------------------- /Pattern08 - Tree DFS/Challenge1-Tree_Diameter/solution_test.go: -------------------------------------------------------------------------------- 1 | package Challenge1_Tree_Diameter 2 | 3 | import "testing" 4 | 5 | func Test_diameterOfBinaryTree(t *testing.T) { 6 | type args struct { 7 | root *TreeNode 8 | } 9 | 10 | head1 := &TreeNode{1, nil, nil} 11 | head1.Left = &TreeNode{2, &TreeNode{Val: 4}, nil} 12 | head1.Right = &TreeNode{3, &TreeNode{Val: 5}, &TreeNode{Val: 6}} 13 | 14 | head2 := &TreeNode{1, &TreeNode{Val: 2}, nil} 15 | head2.Right = &TreeNode{3, nil, nil} 16 | head2.Right.Left = &TreeNode{5, &TreeNode{Val: 7}, &TreeNode{8, &TreeNode{Val: 10}, nil}} 17 | head2.Right.Right = &TreeNode{6, nil, &TreeNode{9, nil, &TreeNode{Val: 11}}} 18 | 19 | tests := []struct { 20 | name string 21 | args args 22 | want int 23 | }{ 24 | {"case1", args{head1}, 5}, 25 | {"case2", args{head2}, 7}, 26 | } 27 | for _, tt := range tests { 28 | t.Run(tt.name, func(t *testing.T) { 29 | if got := diameterOfBinaryTree(tt.args.root); got != tt.want { 30 | t.Errorf("diameterOfBinaryTree() = %v, want %v", got, tt.want) 31 | } 32 | }) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Pattern08 - Tree DFS/Path_With_Given_Sequence/solution.go: -------------------------------------------------------------------------------- 1 | package Path_With_Given_Sequence 2 | 3 | /* 4 | Given a binary tree and a number sequence, find if the sequence is present as a root-to-leaf path in the given tree. 5 | 6 | ref: https://leetcode-cn.com/problems/check-if-a-string-is-a-valid-sequence-from-root-to-leaves-path-in-a-binary-tree/ 7 | */ 8 | 9 | type TreeNode struct { 10 | Val int 11 | Left, Right *TreeNode 12 | } 13 | 14 | func isValidSequence(root *TreeNode, arr []int) bool { 15 | if root == nil { 16 | return 0 == len(arr) 17 | } 18 | return dfs(root, 0, arr) 19 | } 20 | 21 | func dfs(root *TreeNode, arrInd int, arr []int) bool { 22 | if root == nil { 23 | // 说明该path虽然前面都匹配,但长度不够 24 | return false 25 | } 26 | if arrInd >= len(arr) || root.Val != arr[arrInd] { 27 | // path前面匹配但是path过长,或者当前路径不匹配 28 | return false 29 | } 30 | if arrInd == len(arr)-1 && root.Left == nil && root.Right == nil { 31 | // 必须加上arrInd == len(arr)来保证完全匹配 32 | return true 33 | } 34 | return dfs(root.Left, arrInd+1, arr) || dfs(root.Right, arrInd+1, arr) 35 | } 36 | -------------------------------------------------------------------------------- /Pattern11 - Modified Binary Search/Bitonic_Array_Maximum/solution.go: -------------------------------------------------------------------------------- 1 | package bitonicarraymaximum 2 | 3 | /* 4 | Find the maximum value in a given Bitonic array. 5 | An array is considered bitonic if it is monotonically increasing and then monotonically decreasing. 6 | Monotonically increasing or decreasing means that for any index i in the array arr[i] != arr[i+1]. 7 | 8 | Input: [1, 3, 8, 12, 4, 2] 9 | Output: 12 10 | Explanation: The maximum number in the input bitonic array is '12'. 11 | 12 | Input: [3, 8, 3, 1] 13 | Output: 8 14 | 15 | Input: [1, 3, 8, 12] 16 | Output: 12 17 | 18 | Input: [10, 9, 8] 19 | Output: 10 20 | 21 | ref: https://leetcode-cn.com/problems/peak-index-in-a-mountain-array/ 22 | ref: https://leetcode-cn.com/problems/find-peak-element/ 23 | */ 24 | 25 | func findMax(arr []int) int { 26 | var ( 27 | start = 0 28 | end = len(arr) - 1 29 | ) 30 | 31 | for start < end { 32 | mid := start + (end-start)/2 33 | if arr[mid] < arr[mid+1] { 34 | start = mid + 1 35 | } else { 36 | end = mid 37 | } 38 | } 39 | 40 | return arr[start] 41 | } 42 | -------------------------------------------------------------------------------- /Pattern05 - Cyclic Sort/Find_the_Missing_Number/solution.go: -------------------------------------------------------------------------------- 1 | package Find_the_Missing_Number 2 | 3 | /* 4 | We are given an array containing ‘n’ distinct numbers taken from the range 0 to ‘n’. 5 | Since the array has only ‘n’ numbers out of the total ‘n+1’ numbers, find the missing number. 6 | 7 | Input: [4, 0, 3, 1] 8 | Output: 2 9 | 10 | Input: [8, 3, 5, 2, 4, 6, 0, 1] 11 | Output: 7 12 | */ 13 | 14 | func findMissingNumber(nums []int) int { 15 | // version1 存储已经见过的数字 -> time:O(n), space:O(n) 16 | //var ( 17 | // see = make([]int, len(nums)+1) 18 | //) 19 | //for _, v := range nums { 20 | // see[v] = 1 21 | //} 22 | //for i, v := range see { 23 | // if v == 0 { 24 | // return i 25 | // } 26 | //} 27 | //return -1 28 | // version2 -> time:O(n) 29 | var i = 0 30 | for i < len(nums) { 31 | if nums[i] < len(nums) && nums[i] != nums[nums[i]] { 32 | nums[i], nums[nums[i]] = nums[nums[i]], nums[i] 33 | } else { 34 | i++ 35 | } 36 | } 37 | 38 | for i := 0; i < len(nums); i++ { 39 | if nums[i] != i { 40 | return i 41 | } 42 | } 43 | return len(nums) 44 | } 45 | -------------------------------------------------------------------------------- /Pattern08 - Tree DFS/Challenge2-Path_with_Maximum_Sum/solution_test.go: -------------------------------------------------------------------------------- 1 | package Challenge2_Path_with_Maximum_Sum 2 | 3 | import "testing" 4 | 5 | func Test_maxPathSum(t *testing.T) { 6 | type args struct { 7 | root *TreeNode 8 | } 9 | 10 | head1 := &TreeNode{1, nil, nil} 11 | head1.Left = &TreeNode{2, &TreeNode{Val: 4}, nil} 12 | head1.Right = &TreeNode{3, &TreeNode{Val: 5}, &TreeNode{Val: 6}} 13 | 14 | head2 := &TreeNode{1, nil, nil} 15 | head2.Left = &TreeNode{2, &TreeNode{Val: 1}, &TreeNode{Val: 3}} 16 | head2.Right = &TreeNode{3, nil, nil} 17 | head2.Right.Left = &TreeNode{5, &TreeNode{Val: 7}, &TreeNode{Val: 8}} 18 | head2.Right.Right = &TreeNode{6, nil, &TreeNode{Val: 9}} 19 | 20 | tests := []struct { 21 | name string 22 | args args 23 | want int 24 | }{ 25 | {"case1", args{head1}, 16}, 26 | {"case2", args{head2}, 31}, 27 | } 28 | for _, tt := range tests { 29 | t.Run(tt.name, func(t *testing.T) { 30 | if got := maxPathSum(tt.args.root); got != tt.want { 31 | t.Errorf("maxPathSum() = %v, want %v", got, tt.want) 32 | } 33 | }) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Pattern04 - Merge Intervals/Intervals_Intersection/solution_test.go: -------------------------------------------------------------------------------- 1 | package Intervals_Intersection 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_intersection(t *testing.T) { 9 | type args struct { 10 | arr1 []Interval 11 | arr2 []Interval 12 | } 13 | tests := []struct { 14 | name string 15 | args args 16 | want []Interval 17 | }{ 18 | {"case1", args{ 19 | []Interval{{1, 3}, {5, 6}, {7, 9}}, 20 | []Interval{{2, 3}, {5, 7}}}, 21 | []Interval{{2, 3}, {5, 6}, {7, 7}}}, 22 | {"case2", args{ 23 | arr1: []Interval{{1, 3}, {5, 7}, {9, 12}}, 24 | arr2: []Interval{{5, 10}}, 25 | }, []Interval{{5, 7}, {9, 10}}}, 26 | {"case3", args{ 27 | arr1: []Interval{{3, 6}, {7, 10}}, 28 | arr2: []Interval{{1, 2}, {3, 4}, {5, 6}, {7, 8}}, 29 | }, []Interval{{3, 4}, {5, 6}, {7, 8}}}, 30 | } 31 | for _, tt := range tests { 32 | t.Run(tt.name, func(t *testing.T) { 33 | if got := intersection(tt.args.arr1, tt.args.arr2); !reflect.DeepEqual(got, tt.want) { 34 | t.Errorf("intersection() = %v, want %v", got, tt.want) 35 | } 36 | }) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Pattern04 - Merge Intervals/Insert_Interval/solution_test.go: -------------------------------------------------------------------------------- 1 | package Insert_Interval 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func Test_insert(t *testing.T) { 9 | type args struct { 10 | intervals []Interval 11 | newInterval Interval 12 | } 13 | tests := []struct { 14 | name string 15 | args args 16 | want []Interval 17 | }{ 18 | {"case1", args{[]Interval{{1, 3}, {5, 7}, {8, 12}}, Interval{4, 6}}, []Interval{{1, 3}, {4, 7}, {8, 12}}}, 19 | {"case2", args{[]Interval{{1, 3}, {5, 7}, {8, 12}}, Interval{4, 10}}, []Interval{{1, 3}, {4, 12}}}, 20 | {"case3", args{[]Interval{{2, 3}, {5, 7}}, Interval{1, 4}}, []Interval{{1, 4}, {5, 7}}}, 21 | {"case4", args{[]Interval{}, Interval{1, 4}}, []Interval{{1, 4}}}, 22 | {"case5", args{[]Interval{{2, 3}, {5, 7}}, Interval{3, 4}}, []Interval{{2, 4}, {5, 7}}}, 23 | } 24 | for _, tt := range tests { 25 | t.Run(tt.name, func(t *testing.T) { 26 | if got := insert(tt.args.intervals, tt.args.newInterval); !reflect.DeepEqual(got, tt.want) { 27 | t.Errorf("insert() = %v, want %v", got, tt.want) 28 | } 29 | }) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Pattern10 - Subsets/String_Permutations_by_changing_case/solution_test.go: -------------------------------------------------------------------------------- 1 | package String_Permutations_by_changing_case 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func Test_letterCasePermutation(t *testing.T) { 8 | type args struct { 9 | S string 10 | } 11 | tests := []struct { 12 | name string 13 | args args 14 | want []string 15 | }{ 16 | {"case1", args{"a1b2"}, []string{"a1b2", "A1b2", "a1B2", "A1B2"}}, 17 | {"case2", args{"ab7c"}, []string{"ab7c", "Ab7c", "aB7c", "AB7c", "ab7C", "Ab7C", "aB7C", "AB7C"}}, 18 | } 19 | for _, tt := range tests { 20 | t.Run(tt.name, func(t *testing.T) { 21 | got := letterCasePermutation(tt.args.S) 22 | want := tt.want 23 | if len(got) != len(want) { 24 | t.Errorf("letterCasePermutation() = %v, want %v", got, tt.want) 25 | return 26 | } 27 | 28 | testMap := make(map[string]int) 29 | for _, v := range want { 30 | testMap[v] = 1 31 | } 32 | for _, v := range got { 33 | delete(testMap, v) 34 | } 35 | 36 | if len(testMap) != 0 { 37 | t.Errorf("letterCasePermutation() = %v, want %v", got, tt.want) 38 | } 39 | }) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Pattern07 - Tree BFS/Challenge2-Right_View_of_a_Binary_Tree/solution.go: -------------------------------------------------------------------------------- 1 | package Challenge2_Right_View_of_a_Binary_Tree 2 | 3 | /* 4 | Given a binary tree, return an array containing nodes in its right view. 5 | The right view of a binary tree is the set of nodes visible when the tree is seen from the right side. 6 | */ 7 | 8 | type TreeNode struct { 9 | Val int 10 | Left *TreeNode 11 | Right *TreeNode 12 | } 13 | 14 | func rightSideView(root *TreeNode) []int { 15 | if root == nil { 16 | return []int{} 17 | } 18 | var ( 19 | rightViewList = make([]int, 0) 20 | queue = make([]*TreeNode, 0) 21 | ) 22 | 23 | queue = append(queue, root) 24 | for len(queue) > 0 { 25 | levelSize := len(queue) 26 | for i := 0; i < levelSize; i++ { 27 | curNode := queue[0] 28 | queue = queue[1:] 29 | if i == levelSize-1 { 30 | rightViewList = append(rightViewList, curNode.Val) 31 | } 32 | if curNode.Left != nil { 33 | queue = append(queue, curNode.Left) 34 | } 35 | if curNode.Right != nil { 36 | queue = append(queue, curNode.Right) 37 | } 38 | } 39 | } 40 | 41 | return rightViewList 42 | } 43 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 zhiwei-Feng 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Pattern03 - Fast and Slow pointers/Challenge1-Palindrome_LinkedList/solution_test.go: -------------------------------------------------------------------------------- 1 | package Challenge1_Palindrome_LinkedList 2 | 3 | import "testing" 4 | 5 | func Test_isPalindrome(t *testing.T) { 6 | type args struct { 7 | head *ListNode 8 | } 9 | 10 | head1 := &ListNode{Value: 2} 11 | head1.Next = &ListNode{Value: 4} 12 | head1.Next.Next = &ListNode{Value: 6} 13 | head1.Next.Next.Next = &ListNode{Value: 4} 14 | head1.Next.Next.Next.Next = &ListNode{Value: 2} 15 | 16 | head2 := &ListNode{Value: 2} 17 | head2.Next = &ListNode{Value: 4} 18 | head2.Next.Next = &ListNode{Value: 6} 19 | head2.Next.Next.Next = &ListNode{Value: 4} 20 | head2.Next.Next.Next.Next = &ListNode{Value: 2} 21 | head2.Next.Next.Next.Next.Next = &ListNode{Value: 2} 22 | 23 | tests := []struct { 24 | name string 25 | args args 26 | want bool 27 | }{ 28 | {"case1", args{head1}, true}, 29 | {"case2", args{head2}, false}, 30 | } 31 | for _, tt := range tests { 32 | t.Run(tt.name, func(t *testing.T) { 33 | if got := isPalindrome(tt.args.head); got != tt.want { 34 | t.Errorf("isPalindrome() = %v, want %v", got, tt.want) 35 | } 36 | }) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Pattern16 - Topological Sort/Challenge2/solution_test.go: -------------------------------------------------------------------------------- 1 | package Challenge2 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func Test_findMinHeightTrees(t *testing.T) { 8 | type args struct { 9 | n int 10 | edges [][]int 11 | } 12 | tests := []struct { 13 | name string 14 | args args 15 | want []int 16 | }{ 17 | {"case1", args{5, [][]int{{0, 1}, {1, 2}, {1, 3}, {2, 4}}}, []int{1, 2}}, 18 | {"case2", args{4, [][]int{{0, 1}, {0, 2}, {2, 3}}}, []int{0, 2}}, 19 | {"case3", args{4, [][]int{{0, 1}, {1, 2}, {1, 3}}}, []int{1}}, 20 | {"case4", args{6, [][]int{{3, 0}, {3, 1}, {3, 2}, {3, 4}, {5, 4}}}, []int{3, 4}}, 21 | {"case5", args{1, [][]int{}}, []int{0}}, 22 | {"case6", args{2, [][]int{{0, 1}}}, []int{0, 1}}, 23 | } 24 | for _, tt := range tests { 25 | t.Run(tt.name, func(t *testing.T) { 26 | m := make(map[int]int) 27 | got := findMinHeightTrees(tt.args.n, tt.args.edges) 28 | for _, v := range got { 29 | m[v] = 1 30 | } 31 | for _, v := range tt.want { 32 | delete(m, v) 33 | } 34 | if len(m) != 0 { 35 | t.Errorf("findMinHeightTrees() = %v, want %v", got, tt.want) 36 | } 37 | }) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Pattern06 - Reversal of a LinkedList/Reverse_every_K-elements_Sublist/solution.go: -------------------------------------------------------------------------------- 1 | package Reverse_every_K_elements_Sublist 2 | 3 | /* 4 | Given the head of a LinkedList and a number ‘k’, reverse every ‘k’ sized sub-list starting from the head. 5 | If, in the end, you are left with a sub-list with less than ‘k’ elements, reverse it too. 6 | */ 7 | 8 | type ListNode struct { 9 | Value int 10 | Next *ListNode 11 | } 12 | 13 | func reverse(head *ListNode, k int) *ListNode { 14 | if k <= 1 || head == nil { 15 | return head 16 | } 17 | 18 | var ( 19 | current = head 20 | previous *ListNode 21 | ) 22 | 23 | for { 24 | lastNodeOfPrevPart := previous 25 | lastNodeOfSublist := current 26 | var next *ListNode 27 | for i := 0; i < k && current != nil; i++ { 28 | next = current.Next 29 | current.Next = previous 30 | previous = current 31 | current = next 32 | } 33 | if lastNodeOfPrevPart != nil { 34 | lastNodeOfPrevPart.Next = previous 35 | } else { 36 | head = previous 37 | } 38 | 39 | lastNodeOfSublist.Next = current 40 | if current == nil { 41 | break 42 | } 43 | previous = lastNodeOfSublist 44 | } 45 | 46 | return head 47 | } 48 | -------------------------------------------------------------------------------- /Pattern16 - Topological Sort/Challenge1/solution_test.go: -------------------------------------------------------------------------------- 1 | package Challenge1 2 | 3 | import "testing" 4 | 5 | func Test_sequenceReconstruction(t *testing.T) { 6 | type args struct { 7 | org []int 8 | seqs [][]int 9 | } 10 | tests := []struct { 11 | name string 12 | args args 13 | want bool 14 | }{ 15 | {"case1", args{[]int{1, 2, 3}, [][]int{{1, 2}, {1, 3}}}, false}, 16 | {"case2", args{[]int{1, 2, 3}, [][]int{{1, 2}}}, false}, 17 | {"case3", args{[]int{1, 2, 3, 4}, [][]int{{1, 2}, {2, 3}, {3, 4}}}, true}, 18 | {"case4", args{[]int{1, 2, 3, 4}, [][]int{{1, 2}, {2, 3}, {2, 4}}}, false}, 19 | {"case5", args{[]int{3, 1, 4, 2, 5}, [][]int{{3, 1, 5}, {1, 4, 2, 5}}}, true}, 20 | {"case6", args{[]int{}, [][]int{{3, 1, 5}, {1, 4, 2, 5}}}, false}, 21 | {"case7", args{[]int{1, 2, 3, 4}, [][]int{{1, 2}, {1, 3}, {2, 3}, {4, 2}}}, false}, 22 | {"case8", args{[]int{1, 2, 3, 4}, [][]int{{1, 3}, {3, 4}, {4, 2}}}, false}, 23 | } 24 | for _, tt := range tests { 25 | t.Run(tt.name, func(t *testing.T) { 26 | if got := sequenceReconstruction(tt.args.org, tt.args.seqs); got != tt.want { 27 | t.Errorf("sequenceReconstruction() = %v, want %v", got, tt.want) 28 | } 29 | }) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Pattern12 - Bitwise XOR/Challenge1/solution.go: -------------------------------------------------------------------------------- 1 | package challenge1 2 | 3 | /* 4 | Given a binary matrix representing an image, we want to flip the image horizontally, then invert it. 5 | 6 | To flip an image horizontally means that each row of the image is reversed. For example, flipping [0, 1, 1] horizontally results in [1, 1, 0]. 7 | 8 | To invert an image means that each 0 is replaced by 1, and each 1 is replaced by 0. For example, inverting [1, 1, 0] results in [0, 0, 1]. 9 | 10 | Input: [ 11 | [1,0,1], 12 | [1,1,1], 13 | [0,1,1] 14 | ] 15 | Output: [ 16 | [0,1,0], 17 | [0,0,0], 18 | [0,0,1] 19 | ] 20 | 21 | Input: [ 22 | [1,1,0,0], 23 | [1,0,0,1], 24 | [0,1,1,1], 25 | [1,0,1,0] 26 | ] 27 | Output: [ 28 | [1,1,0,0], 29 | [0,1,1,0], 30 | [0,0,0,1], 31 | [1,0,1,0] 32 | ] 33 | 34 | ref: https://leetcode-cn.com/problems/flipping-an-image/ 35 | */ 36 | 37 | func flipAndInvertImage(image [][]int) [][]int { 38 | if len(image) == 0 { 39 | return [][]int{} 40 | } 41 | 42 | s := len(image[0]) 43 | for i := 0; i < len(image); i++ { 44 | for j := 0; j < (s+1)/2; j++ { 45 | image[i][j], image[i][s-j-1] = image[i][s-j-1]^1, image[i][j]^1 46 | } 47 | } 48 | return image 49 | } 50 | -------------------------------------------------------------------------------- /Pattern11 - Modified Binary Search/Minimum_Difference_Element/solution.go: -------------------------------------------------------------------------------- 1 | package minimumdifferenceelement 2 | 3 | /* 4 | Given an array of numbers sorted in ascending order, find the element in the array that has the minimum difference with the given ‘key’. 5 | 6 | Input: [4, 6, 10], key = 7 7 | Output: 6 8 | Explanation: The difference between the key '7' and '6' is minimum than any other number in the array 9 | 10 | Input: [4, 6, 10], key = 4 11 | Output: 4 12 | 13 | Input: [1, 3, 8, 10, 15], key = 12 14 | Output: 10 15 | 16 | Input: [4, 6, 10], key = 17 17 | Output: 10 18 | */ 19 | 20 | func searchMinDiffElement(arr []int, key int) int { 21 | if key < arr[0] { 22 | return arr[0] 23 | } 24 | if key > arr[len(arr)-1] { 25 | return arr[len(arr)-1] 26 | } 27 | var ( 28 | start = 0 29 | end = len(arr) - 1 30 | ) 31 | 32 | for start <= end { 33 | mid := start + (end-start)/2 34 | if arr[mid] == key { 35 | return arr[mid] 36 | } 37 | if key < arr[mid] { 38 | end = mid - 1 39 | } else { 40 | start = mid + 1 41 | } 42 | } 43 | 44 | // end+1 == start, arr[end] len(nums) { 14 | return -1 15 | } 16 | return recursiveFindPivot(nums, k, 0, len(nums)-1) 17 | } 18 | 19 | func recursiveFindPivot(nums []int, k, start, end int) int { 20 | p := partitionRandomized(nums, start, end) 21 | if p == k-1 { 22 | return nums[p] 23 | } 24 | if p > k-1 { 25 | return recursiveFindPivot(nums, k, start, p-1) 26 | } 27 | return recursiveFindPivot(nums, k, p+1, end) 28 | } 29 | 30 | func partitionRandomized(nums []int, low, high int) int { 31 | if low == high { 32 | return low 33 | } 34 | 35 | rand.Seed(time.Now().Unix()) 36 | pivot_ind := low + rand.Intn(high-low) 37 | nums[pivot_ind], nums[high] = nums[high], nums[pivot_ind] 38 | 39 | pivot := nums[high] 40 | i := low - 1 41 | for j := low; j < high; j++ { 42 | if nums[j] < pivot { 43 | i++ 44 | nums[i], nums[j] = nums[j], nums[i] 45 | } 46 | } 47 | nums[i+1], nums[high] = nums[high], nums[i+1] 48 | return i + 1 49 | } 50 | -------------------------------------------------------------------------------- /Pattern08 - Tree DFS/Challenge2-Path_with_Maximum_Sum/solution.go: -------------------------------------------------------------------------------- 1 | package Challenge2_Path_with_Maximum_Sum 2 | 3 | import "math" 4 | 5 | /* 6 | Find the path with the maximum sum in a given binary tree. Write a function that returns the maximum sum. 7 | 8 | A path can be defined as a sequence of nodes between any two nodes and doesn’t necessarily pass through the root. 9 | The path must contain at least one node. 10 | 11 | ref: https://leetcode-cn.com/problems/binary-tree-maximum-path-sum/ 12 | */ 13 | 14 | type TreeNode struct { 15 | Val int 16 | Left, Right *TreeNode 17 | } 18 | 19 | func maxPathSum(root *TreeNode) int { 20 | var maxSum = math.MinInt8 21 | dfs(root, &maxSum) 22 | return maxSum 23 | } 24 | 25 | func dfs(node *TreeNode, maxSum *int) int { 26 | if node == nil { 27 | return 0 28 | } 29 | 30 | leftMaxSum := max(dfs(node.Left, maxSum), 0) 31 | rightMaxSum := max(dfs(node.Right, maxSum), 0) 32 | 33 | currentSum := leftMaxSum + rightMaxSum + node.Val 34 | if currentSum > *maxSum { 35 | *maxSum = currentSum 36 | } 37 | 38 | return max(leftMaxSum, rightMaxSum) + node.Val 39 | } 40 | 41 | func max(i, j int) int { 42 | if i > j { 43 | return i 44 | } else { 45 | return j 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Pattern10 - Subsets/Unique_Generalized_Abbreviations/solution_test.go: -------------------------------------------------------------------------------- 1 | package Unique_Generalized_Abbreviations 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func Test_generateAbbreviations(t *testing.T) { 8 | type args struct { 9 | word string 10 | } 11 | tests := []struct { 12 | name string 13 | args args 14 | want []string 15 | }{ 16 | {"case1", args{"BAT"}, []string{"BAT", "BA1", "B1T", "B2", "1AT", "1A1", "2T", "3"}}, 17 | {"case2", args{"code"}, []string{"code", "cod1", "co1e", "co2", "c1de", "c1d1", "c2e", "c3", "1ode", "1od1", "1o1e", "1o2", 18 | "2de", "2d1", "3e", "4"}}, 19 | {"case3", args{""}, []string{}}, 20 | } 21 | for _, tt := range tests { 22 | t.Run(tt.name, func(t *testing.T) { 23 | got := generateAbbreviations(tt.args.word) 24 | want := tt.want 25 | if len(got) != len(want) { 26 | t.Errorf("generateParenthesis() = %v, want %v", got, tt.want) 27 | return 28 | } 29 | 30 | testMap := make(map[string]int) 31 | for _, v := range want { 32 | testMap[v] = 1 33 | } 34 | for _, v := range got { 35 | delete(testMap, v) 36 | } 37 | 38 | if len(testMap) != 0 { 39 | t.Errorf("generateParenthesis() = %v, want %v", got, tt.want) 40 | } 41 | }) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Pattern12 - Bitwise XOR/Complement_of_Base_10_Number/solution.go: -------------------------------------------------------------------------------- 1 | package complementofbase10number 2 | 3 | /* 4 | Every non-negative integer N has a binary representation, for example, 8 can be represented as “1000” in binary and 7 as “0111” in binary. 5 | 6 | The complement of a binary representation is the number in binary that we get when we change every 1 to a 0 and every 0 to a 1. 7 | For example, the binary complement of “1010” is “0101”. 8 | 9 | For a given positive number N in base-10, return the complement of its binary representation as a base-10 integer. 10 | 11 | Input: 8 12 | Output: 7 13 | Explanation: 8 is 1000 in binary, its complement is 0111 in binary, which is 7 in base-10. 14 | 15 | Input: 10 16 | Output: 5 17 | Explanation: 10 is 1010 in binary, its complement is 0101 in binary, which is 5 in base-10. 18 | 19 | ref: https://leetcode-cn.com/problems/complement-of-base-10-integer/ 20 | */ 21 | 22 | func bitwiseComplement(n int) int { 23 | if n == 0 { 24 | return 1 25 | } 26 | var ( 27 | all_bit_one = 0 28 | root = 1 29 | tmpN = n 30 | ) 31 | for tmpN > 0 { 32 | all_bit_one = all_bit_one + root 33 | root = root * 2 34 | tmpN = tmpN >> 1 35 | } 36 | 37 | return all_bit_one ^ n 38 | } 39 | -------------------------------------------------------------------------------- /Pattern07 - Tree BFS/Binary_Tree_Level_Order_Traversal/solution.go: -------------------------------------------------------------------------------- 1 | package Binary_Tree_Level_Order_Traversal 2 | 3 | /* 4 | Given a binary tree, populate an array to represent its level-by-level traversal. 5 | You should populate the values of all nodes of each level from left to right in separate sub-arrays. 6 | 7 | Leetcode ref: problems/binary-tree-level-order-traversal/ 8 | */ 9 | 10 | type TreeNode struct { 11 | Val int 12 | Left, Right *TreeNode 13 | } 14 | 15 | func levelOrder(head *TreeNode) [][]int { 16 | if head == nil { 17 | return [][]int{} 18 | } 19 | var ( 20 | result = make([][]int, 0, 10) 21 | queue = make([]*TreeNode, 0, 10) 22 | ) 23 | 24 | queue = append(queue, head) 25 | for len(queue) > 0 { 26 | levelSize := len(queue) 27 | currentLevelArray := make([]int, 0, levelSize) 28 | for i := 0; i < levelSize; i++ { 29 | curNode := queue[0] 30 | queue = queue[1:] 31 | currentLevelArray = append(currentLevelArray, curNode.Val) 32 | if curNode.Left != nil { 33 | queue = append(queue, curNode.Left) 34 | } 35 | if curNode.Right != nil { 36 | queue = append(queue, curNode.Right) 37 | } 38 | } 39 | result = append(result, currentLevelArray) 40 | } 41 | 42 | return result 43 | } 44 | -------------------------------------------------------------------------------- /Pattern08 - Tree DFS/All_Paths_for_a_Sum/solution.go: -------------------------------------------------------------------------------- 1 | package All_Paths_for_a_Sum 2 | 3 | /* 4 | Given a binary tree and a number ‘S’, find all paths from root-to-leaf such that the sum of all the node values of each path equals ‘S’. 5 | 6 | leetcode ref: https://leetcode-cn.com/problems/path-sum-ii/ 7 | */ 8 | 9 | type TreeNode struct { 10 | Val int 11 | Left, Right *TreeNode 12 | } 13 | 14 | func pathSum(root *TreeNode, targetSum int) (ans [][]int) { 15 | var path []int 16 | var dfs func(*TreeNode, int) 17 | dfs = func(root *TreeNode, left int) { 18 | if root == nil { 19 | return 20 | } 21 | left -= root.Val 22 | path = append(path, root.Val) 23 | defer func() { path = path[:len(path)-1] }() 24 | if left == 0 && root.Left == nil && root.Right == nil { 25 | // 解释下为什么要这么做,而不是 26 | // ans = append(ans, path) 27 | // 因为如果像上面做,其实在ans存放的是path这个slice,而path的变化会影响到ans的内容 28 | // 而我们想要的是当ans append操作的时候,是加入一个immutable的[]int, 29 | // 因此必须使用append([]int{}, path...)重新分配一块新的内存空间存放path的复制体,并用一个新的指针指向 30 | // 而此时ans保存的是复制体,则不会在随后的代码执行中被修改。 31 | ans = append(ans, append([]int{}, path...)) 32 | return 33 | } 34 | dfs(root.Left, left) 35 | dfs(root.Right, left) 36 | } 37 | dfs(root, targetSum) 38 | return 39 | } 40 | -------------------------------------------------------------------------------- /Pattern11 - Modified Binary Search/Order-agnostic_Binary_Search/solution.go: -------------------------------------------------------------------------------- 1 | package orderagnosticbinarysearch 2 | 3 | /* 4 | Given a sorted array of numbers, find if a given number ‘key’ is present in the array. 5 | Though we know that the array is sorted, we don’t know if it’s sorted in ascending or descending order. 6 | You should assume that the array can have duplicates. 7 | 8 | Write a function to return the index of the ‘key’ if it is present in the array, otherwise return -1. 9 | 10 | Input: [4, 6, 10], key = 10 11 | Output: 2 12 | 13 | Input: [1, 2, 3, 4, 5, 6, 7], key = 5 14 | Output: 4 15 | 16 | Input: [10, 6, 4], key = 10 17 | Output: 0 18 | 19 | Input: [10, 6, 4], key = 4 20 | Output: 2 21 | */ 22 | 23 | func search(arr []int, key int) int { 24 | var ( 25 | start = 0 26 | end = len(arr) - 1 27 | isAsc = arr[start] < arr[end] 28 | ) 29 | 30 | for start <= end { 31 | mid := (start + end) / 2 32 | if arr[mid] == key { 33 | return mid 34 | } 35 | 36 | if isAsc { 37 | if key < arr[mid] { 38 | end = mid - 1 39 | } else { 40 | start = mid + 1 41 | } 42 | } else { 43 | if key > arr[mid] { 44 | end = mid - 1 45 | } else { 46 | start = mid + 1 47 | } 48 | } 49 | } 50 | 51 | return -1 52 | } 53 | -------------------------------------------------------------------------------- /Pattern06 - Reversal of a LinkedList/Reverse_a_Sublist/solution.go: -------------------------------------------------------------------------------- 1 | package Reverse_a_Sublist 2 | 3 | type ListNode struct { 4 | Val int 5 | Next *ListNode 6 | } 7 | 8 | func reverseBetween(head *ListNode, left int, right int) *ListNode { 9 | if left == right { 10 | return head 11 | } 12 | 13 | /** 14 | current, prev, next用于反转子链表 15 | tail 记录子链表初始时的头结点,用于反转后连接右侧剩余节点 16 | */ 17 | var ( 18 | current, prev, next, tail *ListNode 19 | LeftNode *ListNode 20 | RightNode *ListNode 21 | p = head 22 | i = 1 23 | ) 24 | 25 | // LeftNode表示子链表的前一个节点 26 | for i < left { 27 | LeftNode = p 28 | p = p.Next 29 | i++ 30 | } 31 | 32 | current = p 33 | tail = current 34 | 35 | for i < right { 36 | p = p.Next 37 | i++ 38 | } 39 | 40 | RightNode = p.Next 41 | // 断开子链表和右侧剩余节点的连接,方便子链表反转 42 | p.Next = nil 43 | 44 | for current != nil { 45 | next = current.Next 46 | current.Next = prev 47 | prev = current 48 | current = next 49 | } 50 | // 连接上右侧剩余节点 51 | tail.Next = RightNode 52 | 53 | if LeftNode != nil { 54 | // 说明此时原链表的头结点并未反转 55 | LeftNode.Next = prev 56 | return head 57 | } else { 58 | // 头结点被反转 59 | return prev 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /Pattern10 - Subsets/Balanced_Parentheses/solution_test.go: -------------------------------------------------------------------------------- 1 | package Balanced_Parentheses 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func Test_generateParenthesis(t *testing.T) { 8 | type args struct { 9 | n int 10 | } 11 | tests := []struct { 12 | name string 13 | args args 14 | want []string 15 | }{ 16 | {"case1", args{3}, []string{"((()))", "(()())", "(())()", "()(())", "()()()"}}, 17 | {"case2", args{1}, []string{"()"}}, 18 | {"case3", args{4}, []string{"(((())))", "((()()))", "((())())", "((()))()", "(()(()))", "(()()())", "(()())()", "(())(())", "(())()()", "()((()))", "()(()())", "()(())()", "()()(())", "()()()()"}}, 19 | {"case4", args{0}, []string{}}, 20 | } 21 | for _, tt := range tests { 22 | t.Run(tt.name, func(t *testing.T) { 23 | got := generateParenthesis(tt.args.n) 24 | want := tt.want 25 | if len(got) != len(want) { 26 | t.Errorf("generateParenthesis() = %v, want %v", got, tt.want) 27 | return 28 | } 29 | 30 | testMap := make(map[string]int) 31 | for _, v := range want { 32 | testMap[v] = 1 33 | } 34 | for _, v := range got { 35 | delete(testMap, v) 36 | } 37 | 38 | if len(testMap) != 0 { 39 | t.Errorf("generateParenthesis() = %v, want %v", got, tt.want) 40 | } 41 | }) 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Pattern03 - Fast and Slow pointers/Happy_Number/solution.go: -------------------------------------------------------------------------------- 1 | package Happy_Number 2 | 3 | /* 4 | Any number will be called a happy number if, after repeatedly replacing it with a number equal to the sum of the square of all of its digits, leads us to number ‘1’. 5 | All other (not-happy) numbers will never reach ‘1’. Instead, they will be stuck in a cycle of numbers which does not include ‘1’. 6 | 7 | Input: 23 8 | Output: true (23 is a happy number) 9 | Explanations: Here are the steps to find out that 23 is a happy number: 10 | 11 | Input: 12 12 | Output: false (12 is not a happy number) 13 | Explanations: Here are the steps to find out that 12 is not a happy number: 14 | */ 15 | 16 | func squareSum(num int) int { 17 | sum := 0 18 | for num > 0 { 19 | curNum := num % 10 20 | sum += curNum * curNum 21 | num /= 10 22 | } 23 | return sum 24 | } 25 | 26 | func findHappyNumber(num int) bool { 27 | var ( 28 | fast, slow = num, num 29 | ) 30 | 31 | // 1. 有环,则最终fast==slow 32 | // 2. 无环,则最终fast==slow==1 33 | 34 | fast = squareSum(squareSum(fast)) 35 | slow = squareSum(slow) 36 | for fast != slow { 37 | fast = squareSum(squareSum(fast)) 38 | slow = squareSum(slow) 39 | } 40 | 41 | if fast == 1 { 42 | return true 43 | } else { 44 | return false 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Pattern06 - Reversal of a LinkedList/Challenge1-Reverse_alternating_Kelements_Sublist/solution.go: -------------------------------------------------------------------------------- 1 | package Challenge1_Reverse_alternating_Kelements_Sublist 2 | 3 | /* 4 | Given the head of a LinkedList and a number ‘k’, reverse every alternating ‘k’ sized sub-list starting from the head. 5 | If, in the end, you are left with a sub-list with less than ‘k’ elements, reverse it too. 6 | */ 7 | 8 | type ListNode struct { 9 | Value int 10 | Next *ListNode 11 | } 12 | 13 | func reverseAlternatingKElementsSublist(head *ListNode, k int) *ListNode { 14 | if k <= 1 || head == nil { 15 | return head 16 | } 17 | 18 | var ( 19 | current = head 20 | previous *ListNode 21 | ) 22 | 23 | for current != nil { 24 | lastNodeOfSublist := current 25 | lastNodeOfPrev := previous 26 | 27 | for i := 0; i < k && current != nil; i++ { 28 | next := current.Next 29 | current.Next = previous 30 | previous = current 31 | current = next 32 | } 33 | 34 | if lastNodeOfPrev == nil { 35 | head = previous 36 | } else { 37 | lastNodeOfPrev.Next = previous 38 | } 39 | 40 | lastNodeOfSublist.Next = current 41 | 42 | // skip k steps 43 | for i := 0; i < k && current != nil; i++ { 44 | previous = current 45 | current = current.Next 46 | } 47 | } 48 | 49 | return head 50 | } 51 | -------------------------------------------------------------------------------- /Pattern01 - Sliding Window/Longest_Subarray_with_Ones_after_Replacement/solution.go: -------------------------------------------------------------------------------- 1 | package Longest_Subarray_with_Ones_after_Replacement 2 | 3 | /* 4 | Given an array containing 0s and 1s, if you are allowed to replace no more than ‘k’ 0s with 1s, 5 | find the length of the longest contiguous subarray having all 1s. 6 | 7 | Input: Array=[0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1], k=2 8 | Output: 6 9 | Explanation: Replace the '0' at index 5 and 8 to have the longest contiguous subarray of 1s having length 6. 10 | 11 | Input: Array=[0, 1, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1, 1], k=3 12 | Output: 9 13 | Explanation: Replace the '0' at index 6, 9, and 10 to have the longest contiguous subarray of 1s having length 9. 14 | */ 15 | 16 | func findLength(arr []int, k int) int { 17 | var ( 18 | maxLength = 0 19 | windowStart = 0 20 | zeroNum = 0 21 | ) 22 | 23 | for windowEnd := 0; windowEnd < len(arr); windowEnd++ { 24 | if arr[windowEnd] == 0 { 25 | zeroNum++ 26 | } 27 | 28 | for zeroNum > k { 29 | if arr[windowStart] == 0 { 30 | zeroNum-- 31 | } 32 | windowStart++ 33 | } 34 | 35 | maxLength = max(maxLength, windowEnd-windowStart+1) 36 | } 37 | 38 | return maxLength 39 | } 40 | 41 | func max(x, y int) int { 42 | if x > y { 43 | return x 44 | } else { 45 | return y 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Pattern10 - Subsets/Balanced_Parentheses/solution.go: -------------------------------------------------------------------------------- 1 | package Balanced_Parentheses 2 | 3 | /* 4 | For a given number ‘N’, write a function to generate all combination of ‘N’ pairs of balanced parentheses. 5 | 6 | Input: N=2 7 | Output: (()), ()() 8 | 9 | Input: N=3 10 | Output: ((())), (()()), (())(), ()(()), ()()() 11 | 12 | ref: https://leetcode-cn.com/problems/generate-parentheses/ 13 | */ 14 | 15 | func generateParenthesis(n int) []string { 16 | if n == 0 { 17 | return []string{} 18 | } 19 | var ans []string 20 | var queue []ParenthesesString 21 | queue = append(queue, ParenthesesString{"", 0, 0}) 22 | for len(queue) != 0 { 23 | curStr := queue[0] 24 | queue = queue[1:] // pop 25 | if curStr.OpenCount == n && curStr.CloseCount == n { 26 | ans = append(ans, curStr.Value) 27 | continue 28 | } 29 | if curStr.OpenCount < n { 30 | queue = append(queue, ParenthesesString{curStr.Value + "(", curStr.OpenCount + 1, curStr.CloseCount}) 31 | } 32 | 33 | if curStr.OpenCount > curStr.CloseCount { 34 | queue = append(queue, ParenthesesString{curStr.Value + ")", curStr.OpenCount, curStr.CloseCount + 1}) 35 | } 36 | } 37 | 38 | return ans 39 | } 40 | 41 | type ParenthesesString struct { 42 | Value string 43 | OpenCount int // 多少个左括号 44 | CloseCount int // 多少个右括号 45 | } 46 | -------------------------------------------------------------------------------- /Pattern15 - 01 Knapsack/Equal_Subset_Sum_Partition/solution.go: -------------------------------------------------------------------------------- 1 | package equalsubsetsumpartition 2 | 3 | /* 4 | * Equal Subset Sum Partition 5 | Given a set of positive numbers, find if we can partition it into two subsets such that the sum of elements in both subsets is equal. 6 | 7 | Input: {1, 2, 3, 4} 8 | Output: True 9 | Explanation: The given set can be partitioned into two subsets with equal sum: {1, 4} & {2, 3} 10 | 11 | Input: {1, 1, 3, 4, 7} 12 | Output: True 13 | Explanation: The given set can be partitioned into two subsets with equal sum: {1, 3, 4} & {1, 7} 14 | 15 | Input: {2, 3, 4, 6} 16 | Output: False 17 | Explanation: The given set cannot be partitioned into two subsets with equal sum. 18 | 19 | ref: https://leetcode-cn.com/problems/partition-equal-subset-sum 20 | */ 21 | 22 | func canPartition(nums []int) bool { 23 | sum := 0 24 | for _, v := range nums { 25 | sum += v 26 | } 27 | if sum%2 != 0 { 28 | return false 29 | } 30 | target := sum / 2 31 | dp := make([]bool, target+1) 32 | 33 | for s := 1; s <= target; s++ { 34 | // corner 35 | dp[s] = nums[0] == s 36 | } 37 | 38 | for i := 1; i < len(nums); i++ { 39 | for j := target; j > 0; j-- { 40 | if !dp[j] && j>=nums[i] { 41 | dp[j] = dp[j-nums[i]] 42 | } 43 | } 44 | } 45 | 46 | return dp[target] 47 | } 48 | -------------------------------------------------------------------------------- /Pattern02 - Two Pointers/Triplets_with_Smaller_Sum/solution.go: -------------------------------------------------------------------------------- 1 | package Triplets_with_Smaller_Sum 2 | 3 | import "sort" 4 | 5 | /* 6 | Given an array arr of unsorted numbers and a target sum, 7 | count all triplets in it such that arr[i] + arr[j] + arr[k] < target where i, j, and k are three different indices. 8 | Write a function to return the count of such triplets. 9 | 10 | Input: [-1, 0, 2, 3], target=3 11 | Output: 2 12 | Explanation: There are two triplets whose sum is less than the target: [-1, 0, 3], [-1, 0, 2] 13 | 14 | Input: [-1, 4, 2, 1, 3], target=5 15 | Output: 4 16 | Explanation: There are four triplets whose sum is less than the target: 17 | [-1, 1, 4], [-1, 1, 3], [-1, 1, 2], [-1, 2, 3] 18 | */ 19 | 20 | func searchTriplets(arr []int, target int) int { 21 | var ( 22 | count = 0 23 | ) 24 | 25 | sort.Ints(arr) 26 | for i := 0; i < len(arr)-2; i++ { 27 | left, right := i+1, len(arr)-1 28 | for left < right { 29 | currentSum := arr[i] + arr[left] + arr[right] 30 | //如果currentSum>=target, currentSum需要减小因此right-- 31 | //如果currentSum= target { 35 | right-- 36 | } else { 37 | count += right - left 38 | left++ 39 | } 40 | } 41 | } 42 | 43 | return count 44 | } 45 | -------------------------------------------------------------------------------- /Pattern11 - Modified Binary Search/Number_Range/solution.go: -------------------------------------------------------------------------------- 1 | package numberrange 2 | 3 | /* 4 | Given an array of numbers sorted in ascending order, find the range of a given number ‘key’. 5 | The range of the ‘key’ will be the first and last position of the ‘key’ in the array. 6 | 7 | Write a function to return the range of the ‘key’. If the ‘key’ is not present return [-1, -1]. 8 | 9 | Input: [4, 6, 6, 6, 9], key = 6 10 | Output: [1, 3] 11 | 12 | Input: [1, 3, 8, 10, 15], key = 10 13 | Output: [3, 3] 14 | 15 | Input: [1, 3, 8, 10, 15], key = 12 16 | Output: [-1, -1] 17 | */ 18 | 19 | func searchRange(nums []int, target int) []int { 20 | var res = [2]int{-1, -1} 21 | 22 | res[0] = search(nums, target, true) 23 | if res[0] != -1 { 24 | res[1] = search(nums, target, false) 25 | } 26 | 27 | return res[:] 28 | } 29 | 30 | func search(arr []int, target int, findLeftCorner bool) int { 31 | var ( 32 | start = 0 33 | end = len(arr) - 1 34 | index = -1 35 | ) 36 | 37 | for start <= end { 38 | mid := start + (end-start)/2 39 | if target > arr[mid] { 40 | start = mid + 1 41 | } else if target < arr[mid] { 42 | end = mid - 1 43 | } else { 44 | index = mid 45 | if findLeftCorner { 46 | end = mid - 1 47 | } else { 48 | start = mid + 1 49 | } 50 | } 51 | } 52 | 53 | return index 54 | } 55 | -------------------------------------------------------------------------------- /Pattern10 - Subsets/Subsets_with_Duplicates/solution.go: -------------------------------------------------------------------------------- 1 | package Subsets_with_Duplicates 2 | 3 | import ( 4 | "math" 5 | "sort" 6 | ) 7 | 8 | /* 9 | Given a set of numbers that might contain duplicates, find all of its distinct subsets. 10 | 11 | Input: [1, 3, 3] 12 | Output: [], [1], [3], [1,3], [3,3], [1,3,3] 13 | 14 | Input: [1, 5, 3, 3] 15 | Output: [], [1], [5], [3], [1,5], [1,3], [5,3], [1,5,3], [3,3], [1,3,3], [3,3,5], [1,5,3,3] 16 | 17 | ref: https://leetcode-cn.com/problems/subsets-ii/ 18 | */ 19 | 20 | // 21 | // 1. 将nums排序 22 | // 2. 对于currentNum==prevNum,我们只对上一次添加的子集进行新添操作 23 | // 3. 原因是因为对于在上一次之前的子集,上一次已经进行了一次新添操作,当前轮再做一次操作会导致重复子集的出现,因此不再做操作。 24 | // 25 | func subsetsWithDup(nums []int) [][]int { 26 | var ( 27 | ans = make([][]int, 0, int(math.Pow(2, float64(len(nums))))) 28 | startInd = 0 29 | endInd = 0 30 | ) 31 | sort.Ints(nums) 32 | ans = append(ans, []int{}) 33 | 34 | for i := 0; i < len(nums); i++ { 35 | startInd = 0 36 | if i > 0 && nums[i] == nums[i-1] { 37 | startInd = endInd + 1 38 | } 39 | endInd = len(ans) - 1 40 | for _, subset := range ans[startInd : endInd+1] { 41 | newSubset := make([]int, len(subset), len(subset)+1) 42 | copy(newSubset, subset) 43 | newSubset = append(newSubset, nums[i]) 44 | ans = append(ans, newSubset) 45 | } 46 | } 47 | 48 | return ans 49 | } 50 | -------------------------------------------------------------------------------- /Pattern03 - Fast and Slow pointers/Start_of_LinkedList_Cycle/solution.go: -------------------------------------------------------------------------------- 1 | package Start_of_LinkedList_Cycle 2 | 3 | /* 4 | Given the head of a Singly LinkedList that contains a cycle, write a function to find the starting node of the cycle. 5 | */ 6 | 7 | type ListNode struct { 8 | Value int 9 | Next *ListNode 10 | } 11 | 12 | func findCycleStart(head *ListNode) *ListNode { 13 | // version 1 通过记录走过的位置, 这种方法有比较大的空间消耗 14 | //moveRecord := make(map[*ListNode]bool) 15 | //move := head 16 | //for { 17 | // if _, ok := moveRecord[move]; ok { 18 | // break 19 | // } 20 | // moveRecord[move] = true 21 | // move = move.Next 22 | //} 23 | //return move 24 | 25 | // version 2 利用cycle的长度来寻找 26 | // step1 获取cycle的长度k 27 | var ( 28 | fast, slow = head, head 29 | p1, p2 = head, head 30 | cycleLen = 0 31 | ) 32 | 33 | for fast != nil && fast.Next != nil { 34 | fast = fast.Next.Next 35 | slow = slow.Next 36 | if fast == slow { 37 | move := fast 38 | move = move.Next 39 | cycleLen++ 40 | for move != fast { 41 | move = move.Next 42 | cycleLen++ 43 | } 44 | break 45 | } 46 | } 47 | 48 | // step2 将p2向前移动k个位置 49 | for i := 0; i < cycleLen; i++ { 50 | p2 = p2.Next 51 | } 52 | 53 | // step3 同步移动p1,p2,相遇时即cycle的start node 54 | for p1 != p2 { 55 | p1 = p1.Next 56 | p2 = p2.Next 57 | } 58 | return p1 59 | } 60 | -------------------------------------------------------------------------------- /Pattern14 - K-way merge/Kth_Smallest_Number_in_a_Sorted_Matrix/binary_search_solution.go: -------------------------------------------------------------------------------- 1 | package kthsmallestnumberinasortedmatrix 2 | 3 | func kthSmallestByBinarySearch(matrix [][]int, k int) int { 4 | var ( 5 | n = len(matrix) 6 | start = matrix[0][0] 7 | end = matrix[n-1][n-1] 8 | ) 9 | for start < end { 10 | mid := start + (end-start)/2 11 | pair := Pair{matrix[0][0], matrix[n-1][n-1]} 12 | count := countLessEq(matrix, mid, &pair) 13 | if count == k { 14 | return pair.Small 15 | } 16 | 17 | if count < k { 18 | start = pair.Large 19 | } else { 20 | end = pair.Small 21 | } 22 | } 23 | 24 | return start 25 | } 26 | 27 | func countLessEq(matrix [][]int, mid int, pair *Pair) int { 28 | var ( 29 | count = 0 30 | n = len(matrix) 31 | row = n - 1 32 | col = 0 33 | ) 34 | for row >= 0 && col < n { 35 | if matrix[row][col] > mid { 36 | pair.Large = min(pair.Large, matrix[row][col]) 37 | row-- 38 | } else { 39 | pair.Small = max(pair.Small, matrix[row][col]) 40 | col++ 41 | count += row + 1 42 | } 43 | } 44 | 45 | return count 46 | } 47 | 48 | type Pair struct { 49 | Small int 50 | Large int 51 | } 52 | 53 | func min(x, y int) int { 54 | if x < y { 55 | return x 56 | } 57 | 58 | return y 59 | } 60 | func max(x, y int) int { 61 | if x > y { 62 | return x 63 | } 64 | 65 | return y 66 | } 67 | -------------------------------------------------------------------------------- /Pattern13 - Top K Elements/Top_K_Numbers/solution.go: -------------------------------------------------------------------------------- 1 | package topknumbers 2 | 3 | import "container/heap" 4 | 5 | /* 6 | Given an unsorted array of numbers, find the ‘K’ largest numbers in it. 7 | 8 | Note: For a detailed discussion about different approaches to solve this problem, take a look at Kth Smallest Number. 9 | 10 | Input: [3, 1, 5, 12, 2, 11], K = 3 11 | Output: [5, 12, 11] 12 | 13 | Input: [5, 12, 11, -1, 12], K = 3 14 | Output: [12, 11, 12] 15 | 16 | ref: https://leetcode-cn.com/problems/zui-xiao-de-kge-shu-lcof/ 17 | */ 18 | 19 | type IntHeap []int 20 | 21 | func (h IntHeap) Len() int { return len(h) } 22 | func (h IntHeap) Less(i, j int) bool { return h[i] < h[j] } 23 | func (h IntHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] } 24 | 25 | func (h *IntHeap) Push(x interface{}) { 26 | *h = append(*h, x.(int)) 27 | } 28 | func (h *IntHeap) Pop() interface{} { 29 | old := *h 30 | n := len(old) 31 | x := old[n-1] 32 | *h = old[:n-1] 33 | return x 34 | } 35 | 36 | func getLargestNumbers(arr []int, k int) []int { 37 | var ( 38 | intHeap IntHeap 39 | i = 0 40 | ) 41 | for ; i < k; i++ { 42 | intHeap = append(intHeap, arr[i]) 43 | } 44 | heap.Init(&intHeap) 45 | for ; i < len(arr); i++ { 46 | if arr[i] > intHeap[0] { 47 | heap.Push(&intHeap, arr[i]) 48 | heap.Pop(&intHeap) 49 | } 50 | } 51 | 52 | return intHeap 53 | } 54 | -------------------------------------------------------------------------------- /Pattern08 - Tree DFS/Challenge1-Tree_Diameter/solution.go: -------------------------------------------------------------------------------- 1 | package Challenge1_Tree_Diameter 2 | 3 | /* 4 | Given a binary tree, find the length of its diameter. 5 | The diameter of a tree is the number of nodes on the longest path between any two leaf nodes. 6 | The diameter of a tree may or may not pass through the root. 7 | 8 | Note: You can always assume that there are at least two leaf nodes in the given tree. 9 | 10 | 类似题,但是题意有小区别 11 | https://leetcode-cn.com/problems/diameter-of-binary-tree 12 | */ 13 | 14 | type TreeNode struct { 15 | Val int 16 | Left, Right *TreeNode 17 | } 18 | 19 | func diameterOfBinaryTree(root *TreeNode) int { 20 | var maxDiameter = 0 21 | calculateHeight(root, &maxDiameter) 22 | return maxDiameter 23 | } 24 | 25 | func calculateHeight(node *TreeNode, maxDiameterPtr *int) int { 26 | if node == nil { 27 | return 0 28 | } 29 | 30 | leftTreeH := calculateHeight(node.Left, maxDiameterPtr) 31 | rightTreeH := calculateHeight(node.Right, maxDiameterPtr) 32 | 33 | // 对于没有左子树或者右子树的节点,不去计算其diameter,因为这种情况不存在左子树的叶子到右子树的叶子这样一条路径 34 | if leftTreeH != 0 && rightTreeH != 0 { 35 | diameter := leftTreeH + rightTreeH + 1 36 | if diameter > *maxDiameterPtr { 37 | *maxDiameterPtr = diameter 38 | } 39 | } 40 | 41 | return max(leftTreeH, rightTreeH) + 1 42 | } 43 | 44 | func max(i, j int) int { 45 | if i > j { 46 | return i 47 | } else { 48 | return j 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Pattern07 - Tree BFS/Zigzag_Traversal/solution.go: -------------------------------------------------------------------------------- 1 | package Zigzag_Traversal 2 | 3 | /* 4 | Given a binary tree, populate an array to represent its zigzag level order traversal. 5 | You should populate the values of all nodes of the first level from left to right, 6 | then right to left for the next level and keep alternating in the same manner for the following levels. 7 | */ 8 | 9 | /** 10 | * Definition for a binary tree node. 11 | */ 12 | type TreeNode struct { 13 | Val int 14 | Left, Right *TreeNode 15 | } 16 | 17 | func zigzagLevelOrder(root *TreeNode) [][]int { 18 | if root == nil { 19 | return [][]int{} 20 | } 21 | var ( 22 | result = make([][]int, 0) 23 | queue = make([]*TreeNode, 0) 24 | leftToRight = true 25 | ) 26 | 27 | queue = append(queue, root) 28 | for len(queue) > 0 { 29 | levelSize := len(queue) 30 | levelList := make([]int, levelSize) 31 | for i := 0; i < levelSize; i++ { 32 | curNode := queue[0] 33 | queue = queue[1:] 34 | if curNode.Left != nil { 35 | queue = append(queue, curNode.Left) 36 | } 37 | if curNode.Right != nil { 38 | queue = append(queue, curNode.Right) 39 | } 40 | 41 | if leftToRight { 42 | levelList[i] = curNode.Val 43 | } else { 44 | levelList[levelSize-1-i] = curNode.Val 45 | } 46 | } 47 | leftToRight = !leftToRight 48 | result = append(result, levelList) 49 | } 50 | 51 | return result 52 | } 53 | -------------------------------------------------------------------------------- /Pattern15 - 01 Knapsack/01_Knapsack_Advanced/solution_test.go: -------------------------------------------------------------------------------- 1 | package knapsackadvanced 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func Test_solveKnapsack2(t *testing.T) { 8 | type args struct { 9 | profits []int 10 | weights []int 11 | capacity int 12 | } 13 | tests := []struct { 14 | name string 15 | args args 16 | want int 17 | }{ 18 | {"case1", args{[]int{1, 6, 10, 16}, []int{1, 2, 3, 5}, 7}, 22}, 19 | {"case2", args{[]int{1, 6, 10, 16}, []int{1, 2, 3, 5}, 6}, 17}, 20 | } 21 | for _, tt := range tests { 22 | t.Run(tt.name, func(t *testing.T) { 23 | if got := solveKnapsack2(tt.args.profits, tt.args.weights, tt.args.capacity); got != tt.want { 24 | t.Errorf("solveKnapsack2() = %v, want %v", got, tt.want) 25 | } 26 | }) 27 | } 28 | } 29 | 30 | func Test_solveKnapsack(t *testing.T) { 31 | type args struct { 32 | profits []int 33 | weights []int 34 | capacity int 35 | } 36 | tests := []struct { 37 | name string 38 | args args 39 | want int 40 | }{ 41 | {"case1", args{[]int{1, 6, 10, 16}, []int{1, 2, 3, 5}, 7}, 22}, 42 | {"case2", args{[]int{1, 6, 10, 16}, []int{1, 2, 3, 5}, 6}, 17}, 43 | } 44 | for _, tt := range tests { 45 | t.Run(tt.name, func(t *testing.T) { 46 | if got := solveKnapsack(tt.args.profits, tt.args.weights, tt.args.capacity); got != tt.want { 47 | t.Errorf("solveKnapsack() = %v, want %v", got, tt.want) 48 | } 49 | }) 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Pattern05 - Cyclic Sort/Challenge3-Find_the_First_K_Missing_Positive_Numbers/solution.go: -------------------------------------------------------------------------------- 1 | package Challenge3_Find_the_First_K_Missing_Positive_Numbers 2 | 3 | /* 4 | Given an unsorted array containing numbers and a number ‘k’, find the first ‘k’ missing positive numbers in the array. 5 | 6 | Input: [3, -1, 4, 5, 5], k=3 7 | Output: [1, 2, 6] 8 | Explanation: The smallest missing positive numbers are 1, 2 and 6. 9 | 10 | Input: [2, 3, 4], k=3 11 | Output: [1, 5, 6] 12 | Explanation: The smallest missing positive numbers are 1, 5 and 6. 13 | 14 | Input: [-2, -3, 4], k=2 15 | Output: [1, 2] 16 | Explanation: The smallest missing positive numbers are 1 and 2. 17 | */ 18 | 19 | func findNumbers(nums []int, k int) []int { 20 | var ( 21 | missingNums = make([]int, 0, len(nums)) 22 | i = 0 23 | alreadyExist = make(map[int]int) 24 | ) 25 | for i < len(nums) { 26 | j := nums[i] - 1 27 | if nums[i] > 0 && nums[i] <= len(nums) && nums[i] != nums[j] { 28 | nums[i], nums[j] = nums[j], nums[i] 29 | } else { 30 | i++ 31 | } 32 | } 33 | 34 | for i = 0; i < len(nums) && len(missingNums) < k; i++ { 35 | if nums[i] != i+1 { 36 | missingNums = append(missingNums, i+1) 37 | alreadyExist[nums[i]] = 1 38 | } 39 | } 40 | 41 | for len(missingNums) < k { 42 | if _, ok := alreadyExist[i+1]; !ok { 43 | missingNums = append(missingNums, i+1) 44 | } 45 | i++ 46 | } 47 | 48 | return missingNums 49 | } 50 | -------------------------------------------------------------------------------- /Pattern11 - Modified Binary Search/Ceiling_of_a_Number/solution.go: -------------------------------------------------------------------------------- 1 | package Ceiling_of_a_Number 2 | 3 | /* 4 | Given an array of numbers sorted in an ascending order, find the ceiling of a given number ‘key’. 5 | The ceiling of the ‘key’ will be the smallest element in the given array greater than or equal to the ‘key’. 6 | 7 | Write a function to return the index of the ceiling of the ‘key’. If there isn’t any ceiling return -1. 8 | 9 | Input: [4, 6, 10], key = 6 10 | Output: 1 11 | Explanation: The smallest number greater than or equal to '6' is '6' having index '1'. 12 | 13 | Input: [1, 3, 8, 10, 15], key = 12 14 | Output: 4 15 | Explanation: The smallest number greater than or equal to '12' is '15' having index '4'. 16 | 17 | Input: [4, 6, 10], key = 17 18 | Output: -1 19 | Explanation: There is no number greater than or equal to '17' in the given array. 20 | 21 | Input: [4, 6, 10], key = -1 22 | Output: 0 23 | Explanation: The smallest number greater than or equal to '-1' is '4' having index '0'. 24 | */ 25 | 26 | func searchCeilingOfANumber(arr []int, key int) int { 27 | if arr[len(arr)-1] < key { 28 | return -1 29 | } 30 | var ( 31 | start = 0 32 | end = len(arr) - 1 33 | ) 34 | 35 | for start <= end { 36 | mid := (start + end) / 2 37 | if arr[mid] < key { 38 | start = mid + 1 39 | } else if arr[mid] > key { 40 | end = mid - 1 41 | } else { 42 | return mid 43 | } 44 | } 45 | 46 | return start 47 | } 48 | -------------------------------------------------------------------------------- /Pattern01 - Sliding Window/Longest_Substring_with_K_Distinct_Characters/solution.go: -------------------------------------------------------------------------------- 1 | package Longest_Substring_with_K_Distinct_Characters 2 | 3 | /* 4 | Given a string, find the length of the longest substring in it with no more than K distinct characters. 5 | 6 | Input: String="araaci", K=2 7 | Output: 4 8 | Explanation: The longest substring with no more than '2' distinct characters is "araa". 9 | 10 | Input: String="araaci", K=1 11 | Output: 2 12 | Explanation: The longest substring with no more than '1' distinct characters is "aa". 13 | 14 | Input: String="cbbebi", K=3 15 | Output: 5 16 | Explanation: The longest substrings with no more than '3' distinct characters are "cbbeb" & "bbebi". 17 | */ 18 | 19 | func max(x, y int) int { 20 | if x > y { 21 | return x 22 | } else { 23 | return y 24 | } 25 | } 26 | 27 | func findLength(str string, k int) int { 28 | var ( 29 | maxLength = 0 30 | windowStart = 0 31 | distinctMap = make(map[uint8]int) // record each character appear times of window 32 | ) 33 | 34 | for windowEnd := 0; windowEnd < len(str); windowEnd++ { 35 | curChar := str[windowEnd] 36 | distinctMap[curChar]++ 37 | 38 | for len(distinctMap) > k { 39 | delChar := str[windowStart] 40 | distinctMap[delChar]-- 41 | if distinctMap[delChar] == 0 { 42 | delete(distinctMap, delChar) 43 | } 44 | windowStart++ 45 | } 46 | 47 | maxLength = max(maxLength, windowEnd-windowStart+1) 48 | } 49 | 50 | return maxLength 51 | } 52 | -------------------------------------------------------------------------------- /Pattern11 - Modified Binary Search/Challenge2-Search_in_a_Rotated_Array/solution_test.go: -------------------------------------------------------------------------------- 1 | package challenge2searchinarotatedarray 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func Test_search(t *testing.T) { 8 | type args struct { 9 | nums []int 10 | target int 11 | } 12 | tests := []struct { 13 | name string 14 | args args 15 | want int 16 | }{ 17 | {"case1", args{[]int{4, 5, 6, 7, 0, 1, 2}, 0}, 4}, 18 | {"case2", args{[]int{4, 5, 6, 7, 0, 1, 2}, 3}, -1}, 19 | {"case3", args{[]int{1}, 0}, -1}, 20 | {"case4", args{[]int{10, 15, 1, 3, 8}, 15}, 1}, 21 | {"case5", args{[]int{4, 5, 7, 9, 10, -1, 2}, 10}, 4}, 22 | } 23 | for _, tt := range tests { 24 | t.Run(tt.name, func(t *testing.T) { 25 | if got := search(tt.args.nums, tt.args.target); got != tt.want { 26 | t.Errorf("search() = %v, want %v", got, tt.want) 27 | } 28 | }) 29 | } 30 | } 31 | 32 | func Test_search2(t *testing.T) { 33 | type args struct { 34 | nums []int 35 | target int 36 | } 37 | tests := []struct { 38 | name string 39 | args args 40 | want int 41 | }{ 42 | {"case1", args{[]int{3, 7, 3, 3, 3}, 7}, 1}, 43 | {"case2", args{[]int{2, 5, 6, 0, 0, 1, 2}, 6}, 2}, 44 | {"case3", args{[]int{2, 5, 6, 0, 0, 1, 2}, 3}, -1}, 45 | } 46 | for _, tt := range tests { 47 | t.Run(tt.name, func(t *testing.T) { 48 | if got := search2(tt.args.nums, tt.args.target); got != tt.want { 49 | t.Errorf("search2() = %v, want %v", got, tt.want) 50 | } 51 | }) 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Pattern06 - Reversal of a LinkedList/Challenge2-Rotate_a_LinkedList/solution_test.go: -------------------------------------------------------------------------------- 1 | package Challenge2_Rotate_a_LinkedList 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | "testing" 7 | ) 8 | 9 | func Test_rotate(t *testing.T) { 10 | type args struct { 11 | head *ListNode 12 | k int 13 | } 14 | 15 | head1 := &ListNode{Value: 1} 16 | head1.Next = &ListNode{Value: 2} 17 | node3 := &ListNode{Value: 3} 18 | head1.Next.Next = node3 19 | head1.Next.Next.Next = &ListNode{Value: 4} 20 | head1.Next.Next.Next.Next = &ListNode{Value: 5} 21 | 22 | head2 := &ListNode{Value: 1} 23 | head2.Next = &ListNode{Value: 2} 24 | head2.Next.Next = &ListNode{Value: 3} 25 | node4 := &ListNode{Value: 4} 26 | head2.Next.Next.Next = node4 27 | head2.Next.Next.Next.Next = &ListNode{Value: 5} 28 | head2.Next.Next.Next.Next.Next = &ListNode{Value: 6} 29 | 30 | head3 := &ListNode{Value: 1} 31 | 32 | tests := []struct { 33 | name string 34 | args args 35 | want *ListNode 36 | }{ 37 | {"case1", args{head2, 3}, node4}, 38 | {"case2", args{head1, 8}, node3}, 39 | {"case3", args{head3, 2}, head3}, 40 | } 41 | for _, tt := range tests { 42 | t.Run(tt.name, func(t *testing.T) { 43 | if got := rotate(tt.args.head, tt.args.k); !reflect.DeepEqual(got, tt.want) { 44 | t.Errorf("rotate() = %v, want %v", got, tt.want) 45 | } else { 46 | p := got 47 | for p != nil { 48 | fmt.Printf("%d ", p.Value) 49 | p = p.Next 50 | } 51 | fmt.Println() 52 | } 53 | }) 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Pattern15 - 01 Knapsack/Challenge2-Target_Sum/solution.go: -------------------------------------------------------------------------------- 1 | package Challenge2_Target_Sum 2 | 3 | /* 4 | * Target Sum 5 | You are given a set of positive numbers and a target sum ‘S’. 6 | Each number should be assigned either a ‘+’ or ‘-’ sign. 7 | We need to find the total ways to assign symbols to make the sum of the numbers equal to the target ‘S’. 8 | 9 | Input: {1, 1, 2, 3}, S=1 10 | Output: 3 11 | Explanation: The given set has '3' ways to make a sum of '1': {+1-1-2+3} & {-1+1-2+3} & {+1+1+2-3} 12 | 13 | Input: {1, 2, 7, 1}, S=9 14 | Output: 2 15 | Explanation: The given set has '2' ways to make a sum of '9': {+1+2+7-1} & {-1+2+7+1} 16 | 17 | ref: https://leetcode-cn.com/problems/target-sum/ 18 | */ 19 | 20 | // 21 | // idea: 22 | // Sum(s1) - Sum(s2) = target 23 | // Sum(s1) + Sum(s2) = Sum(num) 24 | // 其中s1中都是+号的数,s2中都是-号的数 25 | // 所以Sum(s1) = (target + Sum(num)) / 2 26 | // 27 | func findTargetSumWays(nums []int, target int) int { 28 | totalSum := 0 29 | for _, v := range nums { 30 | totalSum += v 31 | } 32 | 33 | if totalSum < target || (totalSum+target)%2 != 0 { 34 | return 0 35 | } 36 | 37 | target = (totalSum + target) / 2 38 | 39 | n := len(nums) 40 | dp := make([]int, target+1) 41 | dp[0] = 1 42 | for i := 1; i <= target; i++ { 43 | if nums[0] == i { 44 | dp[i] = 1 45 | } 46 | } 47 | 48 | for i := 1; i < n; i++ { 49 | for s := target; s >= 0; s-- { 50 | if s >= nums[i] { 51 | dp[s] += dp[s-nums[i]] 52 | } 53 | } 54 | } 55 | 56 | return dp[target] 57 | } 58 | -------------------------------------------------------------------------------- /Pattern01 - Sliding Window/Smallest_Subarray_with_a_given_sum/solution.go: -------------------------------------------------------------------------------- 1 | package Smallest_Subarray_with_a_given_sum 2 | 3 | /* 4 | Given an array of positive numbers and a positive number ‘S,’ 5 | find the length of the smallest contiguous subarray whose sum is greater than or equal to ‘S’. 6 | Return 0 if no such subarray exists. 7 | 8 | Input: [2, 1, 5, 2, 3, 2], S=7 9 | Output: 2 10 | Explanation: The smallest subarray with a sum great than or equal to '7' is [5, 2]. 11 | 12 | Input: [2, 1, 5, 2, 8], S=7 13 | Output: 1 14 | Explanation: The smallest subarray with a sum greater than or equal to '7' is [8]. 15 | 16 | Input: [3, 4, 1, 1, 6], S=8 17 | Output: 3 18 | Explanation: Smallest subarrays with a sum greater than or equal to '8' are [3, 4, 1] or [1, 1, 6]. 19 | */ 20 | 21 | func min(x, y int) int { 22 | if x < y { 23 | return x 24 | } else { 25 | return y 26 | } 27 | } 28 | 29 | func findMinSubArray(S int, arr []int) int { 30 | var ( 31 | windowStart = 0 32 | windowSum = 0 33 | smallest = -1 34 | ) 35 | 36 | for windowEnd := 0; windowEnd < len(arr); windowEnd++ { 37 | windowSum += arr[windowEnd] 38 | if windowSum < S { 39 | continue 40 | } 41 | for windowSum >= S { 42 | if smallest == -1 { 43 | smallest = windowEnd - windowStart + 1 44 | } else { 45 | smallest = min(smallest, windowEnd-windowStart+1) 46 | } 47 | windowSum -= arr[windowStart] 48 | windowStart++ 49 | } 50 | } 51 | 52 | if smallest == -1 { 53 | return 0 54 | } 55 | return smallest 56 | } 57 | -------------------------------------------------------------------------------- /Pattern13 - Top K Elements/Sum_of_Elements/solution.go: -------------------------------------------------------------------------------- 1 | package sumofelements 2 | 3 | import ( 4 | "container/heap" 5 | ) 6 | 7 | /* 8 | * Given an array, find the sum of all numbers between the K1’th and K2’th smallest elements of that array. 9 | 10 | Input: [1, 3, 12, 5, 15, 11], and K1=3, K2=6 11 | Output: 23 12 | Explanation: The 3rd smallest number is 5 and 6th smallest number 15. The sum of numbers coming 13 | between 5 and 15 is 23 (11+12). 14 | 15 | Input: [3, 5, 8, 7], and K1=1, K2=4 16 | Output: 12 17 | Explanation: The sum of the numbers between the 1st smallest number (3) and the 4th smallest 18 | number (8) is 12 (5+7). 19 | */ 20 | 21 | func findSumOfElements(nums []int, k1, k2 int) int { 22 | var ( 23 | minh MinHeap 24 | sumOfElems int 25 | ) 26 | 27 | heap.Init(&minh) 28 | for _, v := range nums { 29 | heap.Push(&minh, v) 30 | } 31 | 32 | // pop k1个元素 33 | for i := 0; i < k1; i++ { 34 | heap.Pop(&minh) 35 | } 36 | 37 | // sum k2-k1-1个元素 38 | for i := 0; i < k2-k1-1; i++ { 39 | sumOfElems += heap.Pop(&minh).(int) 40 | } 41 | 42 | return sumOfElems 43 | } 44 | 45 | type MinHeap []int 46 | 47 | func (h MinHeap) Len() int { return len(h) } 48 | func (h MinHeap) Less(i, j int) bool { return h[i] < h[j] } 49 | func (h MinHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] } 50 | func (h *MinHeap) Push(x interface{}) { *h = append(*h, x.(int)) } 51 | func (h *MinHeap) Pop() interface{} { 52 | old := *h 53 | x := old[len(old)-1] 54 | *h = old[:len(old)-1] 55 | return x 56 | } 57 | -------------------------------------------------------------------------------- /Pattern13 - Top K Elements/Top_K_Frequent_Numbers/solution.go: -------------------------------------------------------------------------------- 1 | package topkfrequentnumbers 2 | 3 | import ( 4 | "container/heap" 5 | ) 6 | 7 | /* 8 | Given an unsorted array of numbers, find the top ‘K’ frequently occurring numbers in it. 9 | 10 | Input: [1, 3, 5, 12, 11, 12, 11], K = 2 11 | Output: [12, 11] 12 | Explanation: Both '11' and '12' apeared twice. 13 | 14 | Input: [5, 12, 11, 3, 11], K = 2 15 | Output: [11, 5] or [11, 12] or [11, 3] 16 | Explanation: Only '11' appeared twice, all other numbers appeared once. 17 | 18 | ref: https://leetcode-cn.com/problems/top-k-frequent-elements/ 19 | */ 20 | 21 | type PairHeap [][2]int 22 | 23 | func (ph PairHeap) Len() int { return len(ph) } 24 | func (ph PairHeap) Less(i, j int) bool { return ph[i][1] < ph[j][1] } 25 | func (ph PairHeap) Swap(i, j int) { ph[i], ph[j] = ph[j], ph[i] } 26 | func (ph *PairHeap) Push(x interface{}) { *ph = append(*ph, x.([2]int)) } 27 | func (ph *PairHeap) Pop() interface{} { 28 | old := *ph 29 | n := len(old) 30 | x := old[n-1] 31 | *ph = old[:n-1] 32 | return x 33 | } 34 | 35 | func topKFrequent(nums []int, k int) []int { 36 | var ( 37 | m = make(map[int]int) 38 | ph PairHeap 39 | ) 40 | 41 | for _, v := range nums { 42 | m[v]++ 43 | } 44 | 45 | heap.Init(&ph) 46 | for key, value := range m { 47 | heap.Push(&ph, [2]int{key, value}) 48 | if ph.Len() > k { 49 | heap.Pop(&ph) 50 | } 51 | } 52 | 53 | res := make([]int, 0, k) 54 | for _, v := range ph { 55 | res = append(res, v[0]) 56 | } 57 | 58 | return res 59 | } 60 | -------------------------------------------------------------------------------- /Pattern11 - Modified Binary Search/Challenge3-Rotation_Count/solution_test.go: -------------------------------------------------------------------------------- 1 | package challenge3rotationcount 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func Test_countRotations(t *testing.T) { 8 | type args struct { 9 | arr []int 10 | } 11 | tests := []struct { 12 | name string 13 | args args 14 | want int 15 | }{ 16 | {"case1", args{[]int{10, 15, 1, 3, 8}}, 2}, 17 | {"case2", args{[]int{4, 5, 7, 9, 10, -1, 2}}, 5}, 18 | {"case3", args{[]int{1, 3, 8, 10}}, 0}, 19 | {"case4", args{[]int{10, 1, 3, 8, 9}}, 1}, 20 | } 21 | for _, tt := range tests { 22 | t.Run(tt.name, func(t *testing.T) { 23 | if got := countRotations(tt.args.arr); got != tt.want { 24 | t.Errorf("countRotations() = %v, want %v", got, tt.want) 25 | } 26 | }) 27 | } 28 | } 29 | 30 | func Test_countRotations2(t *testing.T) { 31 | type args struct { 32 | arr []int 33 | } 34 | tests := []struct { 35 | name string 36 | args args 37 | want int 38 | }{ 39 | {"case1", args{[]int{10, 15, 1, 3, 8}}, 2}, 40 | {"case2", args{[]int{4, 5, 7, 9, 10, -1, 2}}, 5}, 41 | {"case3", args{[]int{1, 3, 8, 10}}, 0}, 42 | {"case4", args{[]int{10, 1, 3, 8, 9}}, 1}, 43 | {"case5", args{[]int{3, 3, 7, 3}}, 3}, 44 | {"case6", args{[]int{3, 3, 3, 3, 7}}, 0}, 45 | {"case7", args{[]int{10, 1, 10, 10, 10}}, 1}, 46 | } 47 | for _, tt := range tests { 48 | t.Run(tt.name, func(t *testing.T) { 49 | if got := countRotations2(tt.args.arr); got != tt.want { 50 | t.Errorf("countRotations2() = %v, want %v", got, tt.want) 51 | } 52 | }) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Pattern02 - Two Pointers/Triplet_Sum_Close_to_Target/solution.go: -------------------------------------------------------------------------------- 1 | package Triplet_Sum_Close_to_Target 2 | 3 | import ( 4 | "math" 5 | "sort" 6 | ) 7 | 8 | /* 9 | Given an array of unsorted numbers and a target number, 10 | find a triplet in the array whose sum is as close to the target number as possible, return the sum of the triplet. 11 | If there are more than one such triplet return the sum of the triplet with the smallest sum. 12 | 13 | Input: [-2, 0, 1, 2], target=2 14 | Output: 1 15 | Explanation: The triplet [-2, 1, 2] has the closest sum to the target. 16 | 17 | Input: [-3, -1, 1, 2], target=1 18 | Output: 0 19 | Explanation: The triplet [-3, 1, 2] has the closest sum to the target. 20 | 21 | Input: [1, 0, 1, 1], target=100 22 | Output: 3 23 | Explanation: The triplet [1, 1, 1] has the closest sum to the target. 24 | */ 25 | 26 | func abs(x int) int { 27 | if x < 0 { 28 | x = -x 29 | } 30 | return x 31 | } 32 | 33 | func searchTriplet(arr []int, targetSum int) int { 34 | sort.Ints(arr) 35 | smallestDifference := math.MaxInt8 36 | for i := 0; i < len(arr)-2; i++ { 37 | left, right := i+1, len(arr)-1 38 | for left < right { 39 | targetDiff := targetSum - arr[i] - arr[left] - arr[right] 40 | if targetDiff == 0 { 41 | return targetSum - targetDiff 42 | } 43 | 44 | if abs(targetDiff) < abs(smallestDifference) { 45 | smallestDifference = targetDiff 46 | } 47 | 48 | if targetDiff > 0 { 49 | left++ 50 | } else { 51 | right-- 52 | } 53 | } 54 | } 55 | return targetSum - smallestDifference 56 | } 57 | -------------------------------------------------------------------------------- /Pattern01 - Sliding Window/Longest_Substring_with_Same_Letters_after_Replacement/solution.go: -------------------------------------------------------------------------------- 1 | package Longest_Substring_with_Same_Letters_after_Replacement 2 | 3 | /* 4 | Given a string with lowercase letters only, if you are allowed to replace no more than ‘k’ letters with any letter, 5 | find the length of the longest substring having the same letters after replacement. 6 | 7 | Input: String="aabccbb", k=2 8 | Output: 5 9 | Explanation: Replace the two 'c' with 'b' to have a longest repeating substring "bbbbb". 10 | 11 | Input: String="abbcb", k=1 12 | Output: 4 13 | Explanation: Replace the 'c' with 'b' to have a longest repeating substring "bbbb". 14 | 15 | Input: String="abccde", k=1 16 | Output: 3 17 | Explanation: Replace the 'b' or 'd' with 'c' to have the longest repeating substring "ccc". 18 | */ 19 | 20 | func findLength(str string, k int) int { 21 | var ( 22 | maxLength = 0 23 | windowStart = 0 24 | charMap = make(map[byte]int) // store the times of each characters appear 25 | MaxRepeatNum = 0 26 | ) 27 | 28 | for windowEnd := 0; windowEnd < len(str); windowEnd++ { 29 | curChar := str[windowEnd] 30 | charMap[curChar]++ 31 | MaxRepeatNum = max(charMap[curChar], MaxRepeatNum) 32 | 33 | for windowEnd-windowStart+1-MaxRepeatNum > k { 34 | delChar := str[windowStart] 35 | charMap[delChar]-- 36 | windowStart++ 37 | } 38 | 39 | maxLength = max(maxLength, windowEnd-windowStart+1) 40 | } 41 | 42 | return maxLength 43 | } 44 | 45 | func max(x, y int) int { 46 | if x > y { 47 | return x 48 | } else { 49 | return y 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Pattern10 - Subsets/Challenge1-Evaluate_Expression/solution.go: -------------------------------------------------------------------------------- 1 | package Challenge1_Evaluate_Expression 2 | 3 | import ( 4 | "strconv" 5 | "unicode" 6 | ) 7 | 8 | /* 9 | Given an expression containing digits and operations (+, -, *), 10 | find all possible ways in which the expression can be evaluated by grouping the numbers and operators using parentheses. 11 | 12 | Input: "1+2*3" 13 | Output: 7, 9 14 | Explanation: 1+(2*3) => 7 and (1+2)*3 => 9 15 | 16 | Input: "2*3-4-5" 17 | Output: 8, -12, 7, -7, -3 18 | Explanation: 2*(3-(4-5)) => 8, 2*(3-4-5) => -12, 2*3-(4-5) => 7, 2*(3-4)-5 => -7, (2*3)-4-5 => -3 19 | */ 20 | 21 | func diffWaysToEvaluateExpression(input string) []int { 22 | if v, err := strconv.Atoi(input); err == nil { 23 | return []int{v} 24 | } 25 | m := make(map[string][]int) 26 | var bfs func(string) []int 27 | bfs = func(s string) []int { 28 | if v, ok := m[s]; ok { 29 | return v 30 | } 31 | var ans []int 32 | for i := 0; i < len(input); i++ { 33 | chr := input[i] 34 | if unicode.IsDigit(rune(chr)) == false { 35 | leftPart := diffWaysToEvaluateExpression(input[:i]) 36 | rightPart := diffWaysToEvaluateExpression(input[i+1:]) 37 | 38 | for _, v1 := range leftPart { 39 | for _, v2 := range rightPart { 40 | switch chr { 41 | case '+': 42 | ans = append(ans, v1+v2) 43 | case '-': 44 | ans = append(ans, v1-v2) 45 | case '*': 46 | ans = append(ans, v1*v2) 47 | } 48 | } 49 | } 50 | } 51 | } 52 | m[s] = ans 53 | return ans 54 | } 55 | 56 | return bfs(input) 57 | } 58 | -------------------------------------------------------------------------------- /Pattern04 - Merge Intervals/Intervals_Intersection/solution.go: -------------------------------------------------------------------------------- 1 | package Intervals_Intersection 2 | 3 | /* 4 | Given two lists of intervals, find the intersection of these two lists. 5 | Each list consists of disjoint intervals sorted on their start time. 6 | 7 | Input: arr1=[[1, 3], [5, 6], [7, 9]], arr2=[[2, 3], [5, 7]] 8 | Output: [2, 3], [5, 6], [7, 7] 9 | Explanation: The output list contains the common intervals between the two lists. 10 | 11 | Input: arr1=[[1, 3], [5, 7], [9, 12]], arr2=[[5, 10]] 12 | Output: [5, 7], [9, 10] 13 | Explanation: The output list contains the common intervals between the two lists. 14 | */ 15 | 16 | type Interval struct { 17 | Start int 18 | End int 19 | } 20 | 21 | func min(i, j int) int { 22 | if i < j { 23 | return i 24 | } else { 25 | return j 26 | } 27 | } 28 | 29 | func max(i, j int) int { 30 | if i > j { 31 | return i 32 | } else { 33 | return j 34 | } 35 | } 36 | 37 | func intersection(arr1, arr2 []Interval) []Interval { 38 | var ( 39 | interList = make([]Interval, 0, min(len(arr1), len(arr2))) 40 | i, j = 0, 0 41 | ) 42 | 43 | for i < len(arr1) && j < len(arr2) { 44 | if arr1[i].End < arr2[j].Start { 45 | i++ 46 | continue 47 | } 48 | if arr2[j].End < arr1[i].Start { 49 | j++ 50 | continue 51 | } 52 | // 相交 53 | start := max(arr1[i].Start, arr2[j].Start) 54 | end := min(arr1[i].End, arr2[j].End) 55 | interList = append(interList, Interval{start, end}) 56 | 57 | if arr1[i].End < arr2[j].End { 58 | i++ 59 | } else { 60 | j++ 61 | } 62 | } 63 | 64 | return interList 65 | } 66 | --------------------------------------------------------------------------------