吹拉弹唱


  • Home
  • Archive
  • Categories
  • Tags
  • Books
  •  

© 2022 Kleon

Theme Typography by Makito

Proudly published with Hexo

Code - Hash Table

Posted at 2022-05-05Updated at 2022-05-05 interview  interview algorithm 

  • LeetCode
    • 1. Two Sum
    • 3. Longest Substring Without Repeating Characters
    • 1002. Find Common Characters
    • 350. Intersection of Two Arrays II
    • 349. Intersection of Two Arrays
      • 146. LRU Cache
    • 49. Group Anagrams
    • 242. Valid Anagram
    • 208. Implement Trie (Prefix Tree)

# LeetCode

# 1. Two Sum

leetcode

Using a hash map to check whether the target - n exists.

1
2
3
4
5
6
7
8
9
10
func twoSum(nums []int, target int) []int {
m := map[int]int{}
for i, n := range nums {
if v, ok := m[target - n]; ok {
return []int{v, i}
}
m[n] = i
}
return []int{}
}

# 3. Longest Substring Without Repeating Characters

leetcode

An intuitive solution is using a map to record the index of each letter. When find a duplicated letter move the lower bound the max(lower, index) and calculate the length.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
func lengthOfLongestSubstring(s string) int {
if len(s) == 0 {
return 0
}

d := make(map[byte]int)
low := -1
max := 0
for i := range s {
if index, exists := d[s[i]]; exists {
if index > low {
low = index
}
}
d[s[i]] = i
if i - low > max {
max = i - low
}
}
return max
}

# 1002. Find Common Characters

leetcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
func commonChars(words []string) []string {
cnt := make([]int, 26)
for i := range cnt {
cnt[i] = math.MaxInt32
}
res := []string{}
for _, s := range words {
cnt1 := make([]int, 26)
for _, c := range s {
cnt1[c - 'a']++
}
for i := 0; i < 26; i++ {
if cnt1[i] < cnt[i] {
cnt[i] = cnt1[i]
}
}
// fmt.Printf("%v %v\n", cnt1, cnt)
}
for i := 0; i < 26; i++ {
for j := 0; j < cnt[i]; j++ {
res = append(res, string(i + 'a'))
}
}
return res
}

# 350. Intersection of Two Arrays II

leetcode

Repeat element.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
func intersect(nums1 []int, nums2 []int) []int {
m := make(map[int]int)
for _, num := range nums1 {
m[num]++
}
result := []int{}
for _, num := range nums2 {
if m[num] > 0 {
result = append(result, num)
m[num]--
}
}
return result
}

# 349. Intersection of Two Arrays

Unique element.

leetcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
func intersection(nums1 []int, nums2 []int) []int {
m := make(map[int]bool)
for _, num := range nums1 {
m[num] = true
}
n := make(map[int]bool)
for _, num := range nums2 {
if n[num] {
continue
}
if m[num] {
n[num] = true

}
result := make([]int, 0, len(n))
for num := range n {
result = append(result, num)
}
return result
}

# 146. LRU Cache

leetcode

combination of list & map, try to avoid search.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
type Pair struct {
k int
v int
}

type LRUCache struct {
l *list.List
m map[int]*list.Element
capacity int
}


func Constructor(capacity int) LRUCache {
return LRUCache{
l: list.New(),
m: make(map[int]*list.Element),
capacity: capacity,
}
}


func (this *LRUCache) Get(key int) int {
if e, exists := this.m[key]; exists {
this.l.MoveToFront(e)
return e.Value.(Pair).v
}
return -1
}


func (this *LRUCache) Put(key int, value int) {
if e, exists := this.m[key]; exists {
e.Value = Pair{k:key,v:value}
this.l.MoveToFront(e)
return
}
if len(this.m) == this.capacity {
e := this.l.Back()
this.l.Remove(e)
delete(this.m, e.Value.(Pair).k)
}
e := this.l.PushFront(Pair{k:key,v:value})
this.m[key] = e
}


/**
* Your LRUCache object will be instantiated and called as such:
* obj := Constructor(capacity);
* param_1 := obj.Get(key);
* obj.Put(key,value);
*/

# 49. Group Anagrams

leetcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 func groupAnagrams(strs []string) [][]string {
if len(strs) == 0 {
return [][]string{}
}
m := map[string][]string{}
for _, s := range strs {
ca := make([]rune, 26)
for _, c := range s {
ca[c - 'a']++
}
keyStr := string(ca)
if _, exists := m[keyStr]; !exists {
m[keyStr] = []string{}
}
m[keyStr] = append(m[keyStr], s)
}
res := [][]string{}
for _, v := range m {
res = append(res, v)
}
return res
}

# 242. Valid Anagram

leetcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
func isAnagram(s string, t string) bool {
m := make([]int, 26)
for _, r := range s {
m[r - 'a']++
}
for _, r := range t {
m[r - 'a']--
}
for _, v := range m {
if v != 0 {
return false
}
}
return true
}

# 208. Implement Trie (Prefix Tree)

leetcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
type Trie struct {
root *TrieNode
}


func Constructor() Trie {
return Trie{NewTrieNode()}
}


func (this *Trie) Insert(word string) {
node := this.root
for _, r := range word {
if _, exists := node.children[r]; !exists {
node.children[r] = NewTrieNode()
}
node = node.children[r]
}
node.word = true
}


func (this *Trie) Search(word string) bool {
node := this.root
for _, r := range word {
if _, exists := node.children[r]; !exists {
return false
}
node = node.children[r]
}
return node.word
}


func (this *Trie) StartsWith(prefix string) bool {
node := this.root
for _, r := range prefix {
if _, exists := node.children[r]; !exists {
return false
}
node = node.children[r]
}
return true
}

type TrieNode struct {
word bool
children map[rune]*TrieNode
}

func NewTrieNode() *TrieNode {
return &TrieNode{
children: map[rune]*TrieNode{},
}
}

/**
* Your Trie object will be instantiated and called as such:
* obj := Constructor();
* obj.Insert(word);
* param_2 := obj.Search(word);
* param_3 := obj.StartsWith(prefix);
*/

Share 

 Previous post: Code - Greedy Next post: Code - Heap 

© 2022 Kleon

Theme Typography by Makito

Proudly published with Hexo