From fe9decd126b1c2e3b690e2d051013a1dd31803c5 Mon Sep 17 00:00:00 2001 From: hapiman <894057870@qq.com> Date: Mon, 6 May 2019 09:47:27 +0800 Subject: [PATCH 1/7] Add 169 --- Week_04/id_117/LeetCode_169_117.go | 54 +++++++++++++++++++++++++ Week_04/id_117/LeetCode_169_117_test.go | 32 +++++++++++++++ Week_04/id_117/NOTE.md | 1 - Week_04/id_117/README.md | 6 +++ 4 files changed, 92 insertions(+), 1 deletion(-) create mode 100644 Week_04/id_117/LeetCode_169_117.go create mode 100644 Week_04/id_117/LeetCode_169_117_test.go delete mode 100644 Week_04/id_117/NOTE.md create mode 100644 Week_04/id_117/README.md diff --git a/Week_04/id_117/LeetCode_169_117.go b/Week_04/id_117/LeetCode_169_117.go new file mode 100644 index 00000000..c3410ae8 --- /dev/null +++ b/Week_04/id_117/LeetCode_169_117.go @@ -0,0 +1,54 @@ +package solution + +/* +169. Majority Element + +Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times. + +You may assume that the array is non-empty and the majority element always exist in the array. + +Example 1: + +Input: [3,2,3] +Output: 3 +Example 2: + +Input: [2,2,1,1,1,2,2] +Output: 2 +*/ + +// 方法一, 直接定义map[int]int来存放数据, 找出出现次数最多的数即可, map的长度为 n/2 + 1, 空间复杂度O(n), 时间复杂度O(n) +func majorityElement(nums []int) int { + mps := make(map[int]int, 0) + numsLen := len(nums) + res := 0 + for _, item := range nums { + mps[item]++ + if mps[item] > numsLen/2 { + res = item + } + } + return res +} + +// 方法二, 分治法思想 +// 摩尔投票法,先假设第一个数过半,并设置count=1,之后遍历剩余数据,如果相同则+1,如果不同则-1; 前提条件是存在元素的个数大于n/2 +func majorityElement2(nums []int) int { + numsLen := len(nums) + if numsLen == 0 { + return 0 + } + majar := nums[0] + count := 1 + for i := 1; i < numsLen; i++ { + if count == 0 { + majar = nums[i] + } + if majar == nums[i] { + count++ + } else { + count-- + } + } + return majar +} diff --git a/Week_04/id_117/LeetCode_169_117_test.go b/Week_04/id_117/LeetCode_169_117_test.go new file mode 100644 index 00000000..7bd4b747 --- /dev/null +++ b/Week_04/id_117/LeetCode_169_117_test.go @@ -0,0 +1,32 @@ +package solution + +import ( + "testing" +) + +func Test_eventualSafeNodes(t *testing.T) { + testData := []map[string]interface{}{ + map[string]interface{}{ + "name": "test1", + "ins": []int{3, 2, 3}, + "outs": 3, + }, + map[string]interface{}{ + "name": "test1", + "ins": []int{2, 2, 1, 1, 1, 2, 2}, + "outs": 2, + }, + } + for _, tt := range testData { + name := tt["name"].(string) + ins := tt["ins"].([]int) + outs := tt["outs"].(int) + t.Run(name, func(t *testing.T) { + got := majorityElement2(ins) + eq := got == outs + if !eq { + t.Errorf("eventualSafeNodes() = %v, want %v", got, outs) + } + }) + } +} diff --git a/Week_04/id_117/NOTE.md b/Week_04/id_117/NOTE.md deleted file mode 100644 index c684e62f..00000000 --- a/Week_04/id_117/NOTE.md +++ /dev/null @@ -1 +0,0 @@ -# 学习笔记 \ No newline at end of file diff --git a/Week_04/id_117/README.md b/Week_04/id_117/README.md new file mode 100644 index 00000000..dac36e6f --- /dev/null +++ b/Week_04/id_117/README.md @@ -0,0 +1,6 @@ +# 学习笔记 + +### 169 +方法一, 直接定义map[int]int来存放数据, 找出出现次数最多的数即可, map的长度为 n/2 + 1, 空间复杂度O(n), 时间复杂度O(n) + +方法二, 分治法思想, 摩尔投票法,先假设第一个数过半,并设置count=1,之后遍历剩余数据,如果相同则+1,如果不同则-1; 前提条件是存在元素的个数大于n/2 From 3caca3eb6e2150abb7f952d00693492d08c04a35 Mon Sep 17 00:00:00 2001 From: hapiman <894057870@qq.com> Date: Fri, 10 May 2019 11:22:57 +0800 Subject: [PATCH 2/7] Add 241 --- Week_04/id_117/LeetCode_241_117.go | 103 ++++++++++++++++++++++++ Week_04/id_117/LeetCode_241_117_test.go | 40 +++++++++ Week_04/id_117/README.md | 7 ++ 3 files changed, 150 insertions(+) create mode 100644 Week_04/id_117/LeetCode_241_117.go create mode 100644 Week_04/id_117/LeetCode_241_117_test.go diff --git a/Week_04/id_117/LeetCode_241_117.go b/Week_04/id_117/LeetCode_241_117.go new file mode 100644 index 00000000..0752f32f --- /dev/null +++ b/Week_04/id_117/LeetCode_241_117.go @@ -0,0 +1,103 @@ +package solution + +import ( + "fmt" + "strconv" +) + +/* +241. Different Ways to Add Parentheses + +Given a string of numbers and operators, return all possible results from computing all the different possible ways to group numbers and operators. The valid operators are +, - and *. + +Example 1: + +Input: "2-1-1" +Output: [0, 2] +Explanation: +((2-1)-1) = 0 +(2-(1-1)) = 2 +Example 2: + +Input: "2*3-4*5" +Output: [-34, -14, -10, -10, 10] +Explanation: +(2*(3-(4*5))) = -34 +((2*3)-(4*5)) = -14 +((2*(3-4))*5) = -10 +(2*((3-4)*5)) = -10 +(((2*3)-4)*5) = 10 +*/ + +/* +方法1,直接for遍历,然后根据运算符来执行判断, 为了减少计算次数,最好使用map来保存已经计算的值 +*/ + +func diffWaysToCompute(input string) []int { + ans := make([]int, 0) + for i := 0; i < len(input); i++ { + if input[i] == '-' || input[i] == '+' || input[i] == '*' { + parts1 := input[0:i] + parts2 := input[i+1:] + parts1Res := diffWaysToCompute(parts1) + parts2Res := diffWaysToCompute(parts2) + for _, m := range parts1Res { + for _, n := range parts2Res { + c := 0 + if input[i] == '*' { + c = m * n + } + if input[i] == '+' { + c = m + n + } + if input[i] == '-' { + c = m - n + } + ans = append(ans, c) + } + } + } + } + + if len(ans) == 0 { + x, _ := strconv.Atoi(input) + ans = append(ans, x) + } + + return ans +} + +/* +分析: +1.有多少个运算符就有多少个括号 +2.从第一个数开始递归查找,每一个运算符都有两种方式 +3.表达式如何存储? +*/ +func diffWaysToCompute2(input string) []int { + exps := make([]string, 0) // 表达式 + ans := make([]int, 0) // 表达式计算值 + curStr := input + compute(input, &exps, curStr) + return ans +} + +func compute(input string, exps *[]string, curStr string) { + // 主逻辑, 每次去掉一个数字和运算符 + symbolNum := len(input) / 2 + if symbolNum == 1 { + return + } + fmt.Println("curStr ====>", curStr) + // 左边第一个数加i+1个括号 + for i := 0; i < symbolNum; i++ { + curStr = fmt.Sprintf("(%s)", curStr) + fmt.Println("curStr ===>", curStr) + compute(input[2:], exps, curStr) + } +} + +/* +设想: +1.是否可以将操作符和数字分别取出来,然后计算 +2.是否可以使用动态规划来实现,在某一个数字的组合种类为前面组合种类递推 +*/ diff --git a/Week_04/id_117/LeetCode_241_117_test.go b/Week_04/id_117/LeetCode_241_117_test.go new file mode 100644 index 00000000..f650b9c7 --- /dev/null +++ b/Week_04/id_117/LeetCode_241_117_test.go @@ -0,0 +1,40 @@ +package solution + +import ( + "reflect" + "sort" + "testing" +) + +func Test_diffWaysToCompute(t *testing.T) { + testData := []map[string]interface{}{ + map[string]interface{}{ + "name": "test1", + "ins": "2-1-1", + "outs": []int{0, 2}, + }, + map[string]interface{}{ + "name": "test1", + "ins": "2*3-4*5", + "outs": []int{-34, -14, -10, -10, 10}, + }, + map[string]interface{}{ + "name": "test1", + "ins": "2-1", + "outs": []int{1}, + }, + } + for _, tt := range testData { + name := tt["name"].(string) + ins := tt["ins"].(string) + outs := tt["outs"].([]int) + t.Run(name, func(t *testing.T) { + got := diffWaysToCompute(ins) + sort.Ints(got) + eq := reflect.DeepEqual(got, outs) + if !eq { + t.Errorf("eventualSafeNodes() = %v, want %v", got, outs) + } + }) + } +} diff --git a/Week_04/id_117/README.md b/Week_04/id_117/README.md index dac36e6f..2f136c42 100644 --- a/Week_04/id_117/README.md +++ b/Week_04/id_117/README.md @@ -4,3 +4,10 @@ 方法一, 直接定义map[int]int来存放数据, 找出出现次数最多的数即可, map的长度为 n/2 + 1, 空间复杂度O(n), 时间复杂度O(n) 方法二, 分治法思想, 摩尔投票法,先假设第一个数过半,并设置count=1,之后遍历剩余数据,如果相同则+1,如果不同则-1; 前提条件是存在元素的个数大于n/2 + +### 241 +方法一,直接for遍历,然后根据运算符来执行判断, 这里的收获是在每一层定义ans来保存当前的原始值或者计算值 + +方法二,使用动态规划,定义dp为三维数组dp[][][]int + +方法三,希望能够将每一个表达式计算出来,但是不知如何保存 From b6da5ca45af606f935bedd9376d8833823184f62 Mon Sep 17 00:00:00 2001 From: hapiman <894057870@qq.com> Date: Fri, 10 May 2019 13:03:34 +0800 Subject: [PATCH 3/7] Add 784 --- Week_04/id_117/LeetCode_241_117.go | 4 +- Week_04/id_117/LeetCode_784_117.go | 49 +++++++++++++++++++++++++ Week_04/id_117/LeetCode_784_117_test.go | 46 +++++++++++++++++++++++ Week_04/id_117/README.md | 3 ++ 4 files changed, 100 insertions(+), 2 deletions(-) create mode 100644 Week_04/id_117/LeetCode_784_117.go create mode 100644 Week_04/id_117/LeetCode_784_117_test.go diff --git a/Week_04/id_117/LeetCode_241_117.go b/Week_04/id_117/LeetCode_241_117.go index 0752f32f..05ac6d8a 100644 --- a/Week_04/id_117/LeetCode_241_117.go +++ b/Week_04/id_117/LeetCode_241_117.go @@ -39,8 +39,8 @@ func diffWaysToCompute(input string) []int { if input[i] == '-' || input[i] == '+' || input[i] == '*' { parts1 := input[0:i] parts2 := input[i+1:] - parts1Res := diffWaysToCompute(parts1) - parts2Res := diffWaysToCompute(parts2) + parts1Res := diffWaysToCompute(parts1) // [2, 33]结果 + parts2Res := diffWaysToCompute(parts2) // [2, 1]结果 for _, m := range parts1Res { for _, n := range parts2Res { c := 0 diff --git a/Week_04/id_117/LeetCode_784_117.go b/Week_04/id_117/LeetCode_784_117.go new file mode 100644 index 00000000..e2523f3d --- /dev/null +++ b/Week_04/id_117/LeetCode_784_117.go @@ -0,0 +1,49 @@ +package solution + +import ( + "strings" +) + +/* +784. Letter Case Permutation + +Given a string S, we can transform every letter individually to be lowercase or uppercase to create another string. Return a list of all possible strings we could create. + +Examples: +Input: S = "a1b2" +Output: ["a1b2", "a1B2", "A1b2", "A1B2"] + +Input: S = "3z4" +Output: ["3z4", "3Z4"] + +Input: S = "12345" +Output: ["12345"] +Note: + +S will be a string with length between 1 and 12. +S will consist only of letters or digits. +*/ + +func letterCasePermutation(S string) []string { + // 先转化为小写 + S = strings.ToLower(S) + mps := make(map[string]string) + permute(S, mps) + ans := make([]string, 0) + for _, v := range mps { + ans = append(ans, v) + } + return ans +} + +func permute(s string, m map[string]string) { + if _, ok := m[s]; !ok { + m[s] = s + for i := 0; i < len(s); i++ { + temp := s + temp = string(temp[0:i]) + strings.ToUpper(string(temp[i])) + string(temp[i+1:]) + temp = strings.TrimSpace(temp) + permute(temp, m) + } + } +} diff --git a/Week_04/id_117/LeetCode_784_117_test.go b/Week_04/id_117/LeetCode_784_117_test.go new file mode 100644 index 00000000..c0586298 --- /dev/null +++ b/Week_04/id_117/LeetCode_784_117_test.go @@ -0,0 +1,46 @@ +package solution + +import ( + "reflect" + "sort" + "testing" +) + +func Test_letterCasePermutation(t *testing.T) { + testData := []map[string]interface{}{ + map[string]interface{}{ + "name": "test1", + "ins": "a1b2", + "outs": []string{"a1b2", "a1B2", "A1b2", "A1B2"}, + }, + map[string]interface{}{ + "name": "test2", + "ins": "3z4", + "outs": []string{"3z4", "3Z4"}, + }, + map[string]interface{}{ + "name": "test3", + "ins": "12345", + "outs": []string{"12345"}, + }, + map[string]interface{}{ + "name": "test1", + "ins": "a1b2c", + "outs": []string{"a1b2c", "a1B2c", "A1b2c", "a1b2C", "A1B2c", "a1B2C", "A1b2C", "A1B2C"}, + }, + } + for _, tt := range testData { + name := tt["name"].(string) + ins := tt["ins"].(string) + outs := tt["outs"].([]string) + t.Run(name, func(t *testing.T) { + got := letterCasePermutation(ins) + sort.Strings(got) + sort.Strings(outs) + eq := reflect.DeepEqual(got, outs) + if !eq { + t.Errorf("eventualSafeNodes() = %v, want %v", got, outs) + } + }) + } +} diff --git a/Week_04/id_117/README.md b/Week_04/id_117/README.md index 2f136c42..e54bded8 100644 --- a/Week_04/id_117/README.md +++ b/Week_04/id_117/README.md @@ -11,3 +11,6 @@ 方法二,使用动态规划,定义dp为三维数组dp[][][]int 方法三,希望能够将每一个表达式计算出来,但是不知如何保存 + +### 784 +方法一, 使用`map[string]string`存储已经变换的字符串 From cfb08bb5f5f7fd62d237b57f3e615a9fcd05b818 Mon Sep 17 00:00:00 2001 From: hapiman <894057870@qq.com> Date: Fri, 10 May 2019 13:16:59 +0800 Subject: [PATCH 4/7] Add method 2 --- Week_04/id_117/LeetCode_784_117.go | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/Week_04/id_117/LeetCode_784_117.go b/Week_04/id_117/LeetCode_784_117.go index e2523f3d..087c3d3b 100644 --- a/Week_04/id_117/LeetCode_784_117.go +++ b/Week_04/id_117/LeetCode_784_117.go @@ -24,6 +24,7 @@ S will be a string with length between 1 and 12. S will consist only of letters or digits. */ +// 方法一,必须要先转换大小写 func letterCasePermutation(S string) []string { // 先转化为小写 S = strings.ToLower(S) @@ -47,3 +48,26 @@ func permute(s string, m map[string]string) { } } } + +// 方法二,节省了转化大小写的时间,直接分别递归 +func letterCasePermutation2(s string) []string { + ans := make([]string, 0) + formatString(s, 0, "", &ans) + return ans +} + +func formatString(s string, i int, prevString string, ans *[]string) { + if i >= len(s) { + *ans = append(*ans, prevString) + return + } + if s[i] >= 48 && s[i] <= 57 { + formatString(s, i+1, prevString+string(s[i]), ans) + } else if s[i] >= 65 && s[i] <= 90 { + formatString(s, i+1, prevString+string(s[i]+byte(32)), ans) + formatString(s, i+1, prevString+string(s[i]), ans) + } else { + formatString(s, i+1, prevString+string(s[i]-byte(32)), ans) + formatString(s, i+1, prevString+string(s[i]), ans) + } +} From 686241a2f4469dff3b4c39aaafc516fa7633ca6e Mon Sep 17 00:00:00 2001 From: hapiman <894057870@qq.com> Date: Sun, 12 May 2019 11:18:30 +0800 Subject: [PATCH 5/7] Add 211 --- Week_04/id_117/LeetCode_211_117.go | 131 ++++++++++++++++++++++++ Week_04/id_117/LeetCode_211_117_test.go | 36 +++++++ Week_04/id_117/README.md | 62 +++++++++++ 3 files changed, 229 insertions(+) create mode 100644 Week_04/id_117/LeetCode_211_117.go create mode 100644 Week_04/id_117/LeetCode_211_117_test.go diff --git a/Week_04/id_117/LeetCode_211_117.go b/Week_04/id_117/LeetCode_211_117.go new file mode 100644 index 00000000..61c0c0f1 --- /dev/null +++ b/Week_04/id_117/LeetCode_211_117.go @@ -0,0 +1,131 @@ +package solution + +/* +211. Add and Search Word - Data structure design + +Design a data structure that supports the following two operations: + +void addWord(word) +bool search(word) +search(word) can search a literal word or a regular expression string containing only letters a-z or .. A . means it can represent any one letter. + +Example: + +addWord("bad") +addWord("dad") +addWord("mad") +search("pad") -> false +search("bad") -> true +search(".ad") -> true +search("b..") -> true +Note: +You may assume that all words are consist of lowercase letters a-z. +*/ + +/** + * 测试案例 + * Your WordDictionary object will be instantiated and called as such: + * obj := Constructor(); + * obj.AddWord(word); + * param_2 := obj.Search(word); + */ + +// 方法一 +type WordDictionary struct { + Words map[int][]string +} + +/** Initialize your data structure here. */ +func Constructor() WordDictionary { + return WordDictionary{Words: make(map[int][]string)} +} + +/** Adds a word into the data structure. */ +func (this *WordDictionary) AddWord(word string) { + m := len(word) + if len(this.Words[m]) > 0 { + this.Words[m] = append(this.Words[m], word) + } else { + this.Words[m] = []string{word} + } +} + +/** Returns if the word is in the data structure. A word could contain the dot character '.' to represent any one letter. */ +func (this *WordDictionary) Search(word string) bool { + m := len(word) + if this.Words[m] == nil { + return false + } + // 当前列表中元素 + w := len(this.Words[m]) + for i := 0; i < w; i++ { + tmp := true + for j := 0; j < m; j++ { + if word[j] != '.' && word[j] != this.Words[m][i][j] { + tmp = false + continue + } + } + if tmp { + return true + } + } + + return false +} + +// 方法二 +type WordDictionary2 struct { + children map[rune]*WordDictionary2 + isWord bool +} + +/** Initialize your data structure here. */ +func Constructor2() WordDictionary2 { + return WordDictionary2{children: make(map[rune]*WordDictionary2)} +} + +/** Adds a word into the data structure. */ +func (this *WordDictionary2) AddWord2(word string) { + parent := this + for _, v := range word { + // 判断是否已存储在树中 + if child, ok := parent.children[v]; !ok { + newDic := &WordDictionary2{ + children: make(map[rune]*WordDictionary2), + isWord: false, + } + parent.children[v] = newDic + parent = newDic + } else { + parent = child + } + } + parent.isWord = true +} + +/** Returns if the word is in the data structure. A word could contain the dot character '.' to represent any one letter. */ +func (this *WordDictionary2) Search2(word string) bool { + parent := this + wLen := len(word) + for i := 0; i < wLen; i++ { + if word[i] == '.' { + // 递归查找 + mapStatus := false + for _, v := range parent.children { + if v.Search2(word[i+1:]) { + mapStatus = true + } + } + return mapStatus + } else { + // 非.字符直接判读 + if _, ok := parent.children[rune(word[i])]; !ok { + return false + } + } + // 移动指针 + parent = parent.children[rune(word[i])] + } + return len(parent.children) == 0 || parent.isWord +} diff --git a/Week_04/id_117/LeetCode_211_117_test.go b/Week_04/id_117/LeetCode_211_117_test.go new file mode 100644 index 00000000..f2c6f673 --- /dev/null +++ b/Week_04/id_117/LeetCode_211_117_test.go @@ -0,0 +1,36 @@ +package solution + +import ( + "testing" +) + +func Test_Search(t *testing.T) { + testData := []map[string]interface{}{ + map[string]interface{}{ + "name": "test1", + "ins": []string{"bad", "dad", "mad"}, + "finds": []string{"pad", "bad", ".ad", "b.."}, + "outs": []bool{false, true, true, true}, + }, + } + + for _, tt := range testData { + name := tt["name"].(string) + finds := tt["finds"].([]string) + ins := tt["ins"].([]string) + outs := tt["outs"].([]bool) + t.Run(name, func(t *testing.T) { + obj := Constructor2() + for _, word := range ins { + obj.AddWord2(word) + } + for k, word := range finds { + + got := obj.Search2(word) + if got != outs[k] { + t.Errorf("Search got= %v, want %v, k=%d", got, outs[k], k) + } + } + }) + } +} diff --git a/Week_04/id_117/README.md b/Week_04/id_117/README.md index e54bded8..3b41466d 100644 --- a/Week_04/id_117/README.md +++ b/Week_04/id_117/README.md @@ -14,3 +14,65 @@ ### 784 方法一, 使用`map[string]string`存储已经变换的字符串 + +### 211 +方法一,使用暴力破解法,使用`map[int][]string`将长度相同的单词存放在一起,比较简单 +方法二,使用`Trie`树(前缀树) + +`Trie`树特点: +1.根节点不包含字符,除根节点外的每一个子节点都包含一个字符。 +2.从根节点到某一个节点,路径上经过的字符连接起来,为该节点对应的字符串。 +3.每个节点的所有子节点包含的字符互不相同。 + +关键点在于构建和查找 +```go +type WordDictionary struct { + // 使用某一层数据 + children map[rune]*WordDictionary + isWord bool +} + + +/** Initialize your data structure here. */ +func Constructor() WordDictionary { + return WordDictionary{children:make(map[rune]*WordDictionary)} +} + + +/** Adds a word into the data structure. */ +func (this *WordDictionary) AddWord(word string) { + parent := this + for _,ch := range word { + if child,ok:= parent.children[ch];ok { + parent = child + } else { + newChild := &WordDictionary{children:make(map[rune]*WordDictionary)} + parent.children[ch] = newChild + // 下一层 + parent = newChild + } + } + parent.isWord = true +} + + +/** Returns if the word is in the data structure. A word could contain the dot character '.' to represent any one letter. */ +func (this *WordDictionary) Search(word string) bool { + parent := this + for i,ch := range word { + if rune(ch) == '.' { + isMatched := false + for _,v := range parent.children { + if v.Search(word[i+1:]) { + isMatched = true + } + } + return isMatched + } else if _,ok := parent.children[rune(ch)];!ok { + return false + } + parent = parent.children[rune(ch)] + } + return len(parent.children) ==0 || parent.isWord +} +``` From 3f5dd33c4558606f40f259f74fd48b10439a8e8d Mon Sep 17 00:00:00 2001 From: hapiman <894057870@qq.com> Date: Sun, 12 May 2019 18:52:35 +0800 Subject: [PATCH 6/7] Add 746 --- Week_04/id_117/LeetCode_746_117.go | 47 +++++++++++++++++++++++++ Week_04/id_117/LeetCode_746_117_test.go | 43 ++++++++++++++++++++++ 2 files changed, 90 insertions(+) create mode 100644 Week_04/id_117/LeetCode_746_117.go create mode 100644 Week_04/id_117/LeetCode_746_117_test.go diff --git a/Week_04/id_117/LeetCode_746_117.go b/Week_04/id_117/LeetCode_746_117.go new file mode 100644 index 00000000..ff06ac56 --- /dev/null +++ b/Week_04/id_117/LeetCode_746_117.go @@ -0,0 +1,47 @@ +package solution + +/* +746. Min Cost Climbing Stairs + +On a staircase, the i-th step has some non-negative cost cost[i] assigned (0 indexed). + +Once you pay the cost, you can either climb one or two steps. You need to find minimum cost to reach the top of the floor, and you can either start from the step with index 0, or the step with index 1. + +Example 1: +Input: cost = [10, 15, 20] +Output: 15 +Explanation: Cheapest is start on cost[1], pay that cost and go to the top. +Example 2: +Input: cost = [1, 100, 1, 1, 1, 100, 1, 1, 100, 1] +Output: 6 +Explanation: Cheapest is start on cost[0], and only step on 1s, skipping cost[3]. +Note: +cost will have a length in the range [2, 1000]. +Every cost[i] will be an integer in the range [0, 999]. + +*/ + +func getSm(a, b int) int { + if a > b { + return b + } + return a +} + +func minCostClimbingStairs(cost []int) int { + costLen := len(cost) + if costLen == 0 { + return -1 + } + if costLen == 1 { + return cost[0] + } + + dp := make([]int, costLen+1) + dp[0] = cost[0] + dp[1] = cost[1] + for i := 2; i < costLen; i++ { + dp[i] = getSm(dp[i-1], dp[i-2]) + cost[i] + } + return getSm(dp[costLen-1], dp[costLen-2]) +} diff --git a/Week_04/id_117/LeetCode_746_117_test.go b/Week_04/id_117/LeetCode_746_117_test.go new file mode 100644 index 00000000..1325f643 --- /dev/null +++ b/Week_04/id_117/LeetCode_746_117_test.go @@ -0,0 +1,43 @@ +package solution + +import ( + "reflect" + "testing" +) + +/* +Example 1: +Input: cost = [10, 15, 20] +Output: 15 +Explanation: Cheapest is start on cost[1], pay that cost and go to the top. +Example 2: +Input: cost = [1, 100, 1, 1, 1, 100, 1, 1, 100, 1] +Output: 6 +Explanation: Cheapest is start on cost[0], and only step on 1s, skipping cost[3]. +*/ +func Test_letterCasePermutation(t *testing.T) { + testData := []map[string]interface{}{ + map[string]interface{}{ + "name": "test1", + "ins": []int{10, 15, 20}, + "outs": 15, + }, + map[string]interface{}{ + "name": "test2", + "ins": []int{1, 100, 1, 1, 1, 100, 1, 1, 100, 1}, + "outs": 6, + }, + } + for _, tt := range testData { + name := tt["name"].(string) + ins := tt["ins"].([]int) + outs := tt["outs"].(int) + t.Run(name, func(t *testing.T) { + got := minCostClimbingStairs(ins) + eq := reflect.DeepEqual(got, outs) + if !eq { + t.Errorf("minCostClimbingStairs() = %v, want %v", got, outs) + } + }) + } +} From beed8bfd9e8738ed9c93bae28b495b989bda4609 Mon Sep 17 00:00:00 2001 From: hapiman <894057870@qq.com> Date: Tue, 14 May 2019 15:47:46 +0800 Subject: [PATCH 7/7] Add 309 --- Week_04/id_117/LeetCode_309_117.go | 51 +++++++++++++++++++++++++ Week_04/id_117/LeetCode_309_117_test.go | 32 ++++++++++++++++ 2 files changed, 83 insertions(+) create mode 100644 Week_04/id_117/LeetCode_309_117.go create mode 100644 Week_04/id_117/LeetCode_309_117_test.go diff --git a/Week_04/id_117/LeetCode_309_117.go b/Week_04/id_117/LeetCode_309_117.go new file mode 100644 index 00000000..cbb6227d --- /dev/null +++ b/Week_04/id_117/LeetCode_309_117.go @@ -0,0 +1,51 @@ +package solution + +/* +309. Best Time to Buy and Sell Stock with Cooldown + +Say you have an array for which the ith element is the price of a given stock on day i. + +Design an algorithm to find the maximum profit. You may complete as many transactions as you like (ie, buy one and sell one share of the stock multiple times) with the following restrictions: + +You may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again). +After you sell your stock, you cannot buy stock on next day. (ie, cooldown 1 day) +Example: + +Input: [1,2,3,0,2] +Output: 3 +Explanation: transactions = [buy, sell, cooldown, buy, sell] +*/ +/* +解题思路: +prices := [1,2,3,0,2] +1.第i天买股票能够剩下的最大利润 +(1)第i-1天买股票能够剩下的最大利润, 即第i天冷冻 +(2)第i-2天卖股票剩余的最大利润 - 第i天买股票能够剩下的最大利润 +公式: buy[i] = max(buy[i-1], sell[i-2] - prices[i-1]) +2.第i天卖股票能够剩下的最大利润 +(1)第i-1天卖股票能够剩下的最大利润, 即第i天冷冻 +(2)第i天卖股票的钱 + 第i-1天买股票剩余的最大利润 +公式: sell[i] = max(sell[i-1], buy[i-1] + prices[i-1]) +3.初始化设置buy[1]= prices[0], 默认第1天就开始买, 如果第2天是较低价格, 则会重新设置 +*/ + +func getMax(a, b int) int { + if a > b { + return a + } + return b +} +func maxProfit(prices []int) int { + pLen := len(prices) + if pLen <= 0 { + return 0 + } + sell := make([]int, pLen+1) + buy := make([]int, pLen+1) + buy[1] = -prices[0] + for i := 2; i <= pLen; i++ { + buy[i] = getMax(buy[i-1], sell[i-2]-prices[i-1]) + sell[i] = getMax(sell[i-1], buy[i-1]+prices[i-1]) + } + return sell[pLen] +} diff --git a/Week_04/id_117/LeetCode_309_117_test.go b/Week_04/id_117/LeetCode_309_117_test.go new file mode 100644 index 00000000..e6381f61 --- /dev/null +++ b/Week_04/id_117/LeetCode_309_117_test.go @@ -0,0 +1,32 @@ +package solution + +import ( + "testing" +) + +func Test_maxProfit(t *testing.T) { + testData := []map[string]interface{}{ + map[string]interface{}{ + "name": "test1", + "ins": []int{1, 2, 3, 0, 2}, + "outs": 3, + }, + map[string]interface{}{ + "name": "test2", + "ins": []int{100, 99, 88, 77, 66, 55, 44}, + "outs": 0, + }, + } + for _, tt := range testData { + name := tt["name"].(string) + ins := tt["ins"].([]int) + outs := tt["outs"].(int) + t.Run(name, func(t *testing.T) { + got := maxProfit(ins) + eq := (got == outs) + if !eq { + t.Errorf("maxProfit() = %v, want %v", got, outs) + } + }) + } +}