Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
LeetCode of algorithms with golang solution(updating:smiley:).

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

<p align="center">
Expand Down
79 changes: 79 additions & 0 deletions lib/lru/lru.go
Original file line number Diff line number Diff line change
@@ -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()
}
55 changes: 55 additions & 0 deletions lib/lru/lru_test.go
Original file line number Diff line number Diff line change
@@ -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)
}
}
48 changes: 48 additions & 0 deletions src/0241.Different-Ways-to-Add-Parentheses/README.md
Original file line number Diff line number Diff line change
@@ -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
5 changes: 5 additions & 0 deletions src/0241.Different-Ways-to-Add-Parentheses/Solution.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package Solution

func diffWaysToCompute(input string) []int {
return []int{}
}
40 changes: 40 additions & 0 deletions src/0241.Different-Ways-to-Add-Parentheses/Solution_test.go
Original file line number Diff line number Diff line change
@@ -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() {

}
53 changes: 53 additions & 0 deletions src/0409.Longest-Palindrome/README.md
Original file line number Diff line number Diff line change
@@ -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
20 changes: 20 additions & 0 deletions src/0409.Longest-Palindrome/Solution.go
Original file line number Diff line number Diff line change
@@ -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
}
39 changes: 39 additions & 0 deletions src/0409.Longest-Palindrome/Solution_test.go
Original file line number Diff line number Diff line change
@@ -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() {

}
Loading