contest-251

112 阅读1分钟

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
}