diff --git a/README.md b/README.md index 3ac6234..18452fb 100644 --- a/README.md +++ b/README.md @@ -78,6 +78,9 @@ continually updating 😃. * [435. Non-overlapping Intervals](./src/0435_non_overlapping_intervals/greedy_solution.go)   *`greedy;`*  *`dynamic programming`* * [455. Assign Cookies](./src/0455_assign_cookies/assign_cookies.go) +### Backtracking +* [77. Combinations](src/0077_combinations/combinations.go)   *`combine`* + ### Binary Tree * [94. Binary Tree Inorder Traversal](./src/0094_binary_tree_inorder_traversal/binary_tree_inorder_traversal.go)   *`stack`* * [100. Same Tree](./src/0100_same_tree/same_tree.go)   *`dfs`* diff --git a/src/0077_combinations/combinations.go b/src/0077_combinations/combinations.go new file mode 100644 index 0000000..04e7067 --- /dev/null +++ b/src/0077_combinations/combinations.go @@ -0,0 +1,40 @@ +/* +77. Combinations +https://leetcode.com/problems/combinations/ + +Given two integers n and k, return all possible combinations of k numbers out of 1 ... n. +*/ +// time: 2019-01-04 + +package combinations + +// backtracking +// time complexity: O(n^k) +// space complexity: O(k) +func combine(n int, k int) [][]int { + if n <= 0 || k <= 0 || k > n { + return [][]int{} + } + res := make([][]int, 0) + c := make([]int, 0, k) + generateCombinations(n, k, 1, c, &res) + return res +} + +// 求解C(n,k), 当前已经找到的组合存储在c中,需要从start开始搜索新元素。 +func generateCombinations(n, k, start int, c []int, res *[][]int) { + if len(c) == k { + cpy := make([]int, k) + copy(cpy, c) + *res = append(*res, cpy) + return + } + // 回朔法剪枝。 + // 还有k - len(c)个空位,所以, [i...n]中至少要有k - len(c)个元素 + // i最多为n-(k-len(c))+1 + for i := start; i <= n-(k-len(c))+1; i++ { + c = append(c, i) + generateCombinations(n, k, i+1, c, res) + c = c[:len(c)-1] + } +} diff --git a/src/0077_combinations/combinations_test.go b/src/0077_combinations/combinations_test.go new file mode 100644 index 0000000..72b1b0f --- /dev/null +++ b/src/0077_combinations/combinations_test.go @@ -0,0 +1,31 @@ +package combinations + +import ( + "reflect" + "testing" +) + +func TestCombine(t *testing.T) { + type arg struct { + n, k int + } + + testCases := []arg{ + {n: 0, k: 2}, + {n: 2, k: 0}, + {n: 1, k: 5}, + {n: 4, k: 2}, + } + expected := [][][]int{ + {}, + {}, + {}, + {{1, 2}, {1, 3}, {1, 4}, {2, 3}, {2, 4}, {3, 4}}, + } + + for index, data := range testCases { + if res := combine(data.n, data.k); !reflect.DeepEqual(res, expected[index]) { + t.Errorf("expected %v, got %v", expected[index], res) + } + } +} diff --git a/src/README.md b/src/README.md index c7f9953..45dd9d4 100644 --- a/src/README.md +++ b/src/README.md @@ -37,6 +37,7 @@ |0070|[Climbing Stairs](./0070_climbing_stairs/climbing_stairs.go)|Easy|*`dynamic programming`*| |0075|[75. Sort Colors](0075_sort_colors/sort_colors.go)|Medium|*`sort`*| |0076|[Minimum Window Substring](./0076_minimum_window_substring/minimum_window_substring.go)|Hard|*`sliding window`*| +|0077|[77. Combinations](0077_combinations/combinations.go)|Medium|*`backtracking;`**`combine`*| |0080|[80. Remove Duplicates from Sorted Array II](0080_remove_duplicates_from_sorted_array2/rdfsa2.go)|Medium|*`double index`*| |0088|[88. Merge Sorted Array](0088_merge_sorted_array/msa.go)|Easy|*`sort`*| |0094|[Binary Tree Inorder Traversal](./0094_binary_tree_inorder_traversal/binary_tree_inorder_traversal.go)|Medium|*`binary tree`*|