Skip to content

Commit 541ce1d

Browse files
authored
Merge pull request 6boris#110 from kylesliu/develop
Develop
2 parents f86a816 + f18dc9c commit 541ce1d

File tree

22 files changed

+812
-2
lines changed

22 files changed

+812
-2
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
LeetCode of algorithms with golang solution(updating:smiley:).
44

55
<p align="center">
6-
<img src="http://s.gin.sh/logo/golang-3.png">
7-
<img src="http://s.gin.sh/logo/leetcode-2.png">
6+
<img src="https://s.gin.sh/logo/go/PNG/Go-Logo_Aqua.png" width="160" height="130">
7+
<img src="http://s.gin.sh/logo/leetcode.png" width="250" height="130">
88
</p>
99

1010
<p align="center">

lib/lru/lru.go

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
package lru
2+
3+
import "container/list"
4+
5+
// Cache is a LRU cache. It is not safe for concurrent access.
6+
type Cache struct {
7+
maxBytes int64
8+
nbytes int64
9+
ll *list.List
10+
cache map[string]*list.Element
11+
// optional and executed when an entry is purged.
12+
OnEvicted func(key string, value Value)
13+
}
14+
15+
type entry struct {
16+
key string
17+
value Value
18+
}
19+
20+
// Value use Len to count how many bytes it takes
21+
type Value interface {
22+
Len() int
23+
}
24+
25+
// New is the Constructor of Cache
26+
func New(maxBytes int64, onEvicted func(string, Value)) *Cache {
27+
return &Cache{
28+
maxBytes: maxBytes,
29+
ll: list.New(),
30+
cache: make(map[string]*list.Element),
31+
OnEvicted: onEvicted,
32+
}
33+
}
34+
35+
// Add adds a value to the cache.
36+
func (c *Cache) Add(key string, value Value) {
37+
if ele, ok := c.cache[key]; ok {
38+
c.ll.MoveToFront(ele)
39+
kv := ele.Value.(*entry)
40+
kv.value = value
41+
return
42+
}
43+
ele := c.ll.PushFront(&entry{key, value})
44+
c.cache[key] = ele
45+
c.nbytes += int64(len(key)) + int64(value.Len())
46+
47+
for c.maxBytes != 0 && c.maxBytes < c.nbytes {
48+
c.RemoveOldest()
49+
}
50+
}
51+
52+
// Get look ups a key's value
53+
func (c *Cache) Get(key string) (value Value, ok bool) {
54+
if ele, ok := c.cache[key]; ok {
55+
c.ll.MoveToFront(ele)
56+
kv := ele.Value.(*entry)
57+
return kv.value, true
58+
}
59+
return
60+
}
61+
62+
// RemoveOldest removes the oldest item
63+
func (c *Cache) RemoveOldest() {
64+
ele := c.ll.Back()
65+
if ele != nil {
66+
c.ll.Remove(ele)
67+
kv := ele.Value.(*entry)
68+
delete(c.cache, kv.key)
69+
c.nbytes -= int64(len(kv.key)) + int64(kv.value.Len())
70+
if c.OnEvicted != nil {
71+
c.OnEvicted(kv.key, kv.value)
72+
}
73+
}
74+
}
75+
76+
// Len the number of cache entries
77+
func (c *Cache) Len() int {
78+
return c.ll.Len()
79+
}

lib/lru/lru_test.go

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
package lru
2+
3+
import (
4+
"reflect"
5+
"testing"
6+
)
7+
8+
type String string
9+
10+
func (d String) Len() int {
11+
return len(d)
12+
}
13+
14+
func TestGet(t *testing.T) {
15+
lru := New(int64(0), nil)
16+
lru.Add("key1", String("1234"))
17+
if v, ok := lru.Get("key1"); !ok || string(v.(String)) != "1234" {
18+
t.Fatalf("cache hit key1=1234 failed")
19+
}
20+
if _, ok := lru.Get("key2"); ok {
21+
t.Fatalf("cache miss key2 failed")
22+
}
23+
}
24+
25+
func TestRemoveoldest(t *testing.T) {
26+
k1, k2, k3 := "key1", "key2", "k3"
27+
v1, v2, v3 := "value1", "value2", "v3"
28+
cap := len(k1 + k2 + v1 + v2)
29+
lru := New(int64(cap), nil)
30+
lru.Add(k1, String(v1))
31+
lru.Add(k2, String(v2))
32+
lru.Add(k3, String(v3))
33+
34+
if _, ok := lru.Get("key1"); ok || lru.Len() != 2 {
35+
t.Fatalf("Removeoldest key1 failed")
36+
}
37+
}
38+
39+
func TestOnEvicted(t *testing.T) {
40+
keys := make([]string, 0)
41+
callback := func(key string, value Value) {
42+
keys = append(keys, key)
43+
}
44+
lru := New(int64(10), callback)
45+
lru.Add("key1", String("123456"))
46+
lru.Add("k2", String("k2"))
47+
lru.Add("k3", String("k3"))
48+
lru.Add("k4", String("k4"))
49+
50+
expect := []string{"key1", "k2"}
51+
52+
if !reflect.DeepEqual(expect, keys) {
53+
t.Fatalf("Call OnEvicted failed, expect keys equals to %s", expect)
54+
}
55+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# [241. Different Ways to Add Parentheses][title]
2+
3+
## Description
4+
5+
Given two binary strings, return their sum (also a binary string).
6+
7+
The input strings are both **non-empty** and contains only characters `1` or `0`.
8+
9+
**Example 1:**
10+
11+
```
12+
Input: a = "11", b = "1"
13+
Output: "100"
14+
```
15+
16+
**Example 2:**
17+
18+
```
19+
Input: a = "1010", b = "1011"
20+
Output: "10101"
21+
```
22+
23+
**Tags:** Math, String
24+
25+
## 题意
26+
> 求2数之和
27+
28+
## 题解
29+
30+
### 思路1
31+
> 。。。。
32+
33+
```go
34+
35+
```
36+
37+
### 思路2
38+
> 思路2
39+
```go
40+
41+
```
42+
43+
## 结语
44+
45+
如果你同我一样热爱数据结构、算法、LeetCode,可以关注我 GitHub 上的 LeetCode 题解:[awesome-golang-leetcode][me]
46+
47+
[title]: https://leetcode.com/problems/different-ways-to-add-parentheses/
48+
[me]: https://github.com/kylesliu/awesome-golang-leetcode
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package Solution
2+
3+
func diffWaysToCompute(input string) []int {
4+
return []int{}
5+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package Solution
2+
3+
import (
4+
"reflect"
5+
"strconv"
6+
"testing"
7+
)
8+
9+
func TestSolution(t *testing.T) {
10+
// 测试用例
11+
cases := []struct {
12+
name string
13+
inputs string
14+
expect []int
15+
}{
16+
{"TestCase", "2-1-1", []int{0, 2}},
17+
{"TestCase", "2*3-4*5", []int{-34, -14, -10, -10, 10}},
18+
}
19+
20+
// 开始测试
21+
for i, c := range cases {
22+
t.Run(c.name+" "+strconv.Itoa(i), func(t *testing.T) {
23+
got := diffWaysToCompute(c.inputs)
24+
if !reflect.DeepEqual(got, c.expect) {
25+
t.Fatalf("expected: %v, but got: %v, with inputs: %v",
26+
c.expect, got, c.inputs)
27+
}
28+
})
29+
}
30+
}
31+
32+
// 压力测试
33+
func BenchmarkSolution(b *testing.B) {
34+
35+
}
36+
37+
// 使用案列
38+
func ExampleSolution() {
39+
40+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# [409. Longest Palindrome][title]
2+
3+
## Description
4+
5+
Given a string which consists of lowercase or uppercase letters, find the length of the longest palindromes that can be built with those letters.
6+
7+
This is case sensitive, for example "Aa" is not considered a palindrome here.
8+
9+
Note:
10+
Assume the length of given string will not exceed 1,010.
11+
12+
**Example 1:**
13+
14+
```
15+
Input:
16+
"abccccdd"
17+
18+
Output:
19+
7
20+
21+
Explanation:
22+
One longest palindrome that can be built is "dccaccd", whose length is 7.
23+
```
24+
25+
**Tags:** Math, String
26+
27+
## 题意
28+
> 求2数之和
29+
30+
## 题解
31+
32+
### 思路1
33+
> 用哈希表统计每个字符出现的次数
34+
判断奇偶性:
35+
若字符出现次数为偶数,则肯定能够组成回文串,计入累加器
36+
若为奇数,添加个数-1并计入累加器,并且标记存在中心字符
37+
38+
```go
39+
40+
```
41+
42+
### 思路2
43+
> 思路2
44+
```go
45+
46+
```
47+
48+
## 结语
49+
50+
如果你同我一样热爱数据结构、算法、LeetCode,可以关注我 GitHub 上的 LeetCode 题解:[awesome-golang-leetcode][me]
51+
52+
[title]: https://leetcode.com/problems/longest-palindrome/
53+
[me]: https://github.com/kylesliu/awesome-golang-leetcode
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package Solution
2+
3+
func longestPalindrome(s string) int {
4+
m, ans, has_odd := make(map[rune]int, 128), 0, false
5+
for _, v := range s {
6+
m[v]++
7+
}
8+
for _, v := range m {
9+
ans += v
10+
if v%2 == 1 {
11+
ans--
12+
has_odd = true
13+
}
14+
}
15+
if has_odd {
16+
ans++
17+
}
18+
19+
return ans
20+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package Solution
2+
3+
import (
4+
"reflect"
5+
"strconv"
6+
"testing"
7+
)
8+
9+
func TestSolution(t *testing.T) {
10+
// 测试用例
11+
cases := []struct {
12+
name string
13+
inputs string
14+
expect int
15+
}{
16+
{"TestCase", "abccccdd", 7},
17+
}
18+
19+
// 开始测试
20+
for i, c := range cases {
21+
t.Run(c.name+" "+strconv.Itoa(i), func(t *testing.T) {
22+
got := longestPalindrome(c.inputs)
23+
if !reflect.DeepEqual(got, c.expect) {
24+
t.Fatalf("expected: %v, but got: %v, with inputs: %v",
25+
c.expect, got, c.inputs)
26+
}
27+
})
28+
}
29+
}
30+
31+
// 压力测试
32+
func BenchmarkSolution(b *testing.B) {
33+
34+
}
35+
36+
// 使用案列
37+
func ExampleSolution() {
38+
39+
}

0 commit comments

Comments
 (0)