diff --git a/README.md b/README.md index 408f37d07..a65db5ff1 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,8 @@ LeetCode of algorithms with golang solution(updating:smiley:).
-
-
+
+
diff --git a/lib/lru/lru.go b/lib/lru/lru.go new file mode 100644 index 000000000..81eee4373 --- /dev/null +++ b/lib/lru/lru.go @@ -0,0 +1,79 @@ +package lru + +import "container/list" + +// Cache is a LRU cache. It is not safe for concurrent access. +type Cache struct { + maxBytes int64 + nbytes int64 + ll *list.List + cache map[string]*list.Element + // optional and executed when an entry is purged. + OnEvicted func(key string, value Value) +} + +type entry struct { + key string + value Value +} + +// Value use Len to count how many bytes it takes +type Value interface { + Len() int +} + +// New is the Constructor of Cache +func New(maxBytes int64, onEvicted func(string, Value)) *Cache { + return &Cache{ + maxBytes: maxBytes, + ll: list.New(), + cache: make(map[string]*list.Element), + OnEvicted: onEvicted, + } +} + +// Add adds a value to the cache. +func (c *Cache) Add(key string, value Value) { + if ele, ok := c.cache[key]; ok { + c.ll.MoveToFront(ele) + kv := ele.Value.(*entry) + kv.value = value + return + } + ele := c.ll.PushFront(&entry{key, value}) + c.cache[key] = ele + c.nbytes += int64(len(key)) + int64(value.Len()) + + for c.maxBytes != 0 && c.maxBytes < c.nbytes { + c.RemoveOldest() + } +} + +// Get look ups a key's value +func (c *Cache) Get(key string) (value Value, ok bool) { + if ele, ok := c.cache[key]; ok { + c.ll.MoveToFront(ele) + kv := ele.Value.(*entry) + return kv.value, true + } + return +} + +// RemoveOldest removes the oldest item +func (c *Cache) RemoveOldest() { + ele := c.ll.Back() + if ele != nil { + c.ll.Remove(ele) + kv := ele.Value.(*entry) + delete(c.cache, kv.key) + c.nbytes -= int64(len(kv.key)) + int64(kv.value.Len()) + if c.OnEvicted != nil { + c.OnEvicted(kv.key, kv.value) + } + } +} + +// Len the number of cache entries +func (c *Cache) Len() int { + return c.ll.Len() +} diff --git a/lib/lru/lru_test.go b/lib/lru/lru_test.go new file mode 100644 index 000000000..730832299 --- /dev/null +++ b/lib/lru/lru_test.go @@ -0,0 +1,55 @@ +package lru + +import ( + "reflect" + "testing" +) + +type String string + +func (d String) Len() int { + return len(d) +} + +func TestGet(t *testing.T) { + lru := New(int64(0), nil) + lru.Add("key1", String("1234")) + if v, ok := lru.Get("key1"); !ok || string(v.(String)) != "1234" { + t.Fatalf("cache hit key1=1234 failed") + } + if _, ok := lru.Get("key2"); ok { + t.Fatalf("cache miss key2 failed") + } +} + +func TestRemoveoldest(t *testing.T) { + k1, k2, k3 := "key1", "key2", "k3" + v1, v2, v3 := "value1", "value2", "v3" + cap := len(k1 + k2 + v1 + v2) + lru := New(int64(cap), nil) + lru.Add(k1, String(v1)) + lru.Add(k2, String(v2)) + lru.Add(k3, String(v3)) + + if _, ok := lru.Get("key1"); ok || lru.Len() != 2 { + t.Fatalf("Removeoldest key1 failed") + } +} + +func TestOnEvicted(t *testing.T) { + keys := make([]string, 0) + callback := func(key string, value Value) { + keys = append(keys, key) + } + lru := New(int64(10), callback) + lru.Add("key1", String("123456")) + lru.Add("k2", String("k2")) + lru.Add("k3", String("k3")) + lru.Add("k4", String("k4")) + + expect := []string{"key1", "k2"} + + if !reflect.DeepEqual(expect, keys) { + t.Fatalf("Call OnEvicted failed, expect keys equals to %s", expect) + } +} diff --git a/src/0241.Different-Ways-to-Add-Parentheses/README.md b/src/0241.Different-Ways-to-Add-Parentheses/README.md new file mode 100644 index 000000000..b3e82cf5a --- /dev/null +++ b/src/0241.Different-Ways-to-Add-Parentheses/README.md @@ -0,0 +1,48 @@ +# [241. Different Ways to Add Parentheses][title] + +## Description + +Given two binary strings, return their sum (also a binary string). + +The input strings are both **non-empty** and contains only characters `1` or `0`. + +**Example 1:** + +``` +Input: a = "11", b = "1" +Output: "100" +``` + +**Example 2:** + +``` +Input: a = "1010", b = "1011" +Output: "10101" +``` + +**Tags:** Math, String + +## 题意 +> 求2数之和 + +## 题解 + +### 思路1 +> 。。。。 + +```go + +``` + +### 思路2 +> 思路2 +```go + +``` + +## 结语 + +如果你同我一样热爱数据结构、算法、LeetCode,可以关注我 GitHub 上的 LeetCode 题解:[awesome-golang-leetcode][me] + +[title]: https://leetcode.com/problems/different-ways-to-add-parentheses/ +[me]: https://github.com/kylesliu/awesome-golang-leetcode diff --git a/src/0241.Different-Ways-to-Add-Parentheses/Solution.go b/src/0241.Different-Ways-to-Add-Parentheses/Solution.go new file mode 100644 index 000000000..6a10aa77e --- /dev/null +++ b/src/0241.Different-Ways-to-Add-Parentheses/Solution.go @@ -0,0 +1,5 @@ +package Solution + +func diffWaysToCompute(input string) []int { + return []int{} +} diff --git a/src/0241.Different-Ways-to-Add-Parentheses/Solution_test.go b/src/0241.Different-Ways-to-Add-Parentheses/Solution_test.go new file mode 100644 index 000000000..673e32c5f --- /dev/null +++ b/src/0241.Different-Ways-to-Add-Parentheses/Solution_test.go @@ -0,0 +1,40 @@ +package Solution + +import ( + "reflect" + "strconv" + "testing" +) + +func TestSolution(t *testing.T) { + // 测试用例 + cases := []struct { + name string + inputs string + expect []int + }{ + {"TestCase", "2-1-1", []int{0, 2}}, + {"TestCase", "2*3-4*5", []int{-34, -14, -10, -10, 10}}, + } + + // 开始测试 + for i, c := range cases { + t.Run(c.name+" "+strconv.Itoa(i), func(t *testing.T) { + got := diffWaysToCompute(c.inputs) + if !reflect.DeepEqual(got, c.expect) { + t.Fatalf("expected: %v, but got: %v, with inputs: %v", + c.expect, got, c.inputs) + } + }) + } +} + +// 压力测试 +func BenchmarkSolution(b *testing.B) { + +} + +// 使用案列 +func ExampleSolution() { + +} diff --git a/src/0409.Longest-Palindrome/README.md b/src/0409.Longest-Palindrome/README.md new file mode 100644 index 000000000..302f75621 --- /dev/null +++ b/src/0409.Longest-Palindrome/README.md @@ -0,0 +1,53 @@ +# [409. Longest Palindrome][title] + +## Description + +Given a string which consists of lowercase or uppercase letters, find the length of the longest palindromes that can be built with those letters. + +This is case sensitive, for example "Aa" is not considered a palindrome here. + +Note: +Assume the length of given string will not exceed 1,010. + +**Example 1:** + +``` +Input: +"abccccdd" + +Output: +7 + +Explanation: +One longest palindrome that can be built is "dccaccd", whose length is 7. +``` + +**Tags:** Math, String + +## 题意 +> 求2数之和 + +## 题解 + +### 思路1 +> 用哈希表统计每个字符出现的次数 + 判断奇偶性: + 若字符出现次数为偶数,则肯定能够组成回文串,计入累加器 + 若为奇数,添加个数-1并计入累加器,并且标记存在中心字符 + +```go + +``` + +### 思路2 +> 思路2 +```go + +``` + +## 结语 + +如果你同我一样热爱数据结构、算法、LeetCode,可以关注我 GitHub 上的 LeetCode 题解:[awesome-golang-leetcode][me] + +[title]: https://leetcode.com/problems/longest-palindrome/ +[me]: https://github.com/kylesliu/awesome-golang-leetcode diff --git a/src/0409.Longest-Palindrome/Solution.go b/src/0409.Longest-Palindrome/Solution.go new file mode 100644 index 000000000..87d1d47bd --- /dev/null +++ b/src/0409.Longest-Palindrome/Solution.go @@ -0,0 +1,20 @@ +package Solution + +func longestPalindrome(s string) int { + m, ans, has_odd := make(map[rune]int, 128), 0, false + for _, v := range s { + m[v]++ + } + for _, v := range m { + ans += v + if v%2 == 1 { + ans-- + has_odd = true + } + } + if has_odd { + ans++ + } + + return ans +} diff --git a/src/0409.Longest-Palindrome/Solution_test.go b/src/0409.Longest-Palindrome/Solution_test.go new file mode 100644 index 000000000..fbe99a81c --- /dev/null +++ b/src/0409.Longest-Palindrome/Solution_test.go @@ -0,0 +1,39 @@ +package Solution + +import ( + "reflect" + "strconv" + "testing" +) + +func TestSolution(t *testing.T) { + // 测试用例 + cases := []struct { + name string + inputs string + expect int + }{ + {"TestCase", "abccccdd", 7}, + } + + // 开始测试 + for i, c := range cases { + t.Run(c.name+" "+strconv.Itoa(i), func(t *testing.T) { + got := longestPalindrome(c.inputs) + if !reflect.DeepEqual(got, c.expect) { + t.Fatalf("expected: %v, but got: %v, with inputs: %v", + c.expect, got, c.inputs) + } + }) + } +} + +// 压力测试 +func BenchmarkSolution(b *testing.B) { + +} + +// 使用案列 +func ExampleSolution() { + +} diff --git a/src/0552.Student-Attendance-Record-II/README.md b/src/0552.Student-Attendance-Record-II/README.md new file mode 100644 index 000000000..bc8e17d55 --- /dev/null +++ b/src/0552.Student-Attendance-Record-II/README.md @@ -0,0 +1,49 @@ +# [552. Student Attendance Record II][title] + +## Description + +Given a positive integer n, return the number of all possible attendance records with length n, which will be regarded as rewardable. The answer may be very large, return it after mod 109 + 7. + +A student attendance record is a string that only contains the following three characters: + +'A' : Absent. +'L' : Late. +'P' : Present. +A record is regarded as rewardable if it doesn't contain more than one 'A' (absent) or more than two continuous 'L' (late). +**Example 1:** + +``` +Input: n = 2 +Output: 8 +Explanation: +There are 8 records with length 2 will be regarded as rewardable: +"PP" , "AP", "PA", "LP", "PL", "AL", "LA", "LL" +Only "AA" won't be regarded as rewardable owing to more than one absent times. +``` + +**Tags:** Math, String + +## 题意 +> 求2数之和 + +## 题解 + +### 思路1 +> 。。。。 + +```go + +``` + +### 思路2 +> 思路2 +```go + +``` + +## 结语 + +如果你同我一样热爱数据结构、算法、LeetCode,可以关注我 GitHub 上的 LeetCode 题解:[awesome-golang-leetcode][me] + +[title]: https://leetcode.com/problems/student-attendance-record-ii/ +[me]: https://github.com/kylesliu/awesome-golang-leetcode diff --git a/src/0552.Student-Attendance-Record-II/Solution.go b/src/0552.Student-Attendance-Record-II/Solution.go new file mode 100644 index 000000000..dfa7348e0 --- /dev/null +++ b/src/0552.Student-Attendance-Record-II/Solution.go @@ -0,0 +1,6 @@ +package Solution + +func Solution(x bool) bool { + + return x +} diff --git a/src/0552.Student-Attendance-Record-II/Solution_test.go b/src/0552.Student-Attendance-Record-II/Solution_test.go new file mode 100644 index 000000000..3e51ecacf --- /dev/null +++ b/src/0552.Student-Attendance-Record-II/Solution_test.go @@ -0,0 +1,41 @@ +package Solution + +import ( + "reflect" + "strconv" + "testing" +) + +func TestSolution(t *testing.T) { + // 测试用例 + cases := []struct { + name string + inputs bool + expect bool + }{ + {"TestCase", true, true}, + {"TestCase", true, true}, + {"TestCase", false, false}, + } + + // 开始测试 + for i, c := range cases { + t.Run(c.name+" "+strconv.Itoa(i), func(t *testing.T) { + got := Solution(c.inputs) + if !reflect.DeepEqual(got, c.expect) { + t.Fatalf("expected: %v, but got: %v, with inputs: %v", + c.expect, got, c.inputs) + } + }) + } +} + +// 压力测试 +func BenchmarkSolution(b *testing.B) { + +} + +// 使用案列 +func ExampleSolution() { + +} diff --git a/src/0621.Task-Scheduler/README.md b/src/0621.Task-Scheduler/README.md new file mode 100644 index 000000000..b0d6712a7 --- /dev/null +++ b/src/0621.Task-Scheduler/README.md @@ -0,0 +1,48 @@ +# [621. Task Scheduler][title] + +## Description + +Given two binary strings, return their sum (also a binary string). + +The input strings are both **non-empty** and contains only characters `1` or `0`. + +**Example 1:** + +``` +Input: a = "11", b = "1" +Output: "100" +``` + +**Example 2:** + +``` +Input: a = "1010", b = "1011" +Output: "10101" +``` + +**Tags:** Math, String + +## 题意 +> 求2数之和 + +## 题解 + +### 思路1 +> 。。。。 + +```go + +``` + +### 思路2 +> 思路2 +```go + +``` + +## 结语 + +如果你同我一样热爱数据结构、算法、LeetCode,可以关注我 GitHub 上的 LeetCode 题解:[awesome-golang-leetcode][me] + +[title]: https://leetcode.com/problems/task-scheduler/ +[me]: https://github.com/kylesliu/awesome-golang-leetcode diff --git a/src/0621.Task-Scheduler/Solution.go b/src/0621.Task-Scheduler/Solution.go new file mode 100644 index 000000000..70f46222c --- /dev/null +++ b/src/0621.Task-Scheduler/Solution.go @@ -0,0 +1,8 @@ +package Solution + + + + +func leastInterval(tasks []byte, n int) int { + return 0 +} diff --git a/src/0621.Task-Scheduler/Solution_test.go b/src/0621.Task-Scheduler/Solution_test.go new file mode 100644 index 000000000..cfa015b70 --- /dev/null +++ b/src/0621.Task-Scheduler/Solution_test.go @@ -0,0 +1,40 @@ +package Solution + +import ( + "reflect" + "strconv" + "testing" +) + +func TestSolution(t *testing.T) { + // 测试用例 + cases := []struct { + name string + input1 []byte + input2 int + expect int + }{ + {"TestCase", []byte{'A', 'A', 'A', 'B', 'B', 'B'}, 2, 8}, + } + + // 开始测试 + for i, c := range cases { + t.Run(c.name+" "+strconv.Itoa(i), func(t *testing.T) { + got := leastInterval(c.input1, c.input2) + if !reflect.DeepEqual(got, c.expect) { + t.Fatalf("expected: %v, but got: %v, with input1: %v input2: %v", + c.expect, got, c.input1, c.input2) + } + }) + } +} + +// 压力测试 +func BenchmarkSolution(b *testing.B) { + +} + +// 使用案列 +func ExampleSolution() { + +} diff --git a/src/0676.Implement-Magic-Dictionary/README.md b/src/0676.Implement-Magic-Dictionary/README.md new file mode 100644 index 000000000..e604e600d --- /dev/null +++ b/src/0676.Implement-Magic-Dictionary/README.md @@ -0,0 +1,48 @@ +# [676. Implement Magic Dictionary][title] + +## Description + +Given two binary strings, return their sum (also a binary string). + +The input strings are both **non-empty** and contains only characters `1` or `0`. + +**Example 1:** + +``` +Input: a = "11", b = "1" +Output: "100" +``` + +**Example 2:** + +``` +Input: a = "1010", b = "1011" +Output: "10101" +``` + +**Tags:** Math, String + +## 题意 +> 求2数之和 + +## 题解 + +### 思路1 +> 。。。。 + +```go + +``` + +### 思路2 +> 思路2 +```go + +``` + +## 结语 + +如果你同我一样热爱数据结构、算法、LeetCode,可以关注我 GitHub 上的 LeetCode 题解:[awesome-golang-leetcode][me] + +[title]: https://leetcode.com/problems/implement-magic-dictionary/ +[me]: https://github.com/kylesliu/awesome-golang-leetcode diff --git a/src/0676.Implement-Magic-Dictionary/Solution.go b/src/0676.Implement-Magic-Dictionary/Solution.go new file mode 100644 index 000000000..ba6bbecf5 --- /dev/null +++ b/src/0676.Implement-Magic-Dictionary/Solution.go @@ -0,0 +1,73 @@ +package Solution + +type MagicDictionary struct { + Children [26]*MagicDictionary + End bool +} + +/** Initialize your data structure here. */ +func Constructor() MagicDictionary { + return MagicDictionary{} +} + +func (root *MagicDictionary) Insert(word string) { + start := root + for i, w := range word { + if node := start.Children[w-'a']; node != nil { + start = node + } else { + for _, nw := range word[i:] { + start.Children[nw-'a'] = &MagicDictionary{} + start = start.Children[nw-'a'] + } + break + } + } + start.End = true + +} + +/** Build a dictionary through a list of words */ +func (root *MagicDictionary) BuildDict(dict []string) { + for _, w := range dict { + root.Insert(w) + } +} + +//the second parameter is mismatched character, the third one is word length, and the fourth is the word access index +func (root *MagicDictionary) SearchHelper(word string, miss int, wl int, ind int) bool { + //if mismatch is more than 1 + if miss > 1 { + return false + } + //if end of the word, then must have exact one mismatch + if wl == ind { + return root.End && miss == 1 + } + //current access character of the word + ch := int(word[ind] - 'a') + for i, nc := range root.Children { + if nc != nil { + nm := miss + if i != ch { + nm += 1 + } + if nc.SearchHelper(word, nm, wl, ind+1) { + return true + } + } + } + return false +} + +/** Returns if there is any word in the trie that equals to the given word after modifying exactly one character */ +func (root *MagicDictionary) Search(word string) bool { + return root.SearchHelper(word, 0, len(word), 0) +} + +/** + * Your MagicDictionary object will be instantiated and called as such: + * obj := Constructor(); + * obj.BuildDict(dict); + * param_2 := obj.Search(word); + */ diff --git a/src/0676.Implement-Magic-Dictionary/Solution_test.go b/src/0676.Implement-Magic-Dictionary/Solution_test.go new file mode 100644 index 000000000..f0d32ea2a --- /dev/null +++ b/src/0676.Implement-Magic-Dictionary/Solution_test.go @@ -0,0 +1,45 @@ +package Solution + +import ( + "reflect" + "strconv" + "testing" +) + +func TestSolution(t *testing.T) { + // 测试用例 + cases := []struct { + name string + dict []string + inputs string + expect bool + }{ + {"TestCase", []string{"hello", "leetcode"}, "hello", false}, + {"TestCase", []string{"hello", "leetcode"}, "hhllo", true}, + {"TestCase", []string{"hello", "leetcode"}, "hell", false}, + {"TestCase", []string{"hello", "leetcode"}, "leetcoded", false}, + } + + // 开始测试 + for i, c := range cases { + t.Run(c.name+" "+strconv.Itoa(i), func(t *testing.T) { + obj := Constructor() + obj.BuildDict(c.dict) + got := obj.Search(c.inputs) + if !reflect.DeepEqual(got, c.expect) { + t.Fatalf("expected: %v, but got: %v, with dict: %v, search: %v", + c.expect, got, c.dict, c.inputs) + } + }) + } +} + +// 压力测试 +func BenchmarkSolution(b *testing.B) { + +} + +// 使用案列 +func ExampleSolution() { + +} diff --git a/src/1292.Maximum-Side-Length-of-a-Square-with-Sum-Less-than-or-Equal-to-Threshold/README.md b/src/1292.Maximum-Side-Length-of-a-Square-with-Sum-Less-than-or-Equal-to-Threshold/README.md new file mode 100644 index 000000000..08171fe4a --- /dev/null +++ b/src/1292.Maximum-Side-Length-of-a-Square-with-Sum-Less-than-or-Equal-to-Threshold/README.md @@ -0,0 +1,46 @@ +# [1292. Maximum Side Length of a Square with Sum Less than or Equal to Threshold][title] + +## Description + +Given a m x n matrix mat and an integer threshold. Return the maximum side-length of a square with a sum less than or equal to threshold or return 0 if there is no such square. +**Example 1:** + +``` +Input: mat = [[1,1,3,2,4,3,2],[1,1,3,2,4,3,2],[1,1,3,2,4,3,2]], threshold = 4 +Output: 2 +Explanation: The maximum side length of square with sum less than 4 is 2 as shown. +``` + +**Example 2:** + +``` +Input: mat = [[2,2,2,2,2],[2,2,2,2,2],[2,2,2,2,2],[2,2,2,2,2],[2,2,2,2,2]], threshold = 1 +Output: 0 +``` + +**Tags:** Math, String + +## 题意 +> 求2数之和 + +## 题解 + +### 思路1 +> 。。。。 + +```go + +``` + +### 思路2 +> 思路2 +```go + +``` + +## 结语 + +如果你同我一样热爱数据结构、算法、LeetCode,可以关注我 GitHub 上的 LeetCode 题解:[awesome-golang-leetcode][me] + +[title]: https://leetcode.com/problems/maximum-side-length-of-a-square-with-sum-less-than-or-equal-to-threshold/ +[me]: https://github.com/kylesliu/awesome-golang-leetcode diff --git a/src/1292.Maximum-Side-Length-of-a-Square-with-Sum-Less-than-or-Equal-to-Threshold/Solution.go b/src/1292.Maximum-Side-Length-of-a-Square-with-Sum-Less-than-or-Equal-to-Threshold/Solution.go new file mode 100644 index 000000000..dfa7348e0 --- /dev/null +++ b/src/1292.Maximum-Side-Length-of-a-Square-with-Sum-Less-than-or-Equal-to-Threshold/Solution.go @@ -0,0 +1,6 @@ +package Solution + +func Solution(x bool) bool { + + return x +} diff --git a/src/1292.Maximum-Side-Length-of-a-Square-with-Sum-Less-than-or-Equal-to-Threshold/Solution_test.go b/src/1292.Maximum-Side-Length-of-a-Square-with-Sum-Less-than-or-Equal-to-Threshold/Solution_test.go new file mode 100644 index 000000000..3e51ecacf --- /dev/null +++ b/src/1292.Maximum-Side-Length-of-a-Square-with-Sum-Less-than-or-Equal-to-Threshold/Solution_test.go @@ -0,0 +1,41 @@ +package Solution + +import ( + "reflect" + "strconv" + "testing" +) + +func TestSolution(t *testing.T) { + // 测试用例 + cases := []struct { + name string + inputs bool + expect bool + }{ + {"TestCase", true, true}, + {"TestCase", true, true}, + {"TestCase", false, false}, + } + + // 开始测试 + for i, c := range cases { + t.Run(c.name+" "+strconv.Itoa(i), func(t *testing.T) { + got := Solution(c.inputs) + if !reflect.DeepEqual(got, c.expect) { + t.Fatalf("expected: %v, but got: %v, with inputs: %v", + c.expect, got, c.inputs) + } + }) + } +} + +// 压力测试 +func BenchmarkSolution(b *testing.B) { + +} + +// 使用案列 +func ExampleSolution() { + +} diff --git a/tmp/v1/main.go b/tmp/v1/main.go new file mode 100644 index 000000000..97a571e43 --- /dev/null +++ b/tmp/v1/main.go @@ -0,0 +1,20 @@ +package main + +import ( + "fmt" + "net/http" +) + +func main() { + http.HandleFunc("/hello", helloHandler) + http.ListenAndServe(":8000", nil) +} + +func helloHandler(w http.ResponseWriter, req *http.Request) { + fmt.Println(req.URL.Path) + fmt.Fprintln(w, req.URL.Path) +} + +func indexHandler(w http.ResponseWriter, req *http.Request) { + fmt.Fprintf(w, "URL.Path = %q\n", req.URL.Path) +}