691.stickers-to-spell-word.go 1.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. func minStickers(stickers []string, target string) int {
  2. n := len(stickers)
  3. options := make([][26]int, n)
  4. goal := [26]int{}
  5. set1, set2 := cntFreq(target, goal[:]), 0
  6. for i, s := range stickers {
  7. set2 |= cntFreq(s, options[i][:])
  8. }
  9. for mask := 1; mask < 1<<26; mask <<= 1 {
  10. if mask&set1 != 0 && mask&set2 == 0 {
  11. return -1
  12. }
  13. }
  14. dp := make(map[[26]int]int)
  15. return dfs(options, goal, set1, dp)
  16. }
  17. func dfs(options [][26]int, goal [26]int, set int, dp map[[26]int]int) int {
  18. if v, ok := dp[goal]; ok {
  19. return v
  20. } else if set == 0 {
  21. return 0
  22. }
  23. res := math.MaxInt32
  24. for i := 0; i < len(options); i++ {
  25. ret, next, nset := sub(goal, options[i])
  26. if !ret {
  27. continue
  28. }
  29. if val := dfs(options, next, nset, dp) + 1; val < res {
  30. res = val
  31. }
  32. }
  33. dp[goal] = res
  34. return res
  35. }
  36. func sub(a, b [26]int) (flag bool, res [26]int, set int) {
  37. for i := 0; i < 26; i++ {
  38. if det := a[i] - b[i]; 0 < det {
  39. res[i] = det
  40. set |= 1 << uint(i)
  41. }
  42. if a[i] != 0 && b[i] != 0 {
  43. flag = true
  44. }
  45. }
  46. return
  47. }
  48. func cntFreq(word string, freq []int) (set int) {
  49. for _, r := range word {
  50. i := r - 'a'
  51. freq[i]++
  52. set |= 1 << uint(i)
  53. }
  54. return
  55. }