1.字符串转化后的各位数字之和 (模拟略)
2.子字符串突变后可能得到的最大整数 (贪心)
简单贪心,要想得到最大得数字,那肯定从最高位开始替换能得到更大的数字,注意题目中说的是子数组,所以比当前数字小就可以直接退出了,这里注意一个小细节,就是在相等的时候,需要继续往后检查替换,因为有可能后面能替换出更大的数字。
func maximumNumber(num string, change []int) string {
l := 0
for i := 0 ; i < len(num) ; i++ {
index, _ := strconv.Atoi(string(num[i]))
if change[index] > index {
l = i
break
}
}
b := make([]byte, len(num))
for i := 0 ; i < len(num) ; i++ {
b[i] = num[i]
}
r := l
for r < len(num) {
index, _ := strconv.Atoi(string(num[r]))
if change[index] >= index {
b[r] = byte(change[index] + '0')
r++
} else {
break
}
}
return string(b)
}
3.最大兼容性评分和 (dfs)
题目给出的数据量最大只有8...直接搜能过,如果数据量比较大了,那就需要考虑状压dp了
func maxCompatibilitySum(students [][]int, mentors [][]int) int {
r := make([]int, 1)
n := len(students)
vis1 := make([]bool, n)
getMaxVal(0, 0, &r, students, mentors, vis1)
return r[0]
}
func getMaxVal(n int, curVal int, maxVal *[]int, stu, men [][]int, vis1 []bool) {
if n == len(stu) {
if curVal > (*maxVal)[0] {
(*maxVal)[0] = curVal
}
return
}
for i := 0 ; i < len(stu) ; i++ {
if !vis1[i] {
vis1[i] = true
getMaxVal(n + 1, curVal + getVal(stu[n], men[i]), maxVal, stu, men, vis1)
vis1[i] = false
}
}
}
func getVal(a, b []int) int {
r := 0
for i := 0 ; i < len(a) ; i++ {
if a[i] == b[i] {
r++
}
}
return r
}
4.删除系统中的重复文件夹 (字典树+hash)
题目给出的对文件夹的描述,非常的适合用一棵字典树来存储,所以首先建立字典树,这里需要注意,需要用一个字符串来表示树节点,详情请见代码。之后为了确定两个文件夹是否相同,需要引入一种括号表示法来对当前节点进行表示:假设根节点a有孩子b和c,针对于a节点就表示为a(b)(c)这里是递归的。同时,需要避免有相同子孩子的结点的括号描述不一致,在拼接时,需要先进行排序(见代码),在后续遍历得到每一个结点的括号描述时,统计每个描述出现的次数,如果次数大于1,则需要删除。最后在进行一次dfs,求出答案。(对字典树敏感度不够,需要加强训练)
type Trie struct {
serial string
children map[string]*Trie
}
func deleteDuplicateFolder(paths [][]string) [][]string {
// 建立Trie树
root := &Trie{
serial: "",
children: make(map[string]*Trie),
}
for i := 0 ; i < len(paths) ; i++ {
r := root
for j := 0 ; j < len(paths[i]) ; j++ {
if r.children[paths[i][j]] == nil {
r.children[paths[i][j]] = &Trie{
serial: "",
children: make(map[string]*Trie),
}
}
r = r.children[paths[i][j]]
}
}
// 这里需要删除相同得文件夹 用hash来存每一个节点得序列
// 如果该序列得出现次数超过1次 则说明有重复的需要删除
// 获取每个节点的序列时需要先讲孩子节点按字典序排列
// 这样可以保证相同文件夹得到的节点序列是一致的
m := make(map[string]int)
var dfs1 func(root *Trie)
dfs1 = func(root *Trie) {
if len(root.children) == 0 {
return
}
cur := make([]string, 0)
for k, v := range root.children {
dfs1(v)
cur = append(cur, k + "(" + v.serial + ")")
}
sort.Strings(cur)
for i := 0 ; i < len(cur) ; i++ {
root.serial += cur[i]
}
m[root.serial]++
}
dfs1(root)
res := make([][]string, 0)
temPath := make([]string, 0)
var dfs2 func(root *Trie)
dfs2 = func(root *Trie) {
if m[root.serial] > 1 {
return
}
if len(temPath) > 0 {
t := make([]string, len(temPath))
for i := 0 ; i < len(temPath) ; i++ {
t[i] = temPath[i]
}
res = append(res, t)
}
for k, v := range root.children {
temPath = append(temPath, k)
dfs2(v)
temPath = temPath[:len(temPath) - 1]
}
}
dfs2(root)
return res
}