61.和最小的 k 个数对
思路:用heap实现根堆,然后根据出堆实现优先队列,记住用heap实现根堆五个重要的方法,三个值接受方法Len、Swap、Less和两个指针接受方法,Push、和Pop。
62. 实现前缀树
思路:可以考虑用map进行存储key。
思路二:可以建立前缀树,根据字母建立。
type Trie struct {
children [26]*Trie
isEnd bool
}
func Constructor() Trie {
return Trie{}
}
func (t *Trie) Insert(word string) {
node := t
for _, ch := range word {
ch -= 'a'
if node.children[ch] == nil {
node.children[ch] = &Trie{}
}
node = node.children[ch]
}
node.isEnd = true
}
func (t *Trie) SearchPrefix(prefix string) *Trie {
node := t
for _, ch := range prefix {
ch -= 'a'
if node.children[ch] == nil {
return nil
}
node = node.children[ch]
}
return node
}
func (t *Trie) Search(word string) bool {
node := t.SearchPrefix(word)
return node != nil && node.isEnd
}
func (t *Trie) StartsWith(prefix string) bool {
return t.SearchPrefix(prefix) != nil
}
63.替换单词
前缀树的应用
64.神奇的字典
前缀树和暴力都可以
65.最短的单词编码
暴力思想-字符串后缀匹配
66.单词之和
前缀和的应用或者用map匹配也行
67.最大的异或
思想:前缀和的应用,
var Max int = 32
type Trie struct{
Left , Right *Trie
}
func findMaximumXOR(nums []int) int {
root := &Trie{}
res := 0
max := func (i, j int)int{
if i > j {
return i
}
return j
}
for _,v := range nums{
cv := root
pre := root
cur := 0
for i := Max - 1; i >= 0; i--{
if ((v >> i) & 1) == 0{
if cv.Left == nil{
cv.Left = &Trie{}
}
cv = cv.Left
if pre.Right != nil{
pre = pre.Right
cur += (1 << i)
} else {
pre = pre.Left
}
}else if ((v >> i) & 1) == 1 {
if cv.Right == nil{
cv.Right = &Trie{}
}
cv = cv.Right
if pre.Left != nil{
pre = pre.Left
cur += (1 << i)
} else {
pre = pre.Right
}
}
}
res = max(res , cur)
}
return res
}
68.查找插入位置
思路:简单的二分查找。
69. 山峰数组的顶部
思路:普通遍历
70.排序数组中只出现一次的数字
思路:异或一次遍历,或者一次两步一次遍历中进行判断。